keboola-cli 0.76.0__tar.gz → 0.76.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.76.0 → keboola_cli-0.76.2}/CLAUDE.md +3 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/PKG-INFO +1 -1
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/pyproject.toml +1 -1
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/auto_update.py +145 -64
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/changelog.py +25 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/serve.py +50 -3
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/version.py +6 -5
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_semantic_layer_internals.py +10 -5
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/version_service.py +265 -131
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_auto_update.py +121 -22
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_semantic_layer_service.py +38 -5
- keboola_cli-0.76.2/tests/test_serve_banner_encoding.py +252 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_version_service.py +97 -12
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/.gitignore +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/Makefile +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/README.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/examples/README.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/benchmark.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/check_mcp_parity.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/gen_command_reference.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/gen_release_notes.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/pre-commit +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/sync_version.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/_core.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/_transfer.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/branches.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/configs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/misc.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/query.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/queue.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/storage_files.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/storage_tables.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/stream.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/tokens.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/client/workspaces.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_helpers.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/config.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/context.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/data_app.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/docs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/lineage.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/permissions.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/project.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/storage.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/token.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/tool.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/transformation.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/commands/workspace.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/config_store.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/constants.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/data_science_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/errors.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/mcp_parity.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/metastore_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/permissions.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/scheduler_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/app.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/dependencies.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/configs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/data_apps.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/docs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/storage.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/token.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_encryption.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/component_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/config_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/data_app_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/docs_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/mcp_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/storage_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/sync_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/token_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/transformation_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/services/workspace_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/config_format.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/__init__.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/conftest.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/helpers.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_base_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_client_device_enrollment.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_component_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_component_sync_action.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_create_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_examples.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_row_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_row_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_search.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_store.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_config_update.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_git_repo.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_deep_lineage_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_docs_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_e2e.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_encryption.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_errors.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_flow_examples.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_gen_command_reference.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_gen_release_notes.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_helpers.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_http_base.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_integration.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_lib.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_lib_device_enrollment.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_mcp_deprecation_warnings.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_mcp_parity_map.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_mcp_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_mcp_transport.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_member_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_models.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_org_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_output.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_permissions.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_permissions_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_pricing.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_project_edit_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_repl.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_result_models.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_scheduler_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_search_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_semantic_layer_schema.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_server_router_calls.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_server_smoke.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_services.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_skill_frontmatter.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_create_table.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_snapshots.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_swap.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_storage_write.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_diff_engine.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_reconcile.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_token_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_token_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_tool_call_permissions.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_transformation_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_transformation_ops.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_workspace_cli.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_workspace_service.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/README.md +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/index.html +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/package-lock.json +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/package.json +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/ConfirmModal.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Mcp.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/tsconfig.json +0 -0
- {keboola_cli-0.76.0 → keboola_cli-0.76.2}/web/frontend/vite.config.ts +0 -0
|
@@ -664,6 +664,9 @@ kbagent update [--beta]
|
|
|
664
664
|
# source build; falls back to git+ when absent). Env `KBAGENT_UPDATE_TIMEOUT` (integer
|
|
665
665
|
# seconds, default 300) raises the self-update subprocess timeout for the slow git+
|
|
666
666
|
# fallback on WSL. Bootstrap install: `curl -LsSf .../main/install.sh | sh`.
|
|
667
|
+
# Since 0.76.2 self-update completes discovery first, updates MCP before the terminal
|
|
668
|
+
# exact-version full kbagent reinstall, then immediately re-executes; failures print a
|
|
669
|
+
# copy-paste recovery command.
|
|
667
670
|
kbagent changelog [--limit N] [--full]
|
|
668
671
|
# Default shows a one-line summary (first sentence) per version; --full / -v expands every note.
|
|
669
672
|
kbagent serve [--host HOST] [--port PORT] [--ui] [--ui-dist PATH] [--reload] [--log-level LVL] [--cors-origin ORIGIN] [--config-dir DIR]
|
|
@@ -34,6 +34,8 @@ from .constants import (
|
|
|
34
34
|
from .services.version_service import (
|
|
35
35
|
MCP_PACKAGE_NAME,
|
|
36
36
|
MCP_UV_PRERELEASE_FLAG,
|
|
37
|
+
KbagentUpdatePlan,
|
|
38
|
+
McpUpdatePlan,
|
|
37
39
|
_detect_mcp_install_method,
|
|
38
40
|
_fetch_kbagent_latest_version,
|
|
39
41
|
_fetch_mcp_latest_version,
|
|
@@ -42,6 +44,8 @@ from .services.version_service import (
|
|
|
42
44
|
_perform_mcp_update,
|
|
43
45
|
build_kbagent_upgrade_command,
|
|
44
46
|
get_update_timeout,
|
|
47
|
+
prepare_kbagent_update_plan,
|
|
48
|
+
prepare_mcp_update_plan,
|
|
45
49
|
resolve_kbagent_wheel_url,
|
|
46
50
|
)
|
|
47
51
|
|
|
@@ -264,7 +268,9 @@ def _should_skip() -> bool:
|
|
|
264
268
|
return _should_skip_kbagent_stage() or _should_skip_all()
|
|
265
269
|
|
|
266
270
|
|
|
267
|
-
def _perform_update(
|
|
271
|
+
def _perform_update(
|
|
272
|
+
latest_version: str, *, command: tuple[str, ...] | None = None
|
|
273
|
+
) -> UpdateOutcome:
|
|
268
274
|
"""Download and install the latest version.
|
|
269
275
|
|
|
270
276
|
Delegates to :func:`build_kbagent_upgrade_command` so this path stays
|
|
@@ -283,10 +289,14 @@ def _perform_update(latest_version: str) -> UpdateOutcome:
|
|
|
283
289
|
the install subprocess outran :func:`get_update_timeout` (a slow git+
|
|
284
290
|
build -- retried next run, not a real failure), ``FAILED`` otherwise.
|
|
285
291
|
"""
|
|
286
|
-
#
|
|
287
|
-
#
|
|
288
|
-
|
|
289
|
-
|
|
292
|
+
# ``command`` is supplied by the startup planner. Keep the fallback only
|
|
293
|
+
# for direct legacy callers; it must never be used after another stage has
|
|
294
|
+
# mutated the kbagent environment.
|
|
295
|
+
if command is None:
|
|
296
|
+
wheel_url = resolve_kbagent_wheel_url(latest_version)
|
|
297
|
+
cmd = build_kbagent_upgrade_command(target_version=latest_version, wheel_url=wheel_url)
|
|
298
|
+
else:
|
|
299
|
+
cmd = list(command)
|
|
290
300
|
if cmd is None:
|
|
291
301
|
return UpdateOutcome.FAILED
|
|
292
302
|
|
|
@@ -435,6 +445,58 @@ def _maybe_update_mcp(cache: dict | None, fetched_now: bool) -> str | None:
|
|
|
435
445
|
return mcp_latest
|
|
436
446
|
|
|
437
447
|
|
|
448
|
+
def _apply_prepared_mcp_update(plan: McpUpdatePlan) -> None:
|
|
449
|
+
"""Apply a previously prepared MCP update while kbagent is still intact."""
|
|
450
|
+
if plan.latest_version is None or plan.up_to_date is True or plan.install_method == "none":
|
|
451
|
+
return
|
|
452
|
+
if plan.current_version is None or plan.command is None:
|
|
453
|
+
return
|
|
454
|
+
|
|
455
|
+
sys.stderr.write(
|
|
456
|
+
f"Updating keboola-mcp-server v{plan.current_version} -> v{plan.latest_version}"
|
|
457
|
+
f" (via {plan.install_method})...\n"
|
|
458
|
+
)
|
|
459
|
+
success, info = _perform_mcp_update(
|
|
460
|
+
method=plan.install_method,
|
|
461
|
+
timeout=MCP_UPGRADE_TIMEOUT,
|
|
462
|
+
command=plan.command,
|
|
463
|
+
)
|
|
464
|
+
if not success:
|
|
465
|
+
sys.stderr.write(
|
|
466
|
+
f"keboola-mcp-server upgrade skipped: {info}; continuing with current version.\n"
|
|
467
|
+
)
|
|
468
|
+
return
|
|
469
|
+
|
|
470
|
+
# A post-MCP probe is permitted: the kbagent environment has not yet
|
|
471
|
+
# changed. It is deliberately the last discovery operation in this flow.
|
|
472
|
+
post_version = _get_local_mcp_version()
|
|
473
|
+
if post_version and post_version != plan.current_version:
|
|
474
|
+
sys.stderr.write(f"Updated keboola-mcp-server to v{post_version}.\n")
|
|
475
|
+
elif post_version is None:
|
|
476
|
+
sys.stderr.write(
|
|
477
|
+
f"Updated keboola-mcp-server (probe failed; latest on PyPI: v{plan.latest_version}).\n"
|
|
478
|
+
)
|
|
479
|
+
else:
|
|
480
|
+
sys.stderr.write(
|
|
481
|
+
f"keboola-mcp-server upgrade exit 0 but local version still v{plan.current_version} "
|
|
482
|
+
f"(latest: v{plan.latest_version}). Run `uv tool install --reinstall "
|
|
483
|
+
f"{MCP_UV_PRERELEASE_FLAG} {MCP_PACKAGE_NAME}` to force the latest.\n"
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def _prepare_auto_kbagent_plan(latest_version: str | None) -> KbagentUpdatePlan:
|
|
488
|
+
"""Adapt the shared plan to the startup comparison seam used by tests."""
|
|
489
|
+
prepared = prepare_kbagent_update_plan(latest_version)
|
|
490
|
+
up_to_date = _is_up_to_date(__version__, latest_version)
|
|
491
|
+
return KbagentUpdatePlan(
|
|
492
|
+
current_version=prepared.current_version,
|
|
493
|
+
latest_version=prepared.latest_version,
|
|
494
|
+
up_to_date=up_to_date,
|
|
495
|
+
command=prepared.command if up_to_date is False else None,
|
|
496
|
+
recovery_command=prepared.recovery_command,
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
|
|
438
500
|
def maybe_auto_update() -> None:
|
|
439
501
|
"""Main entry point for the auto-update flow.
|
|
440
502
|
|
|
@@ -484,66 +546,85 @@ def maybe_auto_update() -> None:
|
|
|
484
546
|
|
|
485
547
|
cache = _read_cache()
|
|
486
548
|
cache_is_fresh = bool(cache and _is_cache_fresh(cache, AUTO_UPDATE_CHECK_INTERVAL))
|
|
487
|
-
latest_version
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
# so plainly instead of "failed" and let a later run finish
|
|
522
|
-
# what uv already started (issue #353).
|
|
523
|
-
sys.stderr.write(
|
|
524
|
-
f"Update still building after {int(get_update_timeout())}s; "
|
|
525
|
-
"it will finish on a later run. Continuing with current version.\n"
|
|
526
|
-
)
|
|
527
|
-
else:
|
|
528
|
-
sys.stderr.write("Auto-update failed; continuing with current version.\n")
|
|
529
|
-
|
|
530
|
-
# ----- Stage 2: keboola-mcp-server update --------------------------
|
|
531
|
-
# Always runs (subject only to _should_skip_all above). After a
|
|
532
|
-
# kbagent self-upgrade, this is the re-exec'd process executing
|
|
533
|
-
# Stage 2 for the first time -- exactly the path B-1 broke before.
|
|
534
|
-
mcp_latest = _maybe_update_mcp(cache, fetched_now=not cache_is_fresh)
|
|
535
|
-
mcp_install_method = _detect_mcp_install_method()
|
|
536
|
-
|
|
537
|
-
# Persist combined cache (kbagent + MCP) when we did any fresh fetch.
|
|
538
|
-
# Note: in the re-exec'd path, latest_version stays None (Stage 1
|
|
539
|
-
# was skipped); _write_cache handles that by falling back to the
|
|
540
|
-
# running __version__, so we still persist the MCP-side fields and
|
|
541
|
-
# don't break the next run's cache TTL check.
|
|
542
|
-
if not cache_is_fresh:
|
|
549
|
+
cached_kbagent = cache.get("latest_version") if cache else None
|
|
550
|
+
cached_mcp = cache.get("mcp_latest_version") if cache else None
|
|
551
|
+
skip_kbagent_stage = _should_skip_kbagent_stage()
|
|
552
|
+
use_cached_kbagent = cache_is_fresh and isinstance(cached_kbagent, str)
|
|
553
|
+
use_cached_mcp = cache_is_fresh and isinstance(cached_mcp, str)
|
|
554
|
+
latest_version = (
|
|
555
|
+
cached_kbagent
|
|
556
|
+
if use_cached_kbagent
|
|
557
|
+
else (
|
|
558
|
+
None
|
|
559
|
+
if skip_kbagent_stage
|
|
560
|
+
else _fetch_kbagent_latest_version(timeout=VERSION_CHECK_TIMEOUT)
|
|
561
|
+
)
|
|
562
|
+
)
|
|
563
|
+
mcp_latest = (
|
|
564
|
+
cached_mcp
|
|
565
|
+
if use_cached_mcp
|
|
566
|
+
else _fetch_mcp_latest_version(timeout=VERSION_CHECK_TIMEOUT)
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
# Planning is complete before any subprocess can mutate either tool.
|
|
570
|
+
# In particular, all HTTP requests, import probes, PATH inspection,
|
|
571
|
+
# and command construction are above this line.
|
|
572
|
+
mcp_plan = prepare_mcp_update_plan(mcp_latest)
|
|
573
|
+
kbagent_plan = (
|
|
574
|
+
_prepare_auto_kbagent_plan(latest_version)
|
|
575
|
+
if not skip_kbagent_stage
|
|
576
|
+
else KbagentUpdatePlan(__version__, latest_version, True, None, None)
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
# MCP is an independent environment. Finish it before the terminal
|
|
580
|
+
# self-reinstall and persist the prepared cache before self-mutation.
|
|
581
|
+
_apply_prepared_mcp_update(mcp_plan)
|
|
582
|
+
if not (use_cached_kbagent and use_cached_mcp):
|
|
543
583
|
_write_cache(
|
|
544
|
-
latest_version=
|
|
545
|
-
|
|
546
|
-
|
|
584
|
+
latest_version=(
|
|
585
|
+
latest_version
|
|
586
|
+
if latest_version is not None
|
|
587
|
+
else cached_kbagent
|
|
588
|
+
if isinstance(cached_kbagent, str)
|
|
589
|
+
else None
|
|
590
|
+
),
|
|
591
|
+
mcp_latest_version=(
|
|
592
|
+
mcp_latest
|
|
593
|
+
if mcp_latest is not None
|
|
594
|
+
else cached_mcp
|
|
595
|
+
if isinstance(cached_mcp, str)
|
|
596
|
+
else None
|
|
597
|
+
),
|
|
598
|
+
mcp_install_method=mcp_plan.install_method,
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
if kbagent_plan.up_to_date is not False:
|
|
602
|
+
return
|
|
603
|
+
if kbagent_plan.command is None:
|
|
604
|
+
sys.stderr.write(
|
|
605
|
+
"Auto-update could not prepare a reinstall command. "
|
|
606
|
+
f"Recover with: {kbagent_plan.recovery_command}\n"
|
|
607
|
+
)
|
|
608
|
+
return
|
|
609
|
+
|
|
610
|
+
sys.stderr.write(f"Updating kbagent v{__version__} -> v{kbagent_plan.latest_version}...\n")
|
|
611
|
+
outcome = _perform_update(
|
|
612
|
+
kbagent_plan.latest_version or __version__, command=kbagent_plan.command
|
|
613
|
+
)
|
|
614
|
+
if outcome is UpdateOutcome.SUCCESS:
|
|
615
|
+
sys.stderr.write(f"Updated to v{kbagent_plan.latest_version}. Re-launching...\n")
|
|
616
|
+
os.environ[ENV_UPDATED_FROM] = __version__
|
|
617
|
+
_re_exec()
|
|
618
|
+
return
|
|
619
|
+
if outcome is UpdateOutcome.TIMEOUT:
|
|
620
|
+
sys.stderr.write(
|
|
621
|
+
f"Update timed out after {int(get_update_timeout())}s. Recover with: "
|
|
622
|
+
f"{kbagent_plan.recovery_command}\n"
|
|
623
|
+
)
|
|
624
|
+
else:
|
|
625
|
+
sys.stderr.write(
|
|
626
|
+
"Auto-update failed; continuing with current version. Recover with: "
|
|
627
|
+
f"{kbagent_plan.recovery_command}\n"
|
|
547
628
|
)
|
|
548
629
|
except Exception:
|
|
549
630
|
# Blanket catch: auto-update must NEVER crash the CLI.
|
|
@@ -24,6 +24,31 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
|
|
|
24
24
|
|
|
25
25
|
# Ordered newest-first. Each value is a list of brief one-line descriptions.
|
|
26
26
|
CHANGELOG: dict[str, list[str]] = {
|
|
27
|
+
"0.76.2": [
|
|
28
|
+
"Fix (#528, #530): self-update no longer risks leaving the running Windows uv tool "
|
|
29
|
+
"environment partially upgraded. kbagent now completes all network checks and command "
|
|
30
|
+
"planning before mutation, upgrades the independent keboola-mcp-server environment "
|
|
31
|
+
"first, caches the result, then performs an exact-version full reinstall as the terminal "
|
|
32
|
+
"step and immediately re-executes. Failed or timed-out updates print a copy-paste recovery "
|
|
33
|
+
"command instead of continuing without repair guidance. Thanks to @papousek-radan for "
|
|
34
|
+
"the detailed corruption reports.",
|
|
35
|
+
"Fix (#529, #531): `kbagent semantic-layer export` now writes snapshots on Windows. "
|
|
36
|
+
"The writer conditionally enables platform-specific `O_NOFOLLOW` and `O_BINARY` flags, "
|
|
37
|
+
"so Windows no longer raises `AttributeError` while POSIX keeps its existing final-path "
|
|
38
|
+
"symlink protection; the real Windows export path is covered by CI. Thanks to "
|
|
39
|
+
"@papousek-radan for the report.",
|
|
40
|
+
],
|
|
41
|
+
"0.76.1": [
|
|
42
|
+
"Fix (#522, #526): `kbagent serve --ui` no longer crashes on startup on Windows "
|
|
43
|
+
"consoles with a non-UTF-8 codepage (cp1250 on Czech/Polish/Hungarian Windows). The "
|
|
44
|
+
"startup banner's box-drawing glyphs (`├─` / `└─`) raised `UnicodeEncodeError` from "
|
|
45
|
+
"`sys.stdout.write` before uvicorn bound the port, so the server never started. They "
|
|
46
|
+
"now degrade to ASCII (`|-` / `` `- ``) when the console can't encode them -- the same "
|
|
47
|
+
"UTF-8/ASCII fallback `install.sh` already uses -- with a belt-and-braces `try/except` "
|
|
48
|
+
"so a cosmetic banner can never abort startup. Modern UTF-8 terminals are unchanged. "
|
|
49
|
+
"The `set PYTHONUTF8=1` workaround is no longer needed. Thanks to @papousek-radan for "
|
|
50
|
+
"the detailed report.",
|
|
51
|
+
],
|
|
27
52
|
"0.76.0": [
|
|
28
53
|
"Change (#520): the ~3,960-LOC `client.py` is split into a `client/` package by "
|
|
29
54
|
"endpoint family (storage tables/files, configs, queue, tokens, branches, stream, "
|
|
@@ -86,6 +86,53 @@ def _autodetect_ui_dist() -> Path | None:
|
|
|
86
86
|
return None
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
# Box-drawing glyphs used by the startup banner, mapped to ASCII so the banner
|
|
90
|
+
# degrades to `|-` / `` `- `` on a console that can't render Unicode -- the same
|
|
91
|
+
# fallback install.sh uses (Unicode only under a UTF-8 locale, ASCII otherwise).
|
|
92
|
+
_BANNER_ASCII_FALLBACK = str.maketrans({"├": "|", "└": "`", "─": "-"})
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _encode_safe(text: str, encoding: str | None) -> str:
|
|
96
|
+
"""Return ``text`` with box-drawing glyphs stripped to ASCII if unencodable.
|
|
97
|
+
|
|
98
|
+
On Windows with a non-UTF-8 console codepage (cp1250 on Czech/Polish/
|
|
99
|
+
Hungarian locales, and any other legacy single-byte encoding) the ``├─`` /
|
|
100
|
+
``└─`` glyphs in the startup banner cannot be encoded, so ``sys.stdout.write``
|
|
101
|
+
raises ``UnicodeEncodeError`` -- which crashed ``kbagent serve`` before
|
|
102
|
+
uvicorn ever bound the port (issue #522). When ``encoding`` can represent the
|
|
103
|
+
banner we keep the Unicode glyphs; otherwise we transliterate to ASCII.
|
|
104
|
+
|
|
105
|
+
``encoding`` is ``sys.stdout.encoding`` at the call site (``None`` on an
|
|
106
|
+
exotic stream); an unknown codec name (``LookupError``) also degrades to
|
|
107
|
+
ASCII rather than propagating.
|
|
108
|
+
"""
|
|
109
|
+
enc = encoding or "utf-8"
|
|
110
|
+
try:
|
|
111
|
+
text.encode(enc)
|
|
112
|
+
except (UnicodeEncodeError, LookupError):
|
|
113
|
+
return text.translate(_BANNER_ASCII_FALLBACK)
|
|
114
|
+
return text
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _write_banner(text: str) -> None:
|
|
118
|
+
"""Write the startup banner without ever letting a glyph crash startup.
|
|
119
|
+
|
|
120
|
+
Two layers of defense (issue #522): first transliterate to ASCII when
|
|
121
|
+
stdout's encoding can't represent the banner, then wrap the write in a
|
|
122
|
+
belt-and-braces ``try/except`` so even an unforeseen un-encodable character
|
|
123
|
+
re-emits with lossy replacement instead of aborting the server. A degraded
|
|
124
|
+
banner is always better than a server that won't start.
|
|
125
|
+
"""
|
|
126
|
+
encoding = getattr(sys.stdout, "encoding", None)
|
|
127
|
+
safe = _encode_safe(text, encoding)
|
|
128
|
+
try:
|
|
129
|
+
sys.stdout.write(safe)
|
|
130
|
+
except UnicodeEncodeError:
|
|
131
|
+
enc = encoding or "ascii"
|
|
132
|
+
sys.stdout.write(safe.encode(enc, "replace").decode(enc, "replace"))
|
|
133
|
+
sys.stdout.flush()
|
|
134
|
+
|
|
135
|
+
|
|
89
136
|
def serve_command(
|
|
90
137
|
host: str = typer.Option(
|
|
91
138
|
"127.0.0.1",
|
|
@@ -232,7 +279,7 @@ def serve_command(
|
|
|
232
279
|
# UI mode: the user opens the browser directly; there is no BFF to
|
|
233
280
|
# paste the token into. The token is still printed so scripted
|
|
234
281
|
# callers / curl one-liners keep working.
|
|
235
|
-
|
|
282
|
+
banner = (
|
|
236
283
|
"\n"
|
|
237
284
|
" kbagent serve (single-process UI mode)\n"
|
|
238
285
|
f" ├─ open: http://{host}:{port}/\n"
|
|
@@ -252,7 +299,7 @@ def serve_command(
|
|
|
252
299
|
"\n"
|
|
253
300
|
)
|
|
254
301
|
else:
|
|
255
|
-
|
|
302
|
+
banner = (
|
|
256
303
|
"\n"
|
|
257
304
|
" kbagent serve\n"
|
|
258
305
|
f" ├─ host: http://{host}:{port}\n"
|
|
@@ -270,7 +317,7 @@ def serve_command(
|
|
|
270
317
|
f" export KBAGENT_CONVERSATION_ID={conversation_id}\n"
|
|
271
318
|
"\n"
|
|
272
319
|
)
|
|
273
|
-
|
|
320
|
+
_write_banner(banner)
|
|
274
321
|
|
|
275
322
|
uvicorn.run(
|
|
276
323
|
app,
|
|
@@ -142,12 +142,13 @@ def update_command(
|
|
|
142
142
|
|
|
143
143
|
Two-stage upgrade (since v0.30.1):
|
|
144
144
|
|
|
145
|
-
1. **
|
|
146
|
-
``pip install --upgrade`` from the GitHub repository.
|
|
147
|
-
2. **keboola-mcp-server** -- detects install method and runs the
|
|
145
|
+
1. **keboola-mcp-server** -- detects install method and runs the
|
|
148
146
|
matching upgrade command (``uv tool upgrade`` / ``pip install -U``
|
|
149
|
-
/ ``uvx --refresh``).
|
|
150
|
-
|
|
147
|
+
/ ``uvx --refresh``).
|
|
148
|
+
2. **kbagent** -- final terminal stage: ``uv tool install --force
|
|
149
|
+
--reinstall`` from an exact release wheel or Git tag. This recreates
|
|
150
|
+
the whole tool environment and preserves ``[server]`` extras. On a
|
|
151
|
+
failure the result includes a copy/paste recovery command.
|
|
151
152
|
|
|
152
153
|
JSON output reports both stages independently. Human mode prints a
|
|
153
154
|
one-line summary such as
|
|
@@ -1059,16 +1059,21 @@ def build_export_snapshot(
|
|
|
1059
1059
|
|
|
1060
1060
|
|
|
1061
1061
|
def write_snapshot_to_file(snapshot: dict[str, Any], output_path: Path) -> None:
|
|
1062
|
-
"""
|
|
1062
|
+
"""Write a JSON snapshot with 0o644 permissions where supported.
|
|
1063
1063
|
|
|
1064
|
-
|
|
1065
|
-
path so a malicious
|
|
1066
|
-
redirect the write to a sensitive file.
|
|
1064
|
+
On platforms that expose ``O_NOFOLLOW``, reject a pre-existing symlink at
|
|
1065
|
+
the output path so a malicious ``--output`` (or a planted symlink in the
|
|
1066
|
+
current directory) cannot redirect the write to a sensitive file. Windows
|
|
1067
|
+
does not provide that flag through :mod:`os`; its portable flags still
|
|
1068
|
+
write the encoded JSON bytes without text-mode newline translation.
|
|
1067
1069
|
"""
|
|
1068
1070
|
payload = json.dumps(snapshot, indent=2).encode("utf-8")
|
|
1071
|
+
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
|
|
1072
|
+
flags |= getattr(os, "O_NOFOLLOW", 0)
|
|
1073
|
+
flags |= getattr(os, "O_BINARY", 0)
|
|
1069
1074
|
fd = os.open(
|
|
1070
1075
|
str(output_path),
|
|
1071
|
-
|
|
1076
|
+
flags,
|
|
1072
1077
|
0o644,
|
|
1073
1078
|
)
|
|
1074
1079
|
try:
|