Skip to content

Specify the kbagent command-line interface and release it as 1.0.0 #791

Open

Description

@soustruh

Summary

kbagent has no specification for its command-line interface. Each command sets its own conventions for names, arguments, input, target selection, output, confirmation and exit codes. Users and AI agents cannot predict this behavior. This issue asks for one specification of the interface and for shared code and CI checks that enforce it. The unified interface then ships as kbagent 1.0.0. After that, every change to the command-line interface must follow the specification.

Proposal, version 3 of 2026-10-14: kbagent Interface Proposal (Keboola members only).

Evidence

The numbers come from main at c0bbecc (0.99.0), which has 289 commands. Method: a script walks the Typer command tree. The command categories come from OPERATION_REGISTRY. No command was run.

  • Target selection. --project is required on 172 commands, optional on 36, repeatable on 20 and absent on 61. An omitted --project has different meanings. 18 read commands read all registered projects. Commands that require the option fail. Other commands use the default-project order.
  • "All projects" has two forms: --all-projects (only sync pull, sync push and sync diff) and an omitted --project.
  • Branch. --branch has 45 different help texts.
  • IDs are given in three ways. 19 commands take positional arguments. The agent commands accept the same task ID as a positional argument, as --id and as --task-id.
  • Input from a file has 12 option names.
  • Short forms. -p works on 24 of the 228 commands that have --project.
  • Safety flags. 24 of the 41 destructive commands have no --dry-run, and 8 have neither --yes nor --force. The 8 --force options have different meanings.
  • Drift continues. A prototype of the CI check finds 611 violations (586 at 0.95.0). The 8 commands that were added after 0.95.0 brought 25 new violations. One of these pull requests was reviewed by hand against the draft rules.

Cause

Each of the bugs #684, #745 and #766 was fixed by one shared mechanism and a test that fails when code bypasses it:

A written rule alone does not hold. CONTRIBUTING.md asks for --dry-run and --yes on destructive commands, but 24 of the 41 destructive commands have no --dry-run. So the specification is the index of the shared mechanisms and the record of decisions, and checks enforce its rules.

Deliverables

  1. docs/cli-interface-spec.md, at most about 5,000 words. Each rule has an ID, a level and one example. Each MUST rule names the CI rule, the contract test or the review step that enforces it. Areas:

    • command structure and naming
    • arguments and options
    • input
    • target selection: project, branch, stack, saved choices, all projects, environment variables, order of precedence
    • output: human output, the --json envelope, stdout and stderr, warnings
    • errors and exit codes
    • safety: --dry-run, --yes, --force, behavior without a terminal
    • repeatability
    • lists
    • help text
    • secrets
    • documents for agents: kbagent context and the plugin documents
    • long-running operations: --wait and --timeout
    • environment variables and global options
    • versions and updates
    • kbagent serve: how REST routes map to commands, and their HTTP methods
    • change policy and versioning
  2. Shared code that new commands use: option definitions in one module, one command class for every command, the resolvers, the exit-code helper, one confirmation helper, and shared renderers for human output.

  3. make cli-spec-check, with these parts:

    • rules that read the command tree and the source code
    • a baseline file with the existing violations and a blocking flag for each rule
    • offline contract tests for rules about runtime behavior

    CI fails on a new violation, on a baseline entry that is already fixed, and on a baseline that grows in a pull request.

  4. Checks for human output: a rule that forbids direct printing in commands/ outside OutputFormatter and the shared renderers, and snapshot tests of the human output of each renderer.

  5. docs/cli-manifest.json: a manifest that is generated from the command tree and committed. It contains the commands, options, value kinds, categories and help texts. The command reference, the command part of kbagent context, the check and the inventory report use it as their source.

  6. A binding rule: CLAUDE.md, CONTRIBUTING.md and the kbagent-pr-reviewer playbook refer to the specification. The reviewer playbook checks the human-output rules and the manifest and snapshot diffs.

Release as 1.0.0

  • The unified interface ships as kbagent 1.0.0. Tags keep the v prefix.

  • New installs get 1.0 on the release day on every channel. This includes CI pipelines that install kbagent without a pinned version.

  • Existing installs that update through kbagent stay on 0.x for 28 days after the published_at time of the GitHub release v1.0.0. Then they update themselves. kbagent reads this date from GitHub. The date is not in the code. kbagent update --major updates earlier.

  • At least 14 days before 1.0.0, a 0.x patch release adds these parts to the updater:

    • a major-version gate (today the updater installs any newer version)
    • the migration date
    • a deprecation notice, on stderr and in warnings[] with --json
    • kbagent update --major
  • The release workflow publishes v1.0.0 with make_latest: false until the migration date. Clients without the patch follow the "latest" flag.

  • docs/migrate-to-1.0.md lists every change in 1.0.0.

  • Until 1.0.0, the 0.x releases contain only these changes:

    • bug fixes, security fixes and fixes against data loss
    • the updater patch
    • additive forms for the migration (--all-projects, warnings[])

    All other interface changes ship in 1.0.0.

