keboola-cli 0.76.2__tar.gz → 0.77.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/CLAUDE.md +2 -2
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/PKG-INFO +2 -2
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/pyproject.toml +2 -2
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/changelog.py +18 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/config.py +26 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/context.py +2 -2
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/configs.py +4 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/config_service.py +35 -14
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_row_cli.py +38 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_row_service.py +50 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_update.py +143 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e.py +48 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_router_calls.py +50 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/package-lock.json +11 -21
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/package.json +3 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/.gitignore +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/Makefile +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/README.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/examples/README.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/benchmark.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_mcp_parity.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/gen_command_reference.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/gen_release_notes.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/pre-commit +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/sync_version.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/auto_update.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_core.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_transfer.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/branches.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/configs.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/misc.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/query.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/queue.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/storage_files.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/storage_tables.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/stream.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/tokens.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/workspaces.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_helpers.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/data_app.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/docs.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/lineage.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/permissions.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/project.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/serve.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/storage.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/token.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/tool.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/transformation.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/version.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/workspace.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/config_store.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/constants.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/data_science_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/errors.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/mcp_parity.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/metastore_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/permissions.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/scheduler_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/app.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/dependencies.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/data_apps.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/docs.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/storage.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/token.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_encryption.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/component_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/data_app_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/docs_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/mcp_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/storage_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/sync_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/token_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/transformation_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/version_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/workspace_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/config_format.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/__init__.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/conftest.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/helpers.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_auto_update.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_base_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_client_device_enrollment.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_sync_action.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_create_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_examples.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_search.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_store.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_git_repo.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_deep_lineage_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_docs_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encryption.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_errors.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_examples.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_gen_command_reference.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_gen_release_notes.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_helpers.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_base.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_integration.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lib.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lib_device_enrollment.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_deprecation_warnings.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_parity_map.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_transport.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_member_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_models.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_org_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_output.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_permissions.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_permissions_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_pricing.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_edit_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_repl.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_result_models.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_scheduler_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_search_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_schema.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_banner_encoding.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_smoke.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_services.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_skill_frontmatter.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_create_table.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_snapshots.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_swap.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_write.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_diff_engine.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_reconcile.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_token_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_token_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_tool_call_permissions.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_transformation_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_transformation_ops.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_version_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_cli.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_service.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/README.md +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/index.html +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/ConfirmModal.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Mcp.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/tsconfig.json +0 -0
- {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/vite.config.ts +0 -0
|
@@ -303,7 +303,7 @@ kbagent project member-set-role --project ALIAS --email EMAIL --role admin|guest
|
|
|
303
303
|
kbagent config list [--project NAME] [--component-type TYPE] [--component-id ID] [--branch ID] [--include-rows]
|
|
304
304
|
kbagent config detail --project NAME [--project NAME ...] --component-id ID [--config-id ID] [--branch ID] [--with-state]
|
|
305
305
|
kbagent config search --query PATTERN [--project NAME] [--component-type TYPE] [--ignore-case] [--regex] [--branch ID]
|
|
306
|
-
kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
306
|
+
kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--change-description TEXT] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
307
307
|
kbagent config set-default-bucket --project NAME --component-id ID --config-id ID (--bucket BUCKET_ID | --clear) [--dry-run] [--branch ID]
|
|
308
308
|
kbagent config rename --project NAME --component-id ID --config-id ID --name "New Name" [--branch ID] [--directory DIR]
|
|
309
309
|
kbagent config variables-set --project NAME --component-id ID --config-id ID --var KEY=VALUE [--var ...] [--replace] [--variables-id ID] [--values-id ID] [--branch ID] [--dry-run]
|
|
@@ -315,7 +315,7 @@ kbagent config set-metadata --project NAME --component-id ID --config-id ID --ke
|
|
|
315
315
|
kbagent config delete-metadata --project NAME --component-id ID --config-id ID --metadata-id ID [--branch ID] [--yes]
|
|
316
316
|
kbagent config set-folder --project NAME --component-id ID --config-id ID --name FOLDER [--branch ID]
|
|
317
317
|
kbagent config row-create --project NAME --component-id ID --config-id ID --name ROW_NAME [--description D] [--configuration JSON|@file|-] [--is-disabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
318
|
-
kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
318
|
+
kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--change-description TEXT] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
319
319
|
kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
|
|
320
320
|
kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL]
|
|
321
321
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: keboola-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.77.0
|
|
4
4
|
Summary: AI-friendly CLI for managing Keboola projects
|
|
5
5
|
Author-email: Keboola <dev@keboola.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -17,7 +17,7 @@ Requires-Dist: prompt-toolkit>=3.0
|
|
|
17
17
|
Requires-Dist: pydantic>=2.5
|
|
18
18
|
Requires-Dist: pyyaml>=6
|
|
19
19
|
Requires-Dist: rich>=13
|
|
20
|
-
Requires-Dist: typer
|
|
20
|
+
Requires-Dist: typer>=0.12
|
|
21
21
|
Provides-Extra: server
|
|
22
22
|
Requires-Dist: fastapi>=0.115; extra == 'server'
|
|
23
23
|
Requires-Dist: python-multipart>=0.0.31; extra == 'server'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "keboola-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.77.0"
|
|
4
4
|
description = "AI-friendly CLI for managing Keboola projects"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
{ name = "Keboola", email = "dev@keboola.com" },
|
|
10
10
|
]
|
|
11
11
|
dependencies = [
|
|
12
|
-
"typer
|
|
12
|
+
"typer>=0.12",
|
|
13
13
|
"rich>=13",
|
|
14
14
|
"httpx>=0.27",
|
|
15
15
|
"pydantic>=2.5",
|
|
@@ -24,6 +24,24 @@ 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.77.0": [
|
|
28
|
+
"New (#505): `kbagent config update` and `kbagent config row-update` accept "
|
|
29
|
+
"`--change-description TEXT`, which writes the new config version's "
|
|
30
|
+
"`changeDescription` -- the version-history audit line -- instead of the generic "
|
|
31
|
+
"auto-generated default. On shared production configs that history is the paper "
|
|
32
|
+
"trail, so a change can now say *why* it happened. Omitting the flag preserves the "
|
|
33
|
+
"previous default verbatim, and `--dry-run` echoes the description that would be "
|
|
34
|
+
"sent (`change_description` in `--json`). Note this is distinct from `--description`, "
|
|
35
|
+
"which sets the configuration's display description. Both `kbagent serve` PATCH "
|
|
36
|
+
"routes mirror the flag. Thanks to @jordanrburger.",
|
|
37
|
+
],
|
|
38
|
+
"0.76.3": [
|
|
39
|
+
"Security: bump npm dependencies flagged by Dependabot in `web/backend` and "
|
|
40
|
+
"`web/frontend` -- `@fastify/static` (path traversal / auth bypass), "
|
|
41
|
+
"`brace-expansion` and `find-my-way` (DoS), `postcss` (source-map path traversal), "
|
|
42
|
+
"and `dompurify` (XSS/sanitization bypass, pinned via an npm override on the "
|
|
43
|
+
"`monaco-editor`/`mermaid` transitive copy). No behavior change.",
|
|
44
|
+
],
|
|
27
45
|
"0.76.2": [
|
|
28
46
|
"Fix (#528, #530): self-update no longer risks leaving the running Windows uv tool "
|
|
29
47
|
"environment partially upgraded. kbagent now completes all network checks and command "
|
|
@@ -647,6 +647,11 @@ def config_update(
|
|
|
647
647
|
"--merge",
|
|
648
648
|
help="Deep-merge into existing config instead of replacing",
|
|
649
649
|
),
|
|
650
|
+
change_description: str | None = typer.Option(
|
|
651
|
+
None,
|
|
652
|
+
"--change-description",
|
|
653
|
+
help="Version changeDescription for the audit trail (default: auto-generated)",
|
|
654
|
+
),
|
|
650
655
|
dry_run: bool = typer.Option(
|
|
651
656
|
False,
|
|
652
657
|
"--dry-run",
|
|
@@ -692,6 +697,10 @@ def config_update(
|
|
|
692
697
|
# Preview changes without applying
|
|
693
698
|
kbagent config update --project P --component-id C --config-id ID \\
|
|
694
699
|
--set 'parameters.db.host=new-host' --dry-run
|
|
700
|
+
|
|
701
|
+
# Set a meaningful version changeDescription for the audit trail
|
|
702
|
+
kbagent config update --project P --component-id C --config-id ID \\
|
|
703
|
+
--set 'parameters.db.host=new-host' --change-description "AI-1234: point at new DB host"
|
|
695
704
|
"""
|
|
696
705
|
formatter = get_formatter(ctx)
|
|
697
706
|
service = get_service(ctx, "config_service")
|
|
@@ -753,6 +762,7 @@ def config_update(
|
|
|
753
762
|
set_paths=parsed_sets,
|
|
754
763
|
merge=effective_merge,
|
|
755
764
|
dry_run=dry_run,
|
|
765
|
+
change_description=change_description,
|
|
756
766
|
branch_id=branch,
|
|
757
767
|
allow_plaintext_fallback=allow_plaintext,
|
|
758
768
|
)
|
|
@@ -782,6 +792,9 @@ def config_update(
|
|
|
782
792
|
for change in changes:
|
|
783
793
|
formatter.console.print(f" {change}")
|
|
784
794
|
formatter.console.print()
|
|
795
|
+
change_desc = result.get("change_description")
|
|
796
|
+
if change_desc:
|
|
797
|
+
formatter.console.print(f"[dim]changeDescription:[/dim] {change_desc}")
|
|
785
798
|
_emit_normalizations_warning(formatter, normalizations)
|
|
786
799
|
return
|
|
787
800
|
|
|
@@ -2259,6 +2272,11 @@ def config_row_update(
|
|
|
2259
2272
|
"--merge",
|
|
2260
2273
|
help="Deep-merge into existing row config instead of replacing",
|
|
2261
2274
|
),
|
|
2275
|
+
change_description: str | None = typer.Option(
|
|
2276
|
+
None,
|
|
2277
|
+
"--change-description",
|
|
2278
|
+
help="Version changeDescription for the audit trail (default: auto-generated)",
|
|
2279
|
+
),
|
|
2262
2280
|
dry_run: bool = typer.Option(
|
|
2263
2281
|
False,
|
|
2264
2282
|
"--dry-run",
|
|
@@ -2313,6 +2331,10 @@ def config_row_update(
|
|
|
2313
2331
|
|
|
2314
2332
|
# Disable a row (excludes it from job runs)
|
|
2315
2333
|
kbagent config row-update --project P --component-id C --config-id ID --row-id R --is-disabled
|
|
2334
|
+
|
|
2335
|
+
# Set a meaningful version changeDescription for the audit trail
|
|
2336
|
+
kbagent config row-update --project P --component-id C --config-id ID --row-id R \\
|
|
2337
|
+
--set 'parameters.table=new_table' --change-description "AI-1234: repoint row"
|
|
2316
2338
|
"""
|
|
2317
2339
|
if is_disabled and is_enabled:
|
|
2318
2340
|
formatter = get_formatter(ctx)
|
|
@@ -2369,6 +2391,7 @@ def config_row_update(
|
|
|
2369
2391
|
set_paths=parsed_sets,
|
|
2370
2392
|
merge=effective_merge,
|
|
2371
2393
|
dry_run=dry_run,
|
|
2394
|
+
change_description=change_description,
|
|
2372
2395
|
is_disabled=is_disabled_value,
|
|
2373
2396
|
branch_id=branch,
|
|
2374
2397
|
allow_plaintext_fallback=allow_plaintext,
|
|
@@ -2396,6 +2419,9 @@ def config_row_update(
|
|
|
2396
2419
|
for change in changes:
|
|
2397
2420
|
formatter.console.print(f" {change}")
|
|
2398
2421
|
formatter.console.print()
|
|
2422
|
+
change_desc = result.get("change_description")
|
|
2423
|
+
if change_desc:
|
|
2424
|
+
formatter.console.print(f"[dim]changeDescription:[/dim] {change_desc}")
|
|
2399
2425
|
return
|
|
2400
2426
|
|
|
2401
2427
|
if formatter.json_mode:
|
|
@@ -172,7 +172,7 @@ Use `kbagent <command> --help` for full flag details and examples.
|
|
|
172
172
|
Use storage_workspace_id with `kbagent workspace detail --workspace-id ID`,
|
|
173
173
|
NOT parameters.id (which 404s).
|
|
174
174
|
|
|
175
|
-
kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
175
|
+
kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--change-description TEXT] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
176
176
|
Update config metadata and/or configuration content. --set targets a
|
|
177
177
|
nested key (e.g. parameters.db.host=new-host). --merge deep-merges into
|
|
178
178
|
existing config (preserves sibling keys). --dry-run previews changes.
|
|
@@ -257,7 +257,7 @@ Use `kbagent <command> --help` for full flag details and examples.
|
|
|
257
257
|
kbagent config row-create --project NAME --component-id ID --config-id ID --name ROW_NAME [--description D] [--configuration JSON|@file|-] [--is-disabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
258
258
|
Create a new configuration row. Returns the new row ID. Optional --configuration accepts JSON inline, @file, or stdin. #-prefixed secrets auto-encrypt before write (fail-closed; since 0.54.0).
|
|
259
259
|
|
|
260
|
-
kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
260
|
+
kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--change-description TEXT] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
261
261
|
Update an existing configuration row. Pass only the fields you want to change. #-prefixed secrets auto-encrypt before write (fail-closed; since 0.54.0).
|
|
262
262
|
|
|
263
263
|
kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
|
|
@@ -20,6 +20,7 @@ class ConfigUpdate(BaseModel):
|
|
|
20
20
|
set_paths: list[tuple[str, Any]] | None = None
|
|
21
21
|
merge: bool = False
|
|
22
22
|
dry_run: bool = False
|
|
23
|
+
change_description: str | None = None
|
|
23
24
|
branch_id: int | None = None
|
|
24
25
|
|
|
25
26
|
|
|
@@ -36,6 +37,7 @@ class ConfigUpdateRow(BaseModel):
|
|
|
36
37
|
description: str | None = None
|
|
37
38
|
configuration: dict[str, Any] | None = None
|
|
38
39
|
is_disabled: bool | None = None
|
|
40
|
+
change_description: str | None = None
|
|
39
41
|
branch_id: int | None = None
|
|
40
42
|
|
|
41
43
|
|
|
@@ -172,6 +174,7 @@ def config_update(
|
|
|
172
174
|
set_paths=body.set_paths,
|
|
173
175
|
merge=body.merge,
|
|
174
176
|
dry_run=body.dry_run,
|
|
177
|
+
change_description=body.change_description,
|
|
175
178
|
branch_id=body.branch_id,
|
|
176
179
|
)
|
|
177
180
|
|
|
@@ -401,6 +404,7 @@ def row_update(
|
|
|
401
404
|
name=body.name,
|
|
402
405
|
description=body.description,
|
|
403
406
|
configuration=body.configuration,
|
|
407
|
+
change_description=body.change_description,
|
|
404
408
|
is_disabled=body.is_disabled,
|
|
405
409
|
branch_id=body.branch_id,
|
|
406
410
|
)
|
|
@@ -66,6 +66,23 @@ def _infer_component_type(component_id: str) -> str | None:
|
|
|
66
66
|
return None
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
def _default_change_description(command: str, *, has_metadata: bool, has_content: bool) -> str:
|
|
70
|
+
"""Build the default config-version ``changeDescription`` for a write.
|
|
71
|
+
|
|
72
|
+
Used when the caller does not pass an explicit ``--change-description``.
|
|
73
|
+
``command`` is the kbagent command that produced the version (e.g.
|
|
74
|
+
``"config update"``), and the flags describe which parts changed so the
|
|
75
|
+
version-history line reads e.g. ``Updated metadata + configuration via
|
|
76
|
+
kbagent config update``.
|
|
77
|
+
"""
|
|
78
|
+
parts = []
|
|
79
|
+
if has_metadata:
|
|
80
|
+
parts.append("metadata")
|
|
81
|
+
if has_content:
|
|
82
|
+
parts.append("configuration")
|
|
83
|
+
return f"Updated {' + '.join(parts)} via kbagent {command}"
|
|
84
|
+
|
|
85
|
+
|
|
69
86
|
def _find_matches_in_json(
|
|
70
87
|
obj: Any,
|
|
71
88
|
match_fn: Any,
|
|
@@ -663,6 +680,7 @@ class ConfigService(BaseService):
|
|
|
663
680
|
set_paths: list[tuple[str, Any]] | None = None,
|
|
664
681
|
merge: bool = False,
|
|
665
682
|
dry_run: bool = False,
|
|
683
|
+
change_description: str | None = None,
|
|
666
684
|
branch_id: int | None = None,
|
|
667
685
|
allow_plaintext_fallback: bool = False,
|
|
668
686
|
) -> dict[str, Any]:
|
|
@@ -680,6 +698,9 @@ class ConfigService(BaseService):
|
|
|
680
698
|
merge: If True, deep-merge *configuration* or *set_paths* into
|
|
681
699
|
the existing config instead of replacing. When using
|
|
682
700
|
*set_paths* merge is always implied.
|
|
701
|
+
change_description: Text stored as the new config version's
|
|
702
|
+
``changeDescription`` (the version-history audit line). When
|
|
703
|
+
``None`` a default is generated from what changed.
|
|
683
704
|
dry_run: If True, compute and return the diff without applying.
|
|
684
705
|
branch_id: If set, update in a specific dev branch.
|
|
685
706
|
If None, uses the project's active branch (if any).
|
|
@@ -737,6 +758,10 @@ class ConfigService(BaseService):
|
|
|
737
758
|
component_id, final_config
|
|
738
759
|
)
|
|
739
760
|
|
|
761
|
+
change_desc = change_description or _default_change_description(
|
|
762
|
+
"config update", has_metadata=has_metadata, has_content=has_content
|
|
763
|
+
)
|
|
764
|
+
|
|
740
765
|
if dry_run:
|
|
741
766
|
current = client.get_config_detail(
|
|
742
767
|
component_id, config_id, branch_id=effective_branch_id
|
|
@@ -751,6 +776,7 @@ class ConfigService(BaseService):
|
|
|
751
776
|
"config_id": config_id,
|
|
752
777
|
"branch_id": effective_branch_id,
|
|
753
778
|
"changes": changes,
|
|
779
|
+
"change_description": change_desc,
|
|
754
780
|
"old_configuration": old_cfg,
|
|
755
781
|
"new_configuration": new_cfg,
|
|
756
782
|
"normalizations": normalizations,
|
|
@@ -768,13 +794,6 @@ class ConfigService(BaseService):
|
|
|
768
794
|
allow_plaintext_fallback=allow_plaintext_fallback,
|
|
769
795
|
)
|
|
770
796
|
|
|
771
|
-
change_parts = []
|
|
772
|
-
if has_metadata:
|
|
773
|
-
change_parts.append("metadata")
|
|
774
|
-
if has_content:
|
|
775
|
-
change_parts.append("configuration")
|
|
776
|
-
change_desc = f"Updated {' + '.join(change_parts)} via kbagent config update"
|
|
777
|
-
|
|
778
797
|
result = client.update_config(
|
|
779
798
|
component_id=component_id,
|
|
780
799
|
config_id=config_id,
|
|
@@ -1821,6 +1840,7 @@ class ConfigService(BaseService):
|
|
|
1821
1840
|
set_paths: list[tuple[str, Any]] | None = None,
|
|
1822
1841
|
merge: bool = False,
|
|
1823
1842
|
dry_run: bool = False,
|
|
1843
|
+
change_description: str | None = None,
|
|
1824
1844
|
is_disabled: bool | None = None,
|
|
1825
1845
|
branch_id: int | None = None,
|
|
1826
1846
|
allow_plaintext_fallback: bool = False,
|
|
@@ -1838,6 +1858,9 @@ class ConfigService(BaseService):
|
|
|
1838
1858
|
set_paths: List of (path, value) tuples for targeted updates.
|
|
1839
1859
|
merge: If True, deep-merge *configuration* into the existing row
|
|
1840
1860
|
config instead of replacing.
|
|
1861
|
+
change_description: Text stored as the new row version's
|
|
1862
|
+
``changeDescription``. When ``None`` a default is generated
|
|
1863
|
+
from what changed.
|
|
1841
1864
|
dry_run: If True, compute and return the diff without applying.
|
|
1842
1865
|
is_disabled: When True, disable the row; when False, enable it;
|
|
1843
1866
|
when None, leave the current state unchanged.
|
|
@@ -1889,6 +1912,10 @@ class ConfigService(BaseService):
|
|
|
1889
1912
|
branch_id=effective_branch_id,
|
|
1890
1913
|
)
|
|
1891
1914
|
|
|
1915
|
+
change_desc = change_description or _default_change_description(
|
|
1916
|
+
"config row-update", has_metadata=has_metadata, has_content=has_content
|
|
1917
|
+
)
|
|
1918
|
+
|
|
1892
1919
|
if dry_run:
|
|
1893
1920
|
current_row = client.get_config_row(
|
|
1894
1921
|
component_id, config_id, row_id, branch_id=effective_branch_id
|
|
@@ -1910,17 +1937,11 @@ class ConfigService(BaseService):
|
|
|
1910
1937
|
"row_id": row_id,
|
|
1911
1938
|
"branch_id": effective_branch_id,
|
|
1912
1939
|
"changes": changes,
|
|
1940
|
+
"change_description": change_desc,
|
|
1913
1941
|
"old_configuration": old_cfg,
|
|
1914
1942
|
"new_configuration": new_cfg,
|
|
1915
1943
|
}
|
|
1916
1944
|
|
|
1917
|
-
change_parts = []
|
|
1918
|
-
if has_metadata:
|
|
1919
|
-
change_parts.append("metadata")
|
|
1920
|
-
if has_content:
|
|
1921
|
-
change_parts.append("configuration")
|
|
1922
|
-
change_desc = f"Updated {' + '.join(change_parts)} via kbagent config row-update"
|
|
1923
|
-
|
|
1924
1945
|
# Encrypt #-prefixed secrets before they reach Storage (issue #378).
|
|
1925
1946
|
# Real write only -- dry-run returned above with plaintext diff.
|
|
1926
1947
|
if final_config is not None:
|
|
@@ -309,6 +309,44 @@ class TestConfigRowUpdateCli:
|
|
|
309
309
|
assert cfg["parameters"]["table"] == "invoices"
|
|
310
310
|
assert cfg["parameters"]["limit"] == 1000 # sibling preserved
|
|
311
311
|
|
|
312
|
+
def test_change_description_flag_forwarded(self, tmp_config_dir: Path) -> None:
|
|
313
|
+
"""--change-description reaches the client as change_description."""
|
|
314
|
+
store = setup_single_project(tmp_config_dir)
|
|
315
|
+
mock_client = MagicMock()
|
|
316
|
+
mock_client.update_config_row.return_value = {**SAMPLE_ROW}
|
|
317
|
+
service = ConfigService(
|
|
318
|
+
config_store=store,
|
|
319
|
+
client_factory=lambda url, token: mock_client,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
with pytest.MonkeyPatch.context() as mp:
|
|
323
|
+
mp.setattr(
|
|
324
|
+
"keboola_agent_cli.commands.config.get_service",
|
|
325
|
+
lambda ctx, name: service,
|
|
326
|
+
)
|
|
327
|
+
result = _invoke(
|
|
328
|
+
tmp_config_dir,
|
|
329
|
+
"row-update",
|
|
330
|
+
[
|
|
331
|
+
"--project",
|
|
332
|
+
"prod",
|
|
333
|
+
"--component-id",
|
|
334
|
+
"keboola.ex-db-snowflake",
|
|
335
|
+
"--config-id",
|
|
336
|
+
"cfg-001",
|
|
337
|
+
"--row-id",
|
|
338
|
+
"row-001",
|
|
339
|
+
"--name",
|
|
340
|
+
"New Name",
|
|
341
|
+
"--change-description",
|
|
342
|
+
"AI-1234: rename row",
|
|
343
|
+
],
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
assert result.exit_code == 0, result.output
|
|
347
|
+
call_kwargs = mock_client.update_config_row.call_args.kwargs
|
|
348
|
+
assert call_kwargs["change_description"] == "AI-1234: rename row"
|
|
349
|
+
|
|
312
350
|
def test_dry_run_output(self, tmp_config_dir: Path) -> None:
|
|
313
351
|
"""--dry-run shows diff in JSON mode."""
|
|
314
352
|
store = setup_single_project(tmp_config_dir)
|
|
@@ -300,6 +300,56 @@ class TestUpdateConfigRow:
|
|
|
300
300
|
call_kwargs = client.update_config_row.call_args.kwargs
|
|
301
301
|
assert call_kwargs["branch_id"] == 99
|
|
302
302
|
|
|
303
|
+
def test_custom_change_description_forwarded(self, tmp_config_dir: Path) -> None:
|
|
304
|
+
"""An explicit change_description is sent verbatim to the client."""
|
|
305
|
+
service, client = _make_service(tmp_config_dir)
|
|
306
|
+
|
|
307
|
+
service.update_config_row(
|
|
308
|
+
alias="prod",
|
|
309
|
+
component_id="keboola.ex-db-snowflake",
|
|
310
|
+
config_id="cfg-001",
|
|
311
|
+
row_id="row-001",
|
|
312
|
+
name="New Name",
|
|
313
|
+
change_description="AI-1234: bump row limit",
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
call_kwargs = client.update_config_row.call_args.kwargs
|
|
317
|
+
assert call_kwargs["change_description"] == "AI-1234: bump row limit"
|
|
318
|
+
|
|
319
|
+
def test_default_change_description_when_omitted(self, tmp_config_dir: Path) -> None:
|
|
320
|
+
"""Omitting change_description preserves the generated default."""
|
|
321
|
+
service, client = _make_service(tmp_config_dir)
|
|
322
|
+
|
|
323
|
+
service.update_config_row(
|
|
324
|
+
alias="prod",
|
|
325
|
+
component_id="keboola.ex-db-snowflake",
|
|
326
|
+
config_id="cfg-001",
|
|
327
|
+
row_id="row-001",
|
|
328
|
+
name="New Name",
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
call_kwargs = client.update_config_row.call_args.kwargs
|
|
332
|
+
assert call_kwargs["change_description"] == (
|
|
333
|
+
"Updated metadata via kbagent config row-update"
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
def test_dry_run_includes_change_description(self, tmp_config_dir: Path) -> None:
|
|
337
|
+
"""dry_run surfaces the change_description that would be sent."""
|
|
338
|
+
service, client = _make_service(tmp_config_dir)
|
|
339
|
+
|
|
340
|
+
result = service.update_config_row(
|
|
341
|
+
alias="prod",
|
|
342
|
+
component_id="keboola.ex-db-snowflake",
|
|
343
|
+
config_id="cfg-001",
|
|
344
|
+
row_id="row-001",
|
|
345
|
+
set_paths=[("parameters.table", "orders")],
|
|
346
|
+
change_description="AI-1234: repoint table",
|
|
347
|
+
dry_run=True,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
assert result["change_description"] == "AI-1234: repoint table"
|
|
351
|
+
client.update_config_row.assert_not_called()
|
|
352
|
+
|
|
303
353
|
|
|
304
354
|
# ---------------------------------------------------------------------------
|
|
305
355
|
# delete_config_row tests
|
|
@@ -457,3 +457,146 @@ class TestConfigUpdateCli:
|
|
|
457
457
|
assert result.exit_code == 0, result.output
|
|
458
458
|
cfg = mock_client.update_config.call_args.kwargs["configuration"]
|
|
459
459
|
assert cfg["parameters"]["tables"] == {"new": "table"}
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
# ---------------------------------------------------------------------------
|
|
463
|
+
# change-description tests
|
|
464
|
+
# ---------------------------------------------------------------------------
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
class TestConfigServiceUpdateChangeDescription:
|
|
468
|
+
"""Tests for the version changeDescription on ConfigService.update_config."""
|
|
469
|
+
|
|
470
|
+
def test_custom_change_description_forwarded(self, tmp_config_dir: Path) -> None:
|
|
471
|
+
"""An explicit change_description is sent verbatim to the client."""
|
|
472
|
+
service, client = _make_service(tmp_config_dir)
|
|
473
|
+
|
|
474
|
+
service.update_config(
|
|
475
|
+
alias="prod",
|
|
476
|
+
component_id="keboola.ex-db-snowflake",
|
|
477
|
+
config_id="cfg-001",
|
|
478
|
+
name="New Name",
|
|
479
|
+
change_description="AI-1234: bump timeout",
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
call_kwargs = client.update_config.call_args.kwargs
|
|
483
|
+
assert call_kwargs["change_description"] == "AI-1234: bump timeout"
|
|
484
|
+
|
|
485
|
+
def test_default_change_description_when_omitted(self, tmp_config_dir: Path) -> None:
|
|
486
|
+
"""Omitting change_description preserves the generated default."""
|
|
487
|
+
service, client = _make_service(tmp_config_dir)
|
|
488
|
+
|
|
489
|
+
service.update_config(
|
|
490
|
+
alias="prod",
|
|
491
|
+
component_id="keboola.ex-db-snowflake",
|
|
492
|
+
config_id="cfg-001",
|
|
493
|
+
name="New Name",
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
call_kwargs = client.update_config.call_args.kwargs
|
|
497
|
+
assert call_kwargs["change_description"] == ("Updated metadata via kbagent config update")
|
|
498
|
+
|
|
499
|
+
def test_dry_run_includes_change_description(self, tmp_config_dir: Path) -> None:
|
|
500
|
+
"""dry_run surfaces the change_description that would be sent."""
|
|
501
|
+
service, client = _make_service(tmp_config_dir)
|
|
502
|
+
|
|
503
|
+
result = service.update_config(
|
|
504
|
+
alias="prod",
|
|
505
|
+
component_id="keboola.ex-db-snowflake",
|
|
506
|
+
config_id="cfg-001",
|
|
507
|
+
set_paths=[("parameters.user", "new-admin")],
|
|
508
|
+
change_description="AI-1234: rotate creds",
|
|
509
|
+
dry_run=True,
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
assert result["change_description"] == "AI-1234: rotate creds"
|
|
513
|
+
client.update_config.assert_not_called()
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
class TestConfigUpdateChangeDescriptionCli:
|
|
517
|
+
"""CLI-level tests for --change-description on config update."""
|
|
518
|
+
|
|
519
|
+
def _invoke(self, tmp_config_dir: Path, args: list[str]) -> Result:
|
|
520
|
+
return runner.invoke(
|
|
521
|
+
app,
|
|
522
|
+
["--json", "--config-dir", str(tmp_config_dir), "config", "update", *args],
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
def test_change_description_flag_forwarded(self, tmp_config_dir: Path) -> None:
|
|
526
|
+
"""--change-description reaches the client as change_description."""
|
|
527
|
+
store = setup_single_project(tmp_config_dir)
|
|
528
|
+
|
|
529
|
+
mock_client = MagicMock()
|
|
530
|
+
mock_client.get_config_detail.return_value = SAMPLE_CONFIG_DETAIL
|
|
531
|
+
mock_client.update_config.return_value = {
|
|
532
|
+
"id": "cfg-001",
|
|
533
|
+
"name": "My Config",
|
|
534
|
+
"componentId": "keboola.ex-db-snowflake",
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
with pytest.MonkeyPatch.context() as mp:
|
|
538
|
+
mp.setattr(
|
|
539
|
+
"keboola_agent_cli.commands.config.get_service",
|
|
540
|
+
lambda ctx, name: ConfigService(
|
|
541
|
+
config_store=store,
|
|
542
|
+
client_factory=lambda url, token: mock_client,
|
|
543
|
+
),
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
result = self._invoke(
|
|
547
|
+
tmp_config_dir,
|
|
548
|
+
[
|
|
549
|
+
"--project",
|
|
550
|
+
"prod",
|
|
551
|
+
"--component-id",
|
|
552
|
+
"keboola.ex-db-snowflake",
|
|
553
|
+
"--config-id",
|
|
554
|
+
"cfg-001",
|
|
555
|
+
"--set",
|
|
556
|
+
"parameters.user=new-admin",
|
|
557
|
+
"--change-description",
|
|
558
|
+
"AI-1234: rotate creds",
|
|
559
|
+
],
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
assert result.exit_code == 0, result.output
|
|
563
|
+
call_kwargs = mock_client.update_config.call_args.kwargs
|
|
564
|
+
assert call_kwargs["change_description"] == "AI-1234: rotate creds"
|
|
565
|
+
|
|
566
|
+
def test_dry_run_echoes_change_description(self, tmp_config_dir: Path) -> None:
|
|
567
|
+
"""--dry-run --json output includes the change_description."""
|
|
568
|
+
store = setup_single_project(tmp_config_dir)
|
|
569
|
+
|
|
570
|
+
mock_client = MagicMock()
|
|
571
|
+
mock_client.get_config_detail.return_value = SAMPLE_CONFIG_DETAIL
|
|
572
|
+
|
|
573
|
+
with pytest.MonkeyPatch.context() as mp:
|
|
574
|
+
mp.setattr(
|
|
575
|
+
"keboola_agent_cli.commands.config.get_service",
|
|
576
|
+
lambda ctx, name: ConfigService(
|
|
577
|
+
config_store=store,
|
|
578
|
+
client_factory=lambda url, token: mock_client,
|
|
579
|
+
),
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
result = self._invoke(
|
|
583
|
+
tmp_config_dir,
|
|
584
|
+
[
|
|
585
|
+
"--project",
|
|
586
|
+
"prod",
|
|
587
|
+
"--component-id",
|
|
588
|
+
"keboola.ex-db-snowflake",
|
|
589
|
+
"--config-id",
|
|
590
|
+
"cfg-001",
|
|
591
|
+
"--set",
|
|
592
|
+
"parameters.user=new-admin",
|
|
593
|
+
"--change-description",
|
|
594
|
+
"AI-1234: rotate creds",
|
|
595
|
+
"--dry-run",
|
|
596
|
+
],
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
assert result.exit_code == 0, result.output
|
|
600
|
+
data = json.loads(result.output)["data"]
|
|
601
|
+
assert data["change_description"] == "AI-1234: rotate creds"
|
|
602
|
+
mock_client.update_config.assert_not_called()
|
|
@@ -1793,6 +1793,54 @@ class TestFullE2E:
|
|
|
1793
1793
|
assert db_config["port"] == 5439
|
|
1794
1794
|
assert "schema" not in db_config
|
|
1795
1795
|
|
|
1796
|
+
# --change-description sets the version changeDescription verbatim.
|
|
1797
|
+
change_desc = f"{RUN_ID} AI-1234: e2e change description"
|
|
1798
|
+
dry = self._run_ok(
|
|
1799
|
+
"config",
|
|
1800
|
+
"update",
|
|
1801
|
+
"--project",
|
|
1802
|
+
self.alias,
|
|
1803
|
+
"--component-id",
|
|
1804
|
+
TEST_COMPONENT_ID,
|
|
1805
|
+
"--config-id",
|
|
1806
|
+
config_id,
|
|
1807
|
+
"--set",
|
|
1808
|
+
"parameters.audit_probe=1",
|
|
1809
|
+
"--change-description",
|
|
1810
|
+
change_desc,
|
|
1811
|
+
"--dry-run",
|
|
1812
|
+
)
|
|
1813
|
+
# --dry-run echoes the change description that would be sent.
|
|
1814
|
+
assert dry["data"]["change_description"] == change_desc
|
|
1815
|
+
|
|
1816
|
+
self._run_ok(
|
|
1817
|
+
"config",
|
|
1818
|
+
"update",
|
|
1819
|
+
"--project",
|
|
1820
|
+
self.alias,
|
|
1821
|
+
"--component-id",
|
|
1822
|
+
TEST_COMPONENT_ID,
|
|
1823
|
+
"--config-id",
|
|
1824
|
+
config_id,
|
|
1825
|
+
"--set",
|
|
1826
|
+
"parameters.audit_probe=1",
|
|
1827
|
+
"--change-description",
|
|
1828
|
+
change_desc,
|
|
1829
|
+
)
|
|
1830
|
+
|
|
1831
|
+
# Verify the new version's changeDescription via config detail.
|
|
1832
|
+
data = self._run_ok(
|
|
1833
|
+
"config",
|
|
1834
|
+
"detail",
|
|
1835
|
+
"--project",
|
|
1836
|
+
self.alias,
|
|
1837
|
+
"--component-id",
|
|
1838
|
+
TEST_COMPONENT_ID,
|
|
1839
|
+
"--config-id",
|
|
1840
|
+
config_id,
|
|
1841
|
+
)
|
|
1842
|
+
assert data["data"]["changeDescription"] == change_desc
|
|
1843
|
+
|
|
1796
1844
|
def _test_config_merge(self, config_id: str) -> None:
|
|
1797
1845
|
"""Test config update --merge: partial merge without losing existing keys."""
|
|
1798
1846
|
# Current state: host=final.example.com, port=5439, database=final_db
|