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
15 changes: 11 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -958,10 +958,17 @@ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL
# (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
# readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app deploy`.
# The platform injects the clone credentials at deploy time, so no credential wiring is needed.
# deploy pins the LATEST configVersion when a git block is present and omits it for a PURE managed
# repo (deploys from managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to
# stopped (setup-phase failures produce no container logs).
kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--copy] [--reveal]
# deploy pins the LATEST configVersion. For a PURE managed repo (no git block yet), it first
# backfills parameters.dataApp.git from the managed repo's URL, then pins the resulting version
# (CLI-15) -- omitting configVersion alone does NOT provision the app's workspace;
# grant provisioning is gated on that block's presence, not on configVersion. The deploy result
# reports it (`git_backfilled`, `git_branch`, `warnings[]`). The branch written is `--git-branch`;
# without it, `main` for an app with no runs, and a VALIDATION_ERROR before any write for an app
# with runs (branch unknown: pass `--git-branch` with the branch the code is on). It has no effect
# on a deploy that does not backfill. Push the managed repo's code to that branch.
# Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines). Use `data-app runs`
# to debug a deploy that reverts to stopped (setup-phase failures produce no container logs).
kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--git-branch BRANCH] [--copy] [--reveal]
kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
kbagent data-app delete --project NAME --app-id ID [--yes]
Expand Down
7 changes: 7 additions & 0 deletions plugins/kbagent/agents/keboola-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,13 @@ its absence is NOT a promise the entry is version-independent (see §1 Rule 6).
`config detail` -> `configuration.runtime` FIRST (an empty `data-app logs`
grep rules nothing out). `create` defaults it ON at **0.87.0+**; <= 0.86.0
patch + redeploy.
- **Managed-repo app `running` with no `WORKSPACE_ID`**: before vNEXT (CLI-15),
`deploy` on a pure `--use-managed-git-repo` app wrote no
`parameters.dataApp.git`, and the workspace grant is gated on that block --
`data-app detail` shows `Git: {}`. vNEXT+ backfills it on deploy (managed repo
must be pushed to the `deploy --git-branch` branch; without the flag `main`
for an app with no runs, and an error before any write for an app with runs --
pass `--git-branch` with the branch the code is on); older: merge the block by hand, then redeploy.
- **`data-app password` keeps the password out of the chat (0.96.1+)**: it
never prints it without `--reveal`; the user copies it with `c` in their own
terminal, or you run `--copy`. Project token only -- no Manage token. Below
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ Lifecycle for `keboola.data-apps`. Combines Storage API (config body, git block,
- `data-app list [--project NAME ...] [--branch ID]` -- list data apps across projects (Data Science index merged with Storage names). Since v0.43.9 filters out workspace/sandbox deployments (`componentId=keboola.sandboxes`, `type=snowflake`/`bigquery`) that the Data Science `/apps` collection also returns, so the listing matches the Apps UI. Envelope carries `component_id` per app.
- `data-app detail --project NAME --app-id ID [--branch ID]` -- merged view (state, desired, url, configVersion, slug, git block with PAT redacted)
- `data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL | --use-managed-git-repo) [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--workspace/--no-workspace] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run] [--copy] [--reveal]` -- POST shell + encrypt PAT + PUT Storage config (with auto-injected `parameters.id`) + PATCH deploy with the §9 trio. Cleanup-in-finally on failure unless `--keep-on-failure`. Default `--auth password` makes the platform generate a 20-char hex simpleAuth password during the deploy. With `--wait` the password is delivered like `data-app password` once the app runs (since 0.96.1); `--copy` / `--reveal` need `--wait` and a deploy (exit 2 with `--no-deploy` or `--use-managed-git-repo`). `--dry-run` accepts and refuses the same flags and adds `password_delivery` (`prompt` / `clipboard` / `stdout`) plus the warning the real run would give. **Exactly one git source required.** `--use-managed-git-repo` provisions an EMPTY Keboola-hosted repo (POST `useManagedGitRepo:true`), writes NO `parameters.dataApp.git` block, and forces `--no-deploy` (empty repo, nothing to run); mutually exclusive with `--git-repo` and all `--git-*`/PAT flags. Managed-repo deploy WORKS with no credential wiring (verified live -- tic-tac-toe deployed and serving from a Keboola-managed repo). Full flow to a RUNNING app: `git-credentials-create --type http_token --permissions readWrite` -> `git push` your code to the managed repo URL (`data-app git-repo` shows it) -> `data-app deploy`. The platform injects the clone credentials at deploy time, so nothing extra goes into the config; the created credential is only used to authenticate YOUR push. **`--workspace` (since 0.87.0) is ON by default** and writes `runtime.workspace.enabled: true` -- the single switch that makes the platform provision the app's ephemeral workspace and inject `WORKSPACE_ID` / `QUERY_SERVICE_URL` / `KBC_WORKSPACE_MANIFEST_PATH`. Every app that reads Storage needs it; before 0.87.0 kbagent never wrote it, so such an app deployed, reported `state=running`, passed its health probe and read nothing, with NO platform-side diagnostic (check `config detail` -> `configuration.runtime`; a `Missing env vars: WORKSPACE_ID` log line, if any, comes from the app's own code, so its absence rules nothing out). Pass `--no-workspace` only for an app that never touches Storage -- it omits the key entirely (no `enabled: false`), leaving the body identical to 0.86.0. The block is a sibling of `runtime.backend`. Not gated on any project feature. Retrofit an existing app with `config update --merge --set 'runtime.workspace.enabled=true'` then `data-app deploy`.
- `data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--copy] [--reveal]` -- the §9 redeploy contract. With `--wait` on a password app (since 0.96.1) the password is delivered like `data-app password`: the `c` prompt in a terminal (the command then ends after Enter or 120 s), `--copy`, or `--reveal`; both flags need `--wait` (exit 2 otherwise, before any API call). With no flag and no prompt (no terminal, a background job, `--json`) the password is not read and the output is as before. With a flag, `--json` adds only `ui_url`, `password_delivered_to` and (`--reveal`) `password`; a non-password app with a flag, or any failure to read the password after the deploy, is a `warnings[]` entry with exit 0. The `kbagent serve` create / deploy routes do not deliver the password. Default reads latest Storage version; `--config-version` pins an older version (rollback). Since 0.65.0: omits `configVersion` for a PURE managed repo (no git block -- deploys from `app.managedGitRepoId`, and the platform injects the clone credentials) and pins the LATEST Storage `configVersion` when a git block is present (external repos). An explicit `--config-version` always wins.
- `data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--git-branch BRANCH] [--copy] [--reveal]` -- the §9 redeploy contract. With `--wait` on a password app (since 0.96.1) the password is delivered like `data-app password`: the `c` prompt in a terminal (the command then ends after Enter or 120 s), `--copy`, or `--reveal`; both flags need `--wait` (exit 2 otherwise, before any API call). With no flag and no prompt (no terminal, a background job, `--json`) the password is not read and the output is as before. With a flag, `--json` adds only `ui_url`, `password_delivered_to` and (`--reveal`) `password`; a non-password app with a flag, or any failure to read the password after the deploy, is a `warnings[]` entry with exit 0. The `kbagent serve` create / deploy routes do not deliver the password. Default reads latest Storage version; `--config-version` pins an older version (rollback). Since 0.65.0 the platform injects clone credentials at deploy time, so no manual wiring is needed. Since vNEXT (CLI-15): for a PURE managed repo with no git block yet, deploy first resolves the managed repo's URL and backfills `parameters.dataApp.git`, then pins the resulting Storage `configVersion` -- omitting configVersion alone does NOT provision the app's workspace (`WORKSPACE_ID`/`KBC_WORKSPACE_MANIFEST_PATH`); grant provisioning is gated on that block's presence, not on `configVersion`. A git block already present (external repos, or a managed repo already backfilled) pins the LATEST Storage `configVersion` directly. The result then has `git_backfilled: true`, `git_branch` and a `warnings[]` entry. The branch written is `--git-branch` (since vNEXT); it is used only for this backfill and has no effect on any other deploy. Without `--git-branch`, deploy writes `main` for an app with no runs. For an app that has runs (it deployed before from the managed repo's own default branch, which no API returns), deploy fails with `VALIDATION_ERROR` before any write and asks for `--git-branch` with the branch the code is on. Push the managed repo's code to that branch. An explicit `--config-version` always wins and skips the backfill.
- `data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]` -- wake an auto-suspended app at the currently-pinned version. Distinct from deploy: does NOT bump configVersion.
- `data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]` -- stop a running app (URL and Storage config preserved).
- `data-app delete --project NAME --app-id ID [--yes]` -- destructive, cascades to Storage config; URL retired permanently.
Expand Down
23 changes: 22 additions & 1 deletion plugins/kbagent/skills/kbagent/references/data-app-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ kbagent --json data-app git-repo --project prod --app-id 12345678 # -> https_u
git push "https://<token>@<managed-host>/keboola/app-12345678.git" HEAD:main

# 4. Deploy. The platform injects the clone credentials at deploy time, so no
# credential is wired into the config.
# credential is wired into the config. Since vNEXT (CLI-15), this step also
# backfills parameters.dataApp.git from the managed repo's URL before
# pinning a version -- required for the app to get a workspace at all.
kbagent data-app deploy --project prod --app-id 12345678 --wait
```

Expand All @@ -353,6 +355,25 @@ contract), so `data-app deploy` on a pure managed repo deploys straight from
`app.managedGitRepoId`. If a deploy ever reverts to stopped, diagnose it with
`data-app runs` (`failure_reason` + `startup_logs`).

**Workspace access is a separate concern from cloning (since vNEXT; CLI-15).**
Cloning needs no credential wiring, as above -- but an app that also reads
Storage (`runtime.workspace.enabled: true`, the `--workspace` default) needs a
workspace grant, and that grant is gated on `parameters.dataApp.git` being
present in Storage config, independent of `managedGitRepoId`. Step 4 above now
backfills that block automatically before the first deploy, so this flow needs
no extra manual step. **Push to the backfilled branch:** the block sets
`branch` from `data-app deploy --git-branch` (since vNEXT), because the
managed repo's `git-repo` lookup returns no branch to read. Without the flag,
deploy writes `main` for an app with no runs. An app that has runs deployed
before from the repo's own default branch, so deploy fails with
`VALIDATION_ERROR` before any write; pass `--git-branch` with the branch the
code is on. The deploy result reports the branch it wrote (`git_branch`). `--git-branch` has
no effect on a deploy that does not backfill. Code pushed only to another
branch is never deployed. On an older kbagent version, the tell for the
unpatched gap is `data-app detail` showing `Git: {}` (empty) on a `running`
app with no `WORKSPACE_ID` -- see the gotchas reference for the manual
workaround.

### Manage app-runtime secrets

```bash
Expand Down
46 changes: 37 additions & 9 deletions plugins/kbagent/skills/kbagent/references/gotchas.md
Original file line number Diff line number Diff line change
Expand Up @@ -4144,7 +4144,12 @@ Other behaviors of this family:
`git-credentials` list never returns it. `--type
ssh_key` requires a `--public-key` / `--public-key-file` and returns no secret.