Change policy after 1.0.0

A deprecated form keeps working with a warning for at least 28 days. After that, a minor release removes it. A fix that restores documented behavior ships at once. The SDK follows semantic versioning.

Sub-issues

Each group of changes gets its own sub-issue under this issue. There is one list for the 0.x releases and one for 1.0.0. The proposal contains both lists.

Acceptance criteria

  • docs/cli-interface-spec.md covers every area above and has an approved review.
  • make cli-spec-check runs in CI with its baseline and fails on a new violation.
  • docs/cli-manifest.json is committed, and CI checks that it is current.
  • The rule against direct printing and the snapshot tests of the renderers run in CI.
  • CLAUDE.md, CONTRIBUTING.md and the kbagent-pr-reviewer playbook refer to the specification as binding.
  • One sub-issue exists for each group of changes, for the 0.x releases and for 1.0.0.
  • The 0.x updater patch is released at least 14 days before 1.0.0, and 1.0.0 is released as described above.

Activity

  1. added
    epicUmbrella issue tracking multiple sub-issues
    on Sep 25, 2026
  2. added theissue type on Sep 25, 2026
  3. changed the title [-]Specify the command-line interface: one rule set for project, branch and safety flags[/-] [+]Specify the complete kbagent command-line interface[/+] on Sep 25, 2026
  4. soustruh commented on Sep 26, 2026

    @soustruh
    ContributorAuthor

    Input for the naming rules and the target selection area of this specification.

    kbagent project use and kbagent branch use save the same kind of choice. The CLI names this choice differently for projects and for branches:

    Project (project use) Branch (branch use)
    Field in config.json default_project active_branch_id
    CLI help and output Pin <alias> as the default project, Pinned: set the active branch, Branch ID to activate
    --json project current: "source": "pin", key pinned none
    REST (kbagent serve) Get the active project, Switch the active project Pin the active branch
    Code resolve_pinned_alias() resolve_branch(), result effective_branch_id
    • The project side uses three terms for one concept: "default project", "pin" and "active project".
    • The branch side uses "active branch" and, in one REST summary, "pin".
    • "Default" has two meanings. For a project, it is the saved choice. For a branch, it is the production branch, for example in Reset to the default branch.

    The specification must select one term for this concept and use it for projects and branches in the CLI, in --json and in REST.

    The fix for #766 does not change these names. It uses the current branch term, for example branch_source: "active_branch" in the --json output.

  5. linear-code commented on Sep 29, 2026

    @linear-code
  6. soustruh commented on Sep 29, 2026

    @soustruh
    ContributorAuthor

    Linear: CLI-20

  7. soustruh commented on Oct 6, 2026

    @soustruh
    ContributorAuthor

    Serve: HTTP method of a route that changes an object

    I found this while I reviewed #715 and #778. The draft has no rule for the HTTP method of a kbagent serve route that changes an object. The routes use PUT and PATCH for the same kind of change.

    Current state on main:

    Change Routes
    Only the fields in the request change, with PATCH PATCH /configs/{project}/{component_id}/{config_id} (config update), PATCH .../rows/{row_id} (config row-update), PATCH /flows/{project}/{config_id}, PATCH /transformations/{project}/{config_id}, PATCH /agents/{task_id}, PATCH /projects/{alias}
    Only the fields in the request change, with PUT PUT /semantic-layer/items/{kind}/{name} (edit), PUT /merge-requests/{project}/{merge_request_id} (update). #778 adds PUT /rls/{project}/{policy_id} and PUT /cls/{project}/{policy_id}
    A set of keys merges into the existing set by default, with PUT PUT /configs/{project}/{component_id}/{config_id}/variables (replace: false by default), PUT /data-apps/{project}/{app_id}/secrets
    One value is replaced, with PUT PUT .../metadata/{key}, PUT .../state, PUT /projects/{alias}/description, PUT /branches/{project}/metadata/{key}, PUT /semantic-layer/reference-data

    Proposed rule:

    • A route that changes only the fields in the request uses PATCH.
    • A route that replaces the whole resource at its URL, or sets one value, uses PUT.
    • A new route follows the rule. The existing PUT routes with partial updates go to the baseline. For the two routes that merge by default (variables, secrets), the spec decides: PATCH, or PUT with the merge stated in the route summary.
    • A changed method breaks REST clients, so it follows the change policy. During the window, the old method keeps working and returns a warning header.

    The rule covers only the REST interface. The method that kbagent sends to a Keboola API depends on that API. For example, the Storage API has no PATCH for configurations. So config update, flow update and transformation edit read the configuration and send a PUT.

  8. changed the title [-]Specify the complete kbagent command-line interface[/-] [+]Specify the kbagent command-line interface and release it as 1.0.0[/+] on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicUmbrella issue tracking multiple sub-issues

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions