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
10 changes: 10 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ tests/
test_ai_client.py # AI Service client tests
test_component_service.py # Component service tests
test_component_cli.py # Component CLI tests via CliRunner
test_e2e.py # E2E tests against real API (make test-e2e)
test_integration.py # Integration tests (edge cases, linting)
```

Expand Down Expand Up @@ -199,6 +200,8 @@ All three inherit from `BaseHttpClient` (`http_base.py`) which provides shared r

15. **Pre-commit checks are mandatory.** Before every `git commit`, run `ruff check` and `ruff format --check` on changed files. A pre-commit hook (`scripts/pre-commit`, install via `make hooks`) does this automatically. **Never commit without passing lint + format.** If using sub-agents that write code, always run `make check` (or at minimum `ruff check src/ tests/ && ruff format . --check`) before committing their output.

16. **E2E test coverage**: Every new CLI command MUST have a corresponding E2E test in `tests/test_e2e.py`. Run `make test-e2e` to verify. E2E tests require `E2E_API_TOKEN` and `E2E_URL` env vars and exercise the full CLI against a real Keboola project.

## Claude Code Plugin (Marketplace)

This repo doubles as a Claude Code plugin marketplace. The plugin lives in `plugins/kbagent/` and contains a skill that teaches Claude how to use kbagent.
Expand Down Expand Up @@ -241,6 +244,7 @@ kbagent config list [--project NAME] [--component-type TYPE] [--component-id ID]
kbagent config detail --project NAME --component-id ID --config-id ID [--branch ID]
kbagent config search --query PATTERN [--project NAME] [--component-type TYPE] [--ignore-case] [--regex] [--branch ID]
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]
kbagent config rename --project NAME --component-id ID --config-id ID --name "New Name" [--branch ID] [--directory DIR]

kbagent job list [--project NAME] [--component-id ID] [--status STATUS] [--limit N]
kbagent job detail --project NAME --job-id ID
Expand All @@ -255,6 +259,7 @@ kbagent storage create-table --project NAME --bucket-id ID --name NAME --column
kbagent storage upload-table --project NAME --table-id ID --file PATH [--incremental] [--branch ID]
kbagent storage download-table --project NAME --table-id ID [--output FILE] [--columns COL ...] [--limit N] [--branch ID]
kbagent storage delete-table --project NAME --table-id ID [--table-id ...] [--dry-run] [--yes] [--branch ID]
kbagent storage delete-column --project NAME --table-id ID --column COL [--column ...] [--dry-run] [--yes] [--branch ID]
kbagent storage delete-bucket --project NAME --bucket-id ID [--bucket-id ...] [--force] [--dry-run] [--yes] [--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]
Expand Down Expand Up @@ -302,6 +307,11 @@ kbagent config new --component-id ID [--name NAME] [--project NAME] [--output-di

kbagent encrypt values --project ALIAS --component-id ID --input JSON|@file|- [--output-file PATH]

kbagent kai ping [--project NAME]
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 context
kbagent init [--from-global]
kbagent doctor [--fix]
Expand Down
13 changes: 10 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,29 @@ When adding a new command (e.g., `kbagent storage create-foo`), you must update
- [ ] **Client method** in `client.py` (or `manage_client.py`) -- HTTP layer
- [ ] **Service method** in `services/` -- business logic, validation, orchestration
- [ ] **Command function** in `commands/` -- Typer options, formatter, error handling
- [ ] **Hint definition** in `hints/definitions/` -- register a `CommandHint` for `--hint` code generation (see existing files for pattern)
- [ ] **Hint short-circuit** in the command function -- add `if should_hint(ctx): emit_hint(...)` before service call
- [ ] **`--hint` support** -- every command must support `--hint client` and `--hint service` code generation:
- [ ] **Hint definition** in `hints/definitions/` -- register a `CommandHint` with `ClientCall` + `ServiceCall` (see existing files for pattern)
- [ ] **Hint short-circuit** in the command function -- add `if should_hint(ctx): emit_hint(...)` **before** the service call
- [ ] **Verify** both modes produce valid Python: `kbagent --hint client <command> ...` and `kbagent --hint service <command> ...`
- [ ] **Permission registration** in `permissions.py` (`OPERATION_REGISTRY` dict)
- [ ] **Service wiring** in `cli.py` if adding a new service class

### Documentation changes (mandatory!)

- [ ] **`kbagent context`** -- update `AGENT_CONTEXT` string in `commands/context.py` (this is the primary reference for AI agents)
- [ ] **`kbagent context`** -- update `AGENT_CONTEXT` string in `commands/context.py` (this is the primary reference for AI agents; if it's missing there, AI agents won't know the command exists)
- [ ] **SKILL.md** -- run `make skill-gen` to regenerate the decision table (CI has a freshness check that will fail if the generated output doesn't match). **Do not edit SKILL.md by hand** -- the table is auto-generated from CLI command metadata
- [ ] **CLAUDE.md** -- add command signature to the `## All CLI Commands` section
- [ ] **Plugin references** -- update `plugins/kbagent/skills/kbagent/references/`:
- [ ] **`commands-reference.md`** -- add the new command to the appropriate section (this is a hand-maintained file, NOT auto-generated)
- [ ] **New reference file** -- if the command introduces a new workflow or topic area (e.g. a new subcommand group), create a dedicated `<topic>-workflow.md` in the references directory. Existing examples: `workspace-workflow.md`, `branch-workflow.md`, `sync-workflow.md`, `storage-files-workflow.md`
- [ ] **`gotchas.md`** -- if the command has non-obvious behavior, response format quirks, or common mistakes, document them here
- [ ] **`--help` text** -- Typer docstring and option help strings should be clear and complete

