Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ Note: `SKILL.md` instructs Claude to run `kbagent context` as its first step, wh
## All CLI Commands

```
# Global options: --json, --verbose, --no-color, --config-dir, --hint client|service
# Global options: --json, --verbose, --no-color, --config-dir, --hint client|service, --deny-writes, --deny-destructive

kbagent project add --project NAME --url URL --token TOKEN
kbagent project list
Expand All @@ -244,6 +244,8 @@ kbagent project refresh --project ALIAS [--dry-run] [--force] [--yes] [--token-d
kbagent project refresh --all [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
kbagent project description-get --project NAME
kbagent project description-set --project NAME [--text STR | --file PATH | --stdin]
kbagent project use ALIAS
kbagent project current

kbagent config list [--project NAME] [--component-type TYPE] [--component-id ID] [--branch ID]
kbagent config detail --project NAME --component-id ID --config-id ID [--branch ID]
Expand All @@ -253,10 +255,15 @@ kbagent config rename --project NAME --component-id ID --config-id ID --name "Ne
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]
kbagent config variables-get --project NAME --component-id ID --config-id ID [--branch ID]
kbagent config variables-clear --project NAME --component-id ID --config-id ID [--branch ID] [--yes]
kbagent config metadata-list --project NAME --component-id ID --config-id ID [--branch ID]
kbagent config get-metadata --project NAME --component-id ID --config-id ID --key KEY [--branch ID]
kbagent config set-metadata --project NAME --component-id ID --config-id ID --key KEY --value VALUE [--branch ID]
kbagent config delete-metadata --project NAME --component-id ID --config-id ID --metadata-id ID [--branch ID] [--yes]
kbagent config set-folder --project NAME --component-id ID --config-id ID --name FOLDER [--branch ID]

kbagent job list [--project NAME] [--component-id ID] [--status STATUS] [--limit N]
kbagent job detail --project NAME --job-id ID
kbagent job run --project NAME --component-id ID --config-id ID [--row-id ID ...] [--wait] [--timeout N] [--branch ID] [--variable-values-id ID] [--no-variables]
kbagent job run --project NAME --component-id ID --config-id ID [--row-id ID ...] [--wait] [--timeout N] [--branch ID] [--variable-values-id ID] [--no-variables] [--poll-strategy exponential|fixed] [--log-tail-lines N]
kbagent job terminate --project NAME (--job-id ID [--job-id ID ...] | --status any|created|waiting|processing [--component-id ID] [--config-id ID] [--branch ID] [--limit N]) [--dry-run] [--yes]

kbagent storage buckets [--project NAME] [--branch ID]
Expand All @@ -270,6 +277,10 @@ kbagent storage download-table --project NAME --table-id ID [--output FILE] [--c
kbagent storage delete-table --project NAME --table-id ID [--table-id ...] [--force] [--dry-run] [--yes] [--branch ID]
kbagent storage delete-column --project NAME --table-id ID --column COL [--column ...] [--force] [--dry-run] [--yes] [--branch ID]
kbagent storage delete-bucket --project NAME --bucket-id ID [--bucket-id ...] [--force] [--dry-run] [--yes] [--branch ID]
kbagent storage describe-bucket --project NAME --bucket-id ID [--text STR | --file PATH | --stdin] [--branch ID]
kbagent storage describe-table --project NAME --table-id ID [--text STR | --file PATH | --stdin] [--branch ID]
kbagent storage describe-column --project NAME --table-id ID --column NAME=DESC [--column ...] [--branch ID]
kbagent storage describe-batch --project NAME --from-file YAML [--branch ID]
kbagent storage files --project NAME [--tag TAG ...] [--limit N] [--offset N] [--query Q] [--branch ID]
kbagent storage file-upload --project NAME --file PATH [--name NAME] [--tag TAG ...] [--permanent] [--branch ID]
kbagent storage file-download --project NAME [--file-id ID | --tag TAG ...] [--output FILE]
Expand Down Expand Up @@ -309,13 +320,14 @@ kbagent branch metadata-set --project NAME --key KEY [--text STR | --file PATH |
kbagent branch metadata-delete --project NAME --metadata-id ID [--branch ID|default]

kbagent workspace create --project ALIAS [--name NAME] [--backend TYPE] [--ui] [--read-only/--no-read-only]
kbagent workspace list [--project NAME]
kbagent workspace list [--project NAME ...] [--orphaned]
kbagent workspace detail --project ALIAS --workspace-id ID
kbagent workspace delete --project ALIAS --workspace-id ID
kbagent workspace password --project ALIAS --workspace-id ID
kbagent workspace load --project ALIAS --workspace-id ID --tables TABLE_ID [--tables ...] [--preserve]
kbagent workspace query --project ALIAS --workspace-id ID --sql "SELECT ..." [--transactional]
kbagent workspace query --project ALIAS --workspace-id ID --file query.sql
kbagent workspace gc [--project NAME ...] [--dry-run] [--yes]
kbagent workspace from-transformation --project ALIAS --component-id ID --config-id ID [--row-id ID]

kbagent component list [--project NAME] [--type TYPE] [--query QUERY]
Expand All @@ -329,6 +341,15 @@ kbagent kai ask --message "question" [--project NAME]
kbagent kai chat --message "msg" [--chat-id ID] [--project NAME]
kbagent kai history [--project NAME] [--limit N]

kbagent flow list [--project NAME] [--branch ID]
kbagent flow detail --project NAME --flow-id ID [--component-id keboola.orchestrator|keboola.flow] [--branch ID]
kbagent flow schema
kbagent flow new --project NAME --name NAME [--component-id keboola.orchestrator|keboola.flow] [--description D] [--file @path.yaml|-|JSON] [--branch ID]
kbagent flow update --project NAME --flow-id ID [--component-id ID] [--name N] [--description D] [--file @path.yaml|-|JSON] [--branch ID]
kbagent flow delete --project NAME --flow-id ID [--component-id ID] [--branch ID] [--yes]
kbagent flow schedule --project NAME --flow-id ID --cron "0 6 * * *" [--component-id ID] [--timezone TZ] [--disabled] [--branch ID]
kbagent flow schedule-remove --project NAME --flow-id ID [--component-id ID] [--branch ID] [--yes]

kbagent context
kbagent init [--from-global]
kbagent doctor [--fix]
Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DEFAULT_GOAL := help

.PHONY: help install install-mcp sync test test-unit test-integration test-e2e test-file lint lint-fix format format-check skill-check skill-gen version-sync version-check changelog changelog-check check clean hooks
.PHONY: help install install-mcp sync test test-unit test-integration test-e2e test-file lint lint-fix format format-check skill-check skill-gen version-sync version-check changelog changelog-check check-error-codes check clean hooks

help: ## Show this help message
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
Expand Down Expand Up @@ -73,12 +73,15 @@ changelog: ## Generate changelog skeleton from GitHub releases
changelog-check: ## Check all releases have changelog entries
uv run python scripts/generate_changelog.py --check

check-error-codes: ## Reject raw error_code string literals in source (use ErrorCode enum)
uv run python scripts/check_error_codes.py

hooks: ## Install git pre-commit hook (lint + format on staged files)
cp scripts/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
@echo "Pre-commit hook installed."

check: lint format-check skill-check version-check changelog-check test ## Run all checks (lint + format + skill + version + changelog + test)
check: lint format-check skill-check version-check changelog-check check-error-codes test ## Run all checks (lint + format + skill + version + changelog + error-codes + test)

clean: ## Remove build artifacts and caches
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
Expand Down
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,19 @@ kbagent workspace query --project prod --workspace-id WS_ID \
| Area | What you get |
|------|-------------|
| **Multi-project** | All read commands query every connected project in parallel. One command, all projects. |
| **Configurations** | List, search, inspect, scaffold, update, delete configs. Full-text search across all config bodies. |
| **Jobs** | List, inspect, run with `--wait` polling and `--timeout`. Row-level execution for multi-row configs. |
| **Storage** | Buckets, tables, files -- full CRUD. Upload CSV (auto-creates bucket+table). Download by file ID or by tag. |
| **Dev branches** | Create a branch, activate it, and every command auto-targets it. Storage, MCP, sync -- everything follows. |
| **Sync & GitOps** | Pull configs as YAML, edit in IDE, push back. SQL/Python extracted as real files. Diff and status tracking. |
| **Configurations** | List, search, inspect, scaffold, update, delete configs. Full-text search across all config bodies (incl. rows). Metadata CRUD + folder grouping. |
| **Jobs** | List, inspect, run with `--wait` polling (exponential curve), `--timeout` auto-kill, log tail on failure. Row-level execution for multi-row configs. |
| **Flows** | Create, update, delete orchestrator/flow configs with phase/task DAG validation. Attach cron schedules (timezone + enabled/disabled state). |
| **Storage** | Buckets, tables, files -- full CRUD. Upload CSV (auto-creates bucket+table). Download by file ID or by tag. Descriptions on buckets/tables/columns (batch-applicable from YAML). |
| **Dev branches** | Create a branch, activate it, and every command auto-targets it. Storage writes, MCP, sync -- everything follows. Storage reads default to production (safer). |
| **Sync & GitOps** | Pull configs as YAML, edit in IDE, push back. SQL/Python extracted as real files. Diff and status tracking. Adopt existing kbc Go CLI checkouts (`sync init --adopt-existing`). |
| **MCP tools** | Call `keboola-mcp-server` tools with auto-expand, multi-project fan-out, branch propagation, schema validation. |
| **Workspaces** | Create Snowflake/BQ workspace, load tables, run SQL. Create from transformation config for instant debugging. |
| **Workspaces** | Create Snowflake/BQ workspace, load tables, run SQL. Create from transformation config for instant debugging. Orphan detection + garbage collection. |
| **Sharing** | Cross-project bucket sharing with org/project/user access control. Share, link, unlink. |
| **Lineage** | Column-level dependency analysis across projects. SQL/Python parsing, AI-enhanced detection, interactive web browser, Mermaid/HTML/ER export. |
| **Kai (AI Assistant)** | Ask Keboola's built-in AI questions about your project. One-shot or chat sessions with full MCP context. |
| **Encryption** | Encrypt secrets (`#password`, `#api_token`) via Keboola Encryption API. Works with sync push and MCP. |
| **Permissions** | Firewall for AI agents: read-only, deny-writes, deny-destructive. Code-level enforcement, not prompt tricks. |
| **Permissions** | Firewall for AI agents: read-only, deny-writes, deny-destructive (session-only flags or persisted policy). Project pin + `KBAGENT_PROJECT` env override. Code-level enforcement, stable `ErrorCode` enum, not prompt tricks. |
| **Auto-update** | Self-updates on startup. "What's new" after each update. Full changelog via `kbagent changelog`. |

## Setup options
Expand Down Expand Up @@ -109,25 +110,33 @@ Run `kbagent doctor` to verify your setup.
Full command reference with flags: [SKILL.md](plugins/kbagent/skills/kbagent/SKILL.md)

```
kbagent project add | list | remove | edit | status | refresh
kbagent project add | list | remove | edit | status | refresh | use | current
kbagent org setup
kbagent component list | detail
kbagent config list | detail | search | update | rename | delete | new
kbagent job list | detail | run
metadata-list | get-metadata | set-metadata | delete-metadata | set-folder
variables-set | variables-get | variables-clear
kbagent job list | detail | run | terminate
kbagent flow list | detail | schema | new | update | delete | schedule | schedule-remove
kbagent storage buckets | bucket-detail | create-bucket | delete-bucket
tables | table-detail | create-table | upload-table | download-table | delete-table | delete-column
describe-bucket | describe-table | describe-column | describe-batch
files | file-detail | file-upload | file-download | file-tag | file-delete
load-file | unload-table
kbagent sharing list | share | unshare | link | unlink
kbagent sharing list | share | unshare | link | unlink | edges
kbagent lineage build | show | info | server
kbagent branch list | create | use | reset | delete | merge
kbagent workspace create | list | detail | delete | password | load | query | from-transformation
metadata-list | metadata-get | metadata-set | metadata-delete
kbagent workspace create | list | detail | delete | password | load | query | from-transformation | gc
kbagent tool list | call
kbagent sync init | pull | status | diff | push | branch-link | branch-unlink | branch-status
kbagent kai ping | ask | chat | history
kbagent encrypt values
kbagent permissions list | show | set | reset | check
kbagent init | context | doctor | version | update | changelog

# Global flags: --json, --verbose, --no-color, --config-dir, --hint client|service
# --deny-writes, --deny-destructive (session-only firewall)
```

## Documentation
Expand Down
129 changes: 129 additions & 0 deletions docs/error-codes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# kbagent Error Code Reference

All machine-readable codes emitted via `--json` output. Every code is a member
of `ErrorCode` in `src/keboola_agent_cli/errors.py`.

## Versioning

| Change | Version impact |
|---|---|
| Add a new code | Minor bump |
| Rename or remove a code | Major bump |

## Code catalogue

### Auth / access

| Code | Description |
|---|---|
| `INVALID_TOKEN` | Storage API token is invalid or expired |
| `ACCESS_DENIED` | Token lacks the required permission for this API call |
| `PERMISSION_DENIED` | Operation blocked by the active kbagent permission policy |

### Network / transport

| Code | Description |
|---|---|
| `TIMEOUT` | HTTP request timed out |
| `CONNECTION_ERROR` | TCP-level connection failure |
| `RETRY_EXHAUSTED` | All retry attempts failed (typically after 429/5xx) |

### API / generic

| Code | Description |
|---|---|
| `API_ERROR` | Unexpected HTTP error from the Keboola API |
| `NOT_FOUND` | Requested resource does not exist (404) |
| `ALREADY_EXISTS` | Resource or file already exists and was not overwritten |
| `VALIDATION_ERROR` | Request failed API-side validation |
| `INVALID_ARGUMENT` | Caller supplied an invalid argument value |
| `INVALID_FORMAT` | Input is not in the expected format |
| `USAGE_ERROR` | Incorrect CLI flag combination or missing required argument |
| `MISSING_PARAMETER` | A required parameter was not supplied |
| `UNKNOWN_ERROR` | Catch-all for unclassified errors |