## `data-app` managed-repo deploy: omit configVersion (the platform injects clone creds) (since v0.65.0; guidance corrected v0.65.1 -- no credential wiring needed)
## `data-app` managed-repo deploy: the platform injects clone creds; deploy backfills the git block (since v0.65.0; guidance corrected v0.65.1 -- no credential wiring needed)

*(since vNEXT)* `data-app deploy` no longer omits configVersion for a pure
managed repo (CLI-15). It backfills `parameters.dataApp.git` and pins the
resulting version. Read the bullets below with that in mind; the last bullet
has the details.

`--use-managed-git-repo` provisions an **empty** Keboola-hosted git repo
(POST `useManagedGitRepo:true`) linked to the app via `app.managedGitRepoId`. It
Expand Down Expand Up @@ -4172,14 +4177,15 @@ The end-to-end flow that is **verified to deploy and serve** (tic-tac-toe on

The actual bug fixed in 0.65.0 was **kbagent always-pinning `configVersion`**:

- **configVersion at deploy depends on the source location.** `data-app deploy`
**omits** configVersion for a *pure* managed repo (no git block), which deploys
from `managedGitRepoId`; it pins the **latest** Storage configVersion only when
a git block is present (external repos). Pinning a managed app's no-git-block
Storage config made the runtime demand `dataApp.git.repository` and the deploy
reverted to `stopped` -- that was the misdiagnosed "could not read Username"
symptom, NOT a missing credential. Fixed in 0.65.0 by omitting configVersion for
pure managed repos. There is **no** cross-stack "platform doesn't inject
- **configVersion at deploy depends on the source location.** In 0.65.0 through
the release before vNEXT, `data-app deploy` **omitted** configVersion for a
*pure* managed repo (no git block) and pinned the **latest** Storage
configVersion only when a git block was present (external repos). Pinning a
managed app's no-git-block Storage config made the runtime demand
`dataApp.git.repository` and the deploy reverted to `stopped` -- that was the
misdiagnosed "could not read Username" symptom, NOT a missing credential.
Omitting configVersion fixed that crash. Since vNEXT, deploy backfills the git
block instead (last bullet). There is **no** cross-stack "platform doesn't inject
credentials" gap (issue #454 closed as not-a-bug).
- **Diagnose a stopped-reverting deploy with `data-app runs`**, not `data-app
logs`. `runs` returns each attempt's `failure_reason` + `startup_logs` --
Expand All @@ -4189,6 +4195,28 @@ The actual bug fixed in 0.65.0 was **kbagent always-pinning `configVersion`**:
command on the misdiagnosis that a credential had to be wired into the config.
It was removed in 0.65.1 -- it is unnecessary because no platform-injection gap
exists.
- **Correction (since vNEXT, CLI-15): omitting configVersion alone does NOT
provision a workspace.** The 0.65.0 fix above solves the "could not read Username" crash,
but a *pure* managed repo (no git block yet) still deployed with no
`WORKSPACE_ID`/`KBC_WORKSPACE_MANIFEST_PATH`, even with
`runtime.workspace.enabled: true` and `state: running` -- the same
no-platform-diagnostic failure mode as the `--workspace` gotcha above. Root
cause: workspace grant provisioning is gated on `parameters.dataApp.git` being
present in Storage config, independent of `managedGitRepoId`/
`hasManagedGitRepo`/`configVersion`. Fixed since vNEXT: `data-app deploy` now
resolves the managed repo's URL and backfills that git block (repository URL,
branch from `--git-branch`) *before* pinning a version, for any pure managed
repo -- no manual `config update --merge` step needed. No API returns the
managed repo's default branch. So without `--git-branch`, deploy writes
`main` only for an app with no runs (`data-app runs` empty). An app with
runs deployed before from the repo's own default branch, which may not be
`main`: deploy fails with `VALIDATION_ERROR` before any write and asks for
`--git-branch` with the branch the code is on.
`--git-branch` has no effect on a deploy that does not backfill. The deploy
result reports it with `git_backfilled: true`, `git_branch` and a `warnings[]`
entry. Push your code to that branch of the managed repo. `data-app detail`'s `Git: {}` (empty) on a `running` app is the tell
for this on an older kbagent version; the workaround there is to merge the
block manually, then redeploy.

## Core platform gotchas (version-independent)

Expand Down
2 changes: 1 addition & 1 deletion scripts/file_size_baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"commands/config.py": 2007,
"commands/lineage.py": 1271,
"commands/storage.py": 2221,
"services/data_app_service.py": 1633,
"services/data_app_service.py": 1600,
"services/storage_service.py": 1684,
"services/sync_service.py": 1655
}
Expand Down
Loading
Loading