### Tests (mandatory!)

- [ ] **Service-layer tests** -- mock the client, test business logic, edge cases, error propagation
- [ ] **CLI-layer tests** -- use `CliRunner`, test JSON output, error exit codes
- [ ] **E2E tests** -- add a test in `tests/test_e2e.py` that exercises the command against a real Keboola project (requires `E2E_API_TOKEN` + `E2E_URL`). Run `make test-e2e` to verify. Every CLI command must have E2E coverage
- [ ] **Run `make check`** before committing (lint + format + full test suite)

### UX considerations
Expand Down
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.DEFAULT_GOAL := help

.PHONY: help install install-mcp sync test test-unit test-integration 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 clean hooks

help: ## Show this help message
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'

install: ## Install in development mode (editable)
uv pip install -e ".[dev]"
Expand All @@ -14,15 +14,18 @@ install-mcp: ## Install Keboola MCP server (required for 'tool' commands)
sync: ## Sync dependencies from lockfile
uv sync

test: ## Run all tests
uv run pytest tests/ -v
test: ## Run all tests (excluding e2e — use test-e2e separately)
uv run pytest tests/ -v -m "not e2e"

test-unit: ## Run unit tests only (exclude integration)
uv run pytest tests/ -v -m "not integration"
test-unit: ## Run unit tests only (exclude integration and e2e)
uv run pytest tests/ -v -m "not integration and not e2e"

test-integration: ## Run integration tests only
uv run pytest tests/ -v -m integration

test-e2e: ## Run E2E tests (E2E_API_TOKEN and E2E_URL required)
uv run pytest tests/test_e2e.py -v -s --tb=long

test-file: ## Run a specific test file (FILE=tests/test_cli.py)
uv run pytest $(FILE) -v

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Auto-updates on every launch. Run `kbagent changelog` to see what changed.

This CLI is built AI-first. Every command outputs structured JSON (`--json`), errors include machine-readable codes, and the permission firewall enforces safety at the code level -- not via prompt instructions.

**Claude Code plugin** (agent learns all 74 commands automatically):
**Claude Code plugin** (agent learns all 80 commands automatically):

```
/plugin marketplace add padak/keboola_agent_cli
Expand Down Expand Up @@ -77,6 +77,7 @@ kbagent workspace query --project prod --workspace-id WS_ID \
| **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. |
| **Sharing & lineage** | Cross-project data lineage via bucket sharing. Share/link/unlink with org/project/user access control. |
| **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. |
| **Auto-update** | Self-updates on startup. "What's new" after each update. Full changelog via `kbagent changelog`. |
Expand Down Expand Up @@ -110,10 +111,10 @@ Full command reference with flags: [SKILL.md](plugins/kbagent/skills/kbagent/SKI
kbagent project add | list | remove | edit | status | refresh
kbagent org setup
kbagent component list | detail
kbagent config list | detail | search | update | delete | new
kbagent config list | detail | search | update | rename | delete | new
kbagent job list | detail | run
kbagent storage buckets | bucket-detail | create-bucket | delete-bucket
tables | table-detail | create-table | upload-table | download-table | delete-table
tables | table-detail | create-table | upload-table | download-table | delete-table | delete-column
files | file-detail | file-upload | file-download | file-tag | file-delete
load-file | unload-table
kbagent sharing list | share | unshare | link | unlink
Expand All @@ -122,6 +123,7 @@ kbagent branch list | create | use | reset | delete | merge
kbagent workspace create | list | detail | delete | password | load | query | from-transformation
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
Expand Down
Loading
Loading