### Configuration

| Code | Description |
|---|---|
| `CONFIG_ERROR` | kbagent config problem (e.g. unknown project alias) |
| `NOT_INITIALIZED` | `.keboola/manifest.json` not found; run `sync init` first |
| `INIT_ERROR` | Error during `sync init` auto-init path |

### Jobs

| Code | Description |
|---|---|
| `QUEUE_JOB_FAILED` | Queue API job finished with status `error` or `warning` |
| `QUEUE_JOB_TIMEOUT` | Polling timed out waiting for a Queue job |
| `STORAGE_JOB_FAILED` | Storage API async job finished in a failed state |
| `STORAGE_JOB_TIMEOUT` | Polling timed out waiting for a Storage async job |
| `QUERY_JOB_FAILED` | Query Service job finished in a failed state |
| `QUERY_JOB_TIMEOUT` | Polling timed out waiting for a Query Service job |

### Variables

| Code | Description |
|---|---|
| `NO_VARIABLE_ROWS` | Linked `keboola.variables` config has no rows (fix: `config variables-set`) |
| `MALFORMED_VARIABLES_ROW` | Variables row returned by the API is missing a usable `id` |

### Storage

| Code | Description |
|---|---|
| `UPLOAD_FAILED` | Cloud storage upload to S3/Azure/GCS failed |
| `EXPORT_EMPTY_MANIFEST` | Sliced export manifest contains no slices |
| `EXPORT_NO_FILE` | Export manifest lists no downloadable file |
| `EXPORT_NO_URL` | Export entry has no download URL |
| `NOT_SLICED` | Attempted a sliced-file operation on a non-sliced file |
| `FILE_NO_URL` | File metadata has no usable download URL |

### I/O

| Code | Description |
|---|---|
| `FILE_NOT_FOUND` | Local file path does not exist |
| `DIR_NOT_FOUND` | Local directory path does not exist |
| `READ_ERROR` | Error reading a local file |
| `WRITE_ERROR` | Error writing a local file |
| `INPUT_ERROR` | Invalid or unparseable input data |

### Lineage

| Code | Description |
|---|---|
| `NODE_NOT_FOUND` | Requested node not found in the lineage graph |

### Sharing

| Code | Description |
|---|---|
| `INVALID_SHARING_TYPE` | Unsupported bucket sharing type |
| `NOT_LINKED_BUCKET` | Bucket is not a linked bucket |

### KAI (AI Service)

| Code | Description |
|---|---|
| `KAI_ERROR` | AI Service request failed |
| `KAI_NOT_ENABLED` | KAI is not enabled on this project |

### Workspace / Query

| Code | Description |
|---|---|
| `MISSING_QUERY` | No SQL query was provided |
| `WORKSPACE_NOT_FOUND` | Workspace not found in the project |

### Sync

| Code | Description |
|---|---|
| `PARENT_CONFIG_NOT_TRACKED` | Row operation references a parent config not in the manifest |

### Encryption

| Code | Description |
|---|---|
| `ENCRYPTION_FAILED` | Secret encryption via the Encryption API failed |
2 changes: 1 addition & 1 deletion plugins/kbagent/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kbagent",
"version": "0.21.2",
"version": "0.22.0",
"description": "AI-friendly interface to Keboola Connection projects — explore configs, jobs, lineage, call MCP tools, manage dev branches, and debug SQL in workspaces",
"author": {
"name": "Keboola",
Expand Down
Loading
Loading