aitools: plugin-first install command (picker, scope, --path/--skills-only)#5738
Merged
Conversation
4 tasks
Collaborator
Integration test reportCommit: 14c1921
21 interesting tests: 13 SKIP, 7 KNOWN, 1 RECOVERED
Top 4 slowest tests (at least 2 minutes):
|
This was referenced Jun 26, 2026
a022299 to
72c9a8f
Compare
dc07368 to
b793136
Compare
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 26, 2026
…atabricks#5734) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Merge bottom to top: - **databricks#5734 Detection & registry (plugin metadata + capability detection) ← this PR** - databricks#5736 State schema v2 (plugin + file provenance records) - databricks#5737 Plugin engine, checksums, `--path` dump (library) - databricks#5738 Plugin-first install command - databricks#5739 Update + prune of vanished skills - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state <!-- /aitools-stack --> ## Why `databricks aitools` is being redesigned from a raw-skills installer into a plugin-first installer. The first thing that redesign needs is better agent detection: today an agent is "detected" only if its config dir exists on disk, which misses Codex and Copilot (often used through an IDE, or installed-but-not-yet-run), and the registry has no notion of which agents have a plugin or what their CLI binary is. This PR lays that foundation. It is deliberately behavior-neutral: no command output changes, and `DetectInstalled` still uses the same config-dir signal it does today. The picker and install rewrites that consume this come in later PRs in the stack. ## Changes Before: the agent registry only knew each agent's config dir; detection was a single `os.Stat` on that dir. Now: the registry also describes each agent's plugin and CLI binary, and there's a capability detector that can tell the difference between "binary on PATH" and "config dir exists." - `Agent.Binary` — the CLI binary name on PATH (`claude`, `codex`, `copilot`, `cursor-agent`, `opencode`; empty for IDE-only Antigravity). Cursor's binary is `cursor-agent`, not `cursor` (the latter is an IDE shim that isn't on PATH). - `Agent.Plugin *PluginSpec` — describes the databricks plugin. `Plugin != nil` means the agent has a plugin (Claude, Codex, Copilot, Cursor); `nil` means raw skills are the only delivery (OpenCode, Antigravity). `ManualOnly` marks Cursor (plugin exists, but no headless install path). - OpenCode config dir is now per-OS: `%APPDATA%\opencode` on Windows, and honors `XDG_CONFIG_HOME` otherwise (defaulting to `~/.config/opencode`). The previous hardcoded path made OpenCode undetectable on Windows and ignored `XDG_CONFIG_HOME` on Linux. - New `detect.go`: `HasBinary` (via `exec.LookPath`), `DisplayState` (a 5-state enum for the picker, computed from the two cheap signals without running the agent), `Preselect`, and `ProbePlugin` (runs `<agent> plugin --help` with a 5s timeout through `libs/process`; refuses a cwd-relative binary via `exec.ErrDot` so a malicious `./claude` is never executed). ## Test plan - [x] Unit tests (`detect_test.go`): `HasBinary`, `DisplayState` across all five states, `Preselect` rules, `ProbePlugin` (supported / CLI reports unsupported / binary not on PATH / refuses dot-relative binary with zero executions), and `openCodeConfigDir` (XDG honored / `~/.config` default; Windows APPDATA branch on Windows hosts). - [x] `go test ./libs/aitools/... ./cmd/aitools/...` passes (no behavior change to existing commands). - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) all clean. This pull request and its description were written by Isaac.
72c9a8f to
1f5f724
Compare
b793136 to
4ad9646
Compare
… --skills-only) Wires the install command to the plugin engine. The default now installs the databricks plugin per agent instead of copying raw skill files. - Plugin-first delivery: plugin agents (Claude/Codex/Copilot) get the plugin; no-plugin agents (OpenCode/Antigravity) get skills; Cursor prints the /add-plugin tip and copies nothing. --skills-only forces raw skills for every agent; --path <dir> is a dumb dump (no agents, no state). --skills-only and --path together is an error. - Per-agent scope mapping (mapAgentScope): CLI global -> agent user scope; CLI project -> agent project scope only where supported (Claude), else skip with a reason. No silent fallback to user scope. - A blocked plugin install is reported and skipped (exit 0), never silently swapped for skills; it errors only when the agent was named via --agents. - Interactive picker now lists all known agents with detection-state labels (detected ones pre-checked), followed by a plan summary and a single confirm. - Non-interactive selection: plugin agents detected by binary-on-PATH (fixes the Codex/Copilot config-dir miss); --skills-only selection stays config-dir based. - The legacy `experimental skills install` alias pins --skills-only to keep its behavior; the 3 existing acceptance goldens switch to --skills-only and stay byte-identical in their behavior strings. Co-authored-by: Isaac
Co-authored-by: Isaac
The aitools acceptance tests share a process-global HOME (via t.Setenv), so running several in parallel let one test's install race another's on the shared ~/.databricks skills dir. sethome exports a per-test HOME inside each script's own shell, making them hermetic and deterministic. Output is unchanged. Co-authored-by: Isaac
…guard, picker errors) Address cursor review of the install command: - Fix a panic: RecordPluginInstalls created a plugin-only state with nil Skills/ RepoDirs/Files maps, so a later --skills-only install or update assigned into a nil map. Initialize all maps when creating plugin-only state, and add a defensive Skills nil-guard in InstallSkillsForAgents. Regression test covers plugin install followed by a raw-skills install. - Reject --skills unless --skills-only or --path is set; the plugin is installed in full, so cherry-picking individual skills was silently ignored before. - Propagate interactive picker errors (selectAgents now returns an error) instead of swallowing them into a "no agents found" exit 0. Co-authored-by: Isaac
4ad9646 to
14c1921
Compare
This was referenced Jun 26, 2026
Merged
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 27, 2026
…ks#5736) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Merge bottom to top: - databricks#5734 Detection & registry (plugin metadata + capability detection) - **databricks#5736 State schema v2 (plugin + file provenance records) ← this PR** - databricks#5737 Plugin engine, checksums, `--path` dump (library) - databricks#5738 Plugin-first install command - databricks#5739 Update + prune of vanished skills - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state <!-- /aitools-stack --> ## Why The plugin-first `aitools` redesign needs `.state.json` to record two new things: which plugins we installed through each agent's own CLI (so `update`/`uninstall`/`list` act on exactly where we installed), and provenance for the skill files we wrote (so a later `update` can prune a skill that vanished from the release only when the user hasn't modified it). This PR adds that schema, additively, ahead of the install/update/uninstall changes that consume it. Stacked on databricks#5734 (detection foundation). ## Changes Before: `InstallState` tracked only `skills`/`repo_dirs` (schema v1). Now: schema v2 adds two optional maps, and existing state migrates forward transparently. - `PluginRecord` (in `InstallState.Plugins`, keyed by agent name): marketplace, plugin id, agent-native scope, last-seen version, and `installed_marketplace` (whether this CLI registered the marketplace, so uninstall knows if it may de-register it). - `FileRecord` (in `InstallState.Files`, keyed by canonical-relative path like `databricks/SKILL.md`): per-file `sha256` + `origin` ref. - Both maps are `json:",omitempty"`, so a files-only install serializes byte-identically to today. - `LoadState` runs `migrateState`: forward-only and idempotent. v1 → v2 needs no data transformation (the maps are additive and optional), so it only stamps the version; writers lazily initialize the maps the same way `RepoDirs` is handled. - The fresh-install writer now stamps v2 so the on-disk and in-memory versions agree. ## Test plan - [x] Unit tests: v1→v2 migration is additive (existing skills untouched, new maps nil), migration is idempotent, and a state with populated `Plugins`/`Files` round-trips through save/load. Existing round-trip fixtures updated to v2. - [x] `go test ./libs/aitools/... ./cmd/aitools/...` passes. - [x] `go test ./acceptance -run TestAccept/experimental/aitools` passes (`.state.json` is in `Ignore`, so the version bump doesn't touch goldens). - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 27, 2026
…tabricks#5737) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Merge bottom to top: - databricks#5734 Detection & registry (plugin metadata + capability detection) - databricks#5736 State schema v2 (plugin + file provenance records) - **databricks#5737 Plugin engine, checksums, `--path` dump (library) ← this PR** - databricks#5738 Plugin-first install command - databricks#5739 Update + prune of vanished skills - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state <!-- /aitools-stack --> ## Why The plugin-first redesign installs the databricks plugin by driving each agent's own plugin CLI (`claude plugin install`, etc.), and on `update` it needs to be able to prune a skill that vanished from a release without clobbering files the user edited. This PR adds the library layer for both, with no command wiring yet, so the engine can be reviewed and unit-tested on its own. The install/update/uninstall commands call into it in later PRs. Stacked on databricks#5736 (state schema v2). ## Changes - `plugin.go` — the plugin engine. It drives each agent's CLI through `libs/process` (so tests mock it with `process.WithStub`): - `InstallPluginForAgent` registers the marketplace and installs the plugin, recording whether *we* added the marketplace. - `UpdatePluginForAgent` runs the per-agent update (Codex's two-step `marketplace upgrade` then `plugin add` is encoded). - `UninstallPluginForAgent` removes the plugin and de-registers the marketplace **only** when this CLI registered it and `--keep-marketplace` wasn't set — never a marketplace another plugin may share. - Argv is built per agent (Codex uses `plugin add`; Claude is the only `--scope` agent) and run by absolute path; a cwd-relative binary (`exec.ErrDot`) is refused, never executed. - A blocked operation returns a typed `*BlockedError` (`CLINotOnPath` / `InstallFailed` / `ManualOnly`), so the command layer can report it and decide skip-vs-fail — it never silently falls back to skills. The agent's own stderr is surfaced via `errors.AsType`, never string-matched. - `installer.go` — `installSkillToDir` now records a sha256 `FileRecord` per file it writes (origin = ref); `InstallSkillsForAgents` and `UpdateSkills` persist these to `state.Files` for the prune safeguard. The symlink-vs-copy rules are unchanged. - `dump.go` — `DumpSkillsToPath`, a dumb `--path` dump (no agents, no `.state.json`, no lifecycle) that reuses the existing manifest/resolve/fetch path. ## Test plan - [x] `plugin_test.go` via `process.WithStub` + injected `lookPath`: Claude success (marketplace add + `--scope user` install), Codex uses `plugin add` with no `--scope`, manual-only (Cursor) → `ManualOnly`, CLI-not-on-path → `CLINotOnPath` with zero executions, install failure → `InstallFailed` surfacing stderr verbatim, marketplace-already-present leaves `InstalledMarketplace=false`, Codex two-step update, marketplace de-register only when we installed it and `--keep-marketplace` honored. - [x] `dump_test.go`: writes files, writes no state, honors `--skills` cherry-pick. - [x] `installer_test.go`: install captures file checksums into `state.Files`. - [x] `go test ./libs/aitools/... ./cmd/aitools/...` and `go test ./acceptance -run TestAccept/experimental/aitools` pass. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code — engine funcs are reachable via tests until the command layer lands) clean. This pull request and its description were written by Isaac.
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 27, 2026
) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Merge bottom to top: - databricks#5734 Detection & registry (plugin metadata + capability detection) - databricks#5736 State schema v2 (plugin + file provenance records) - databricks#5737 Plugin engine, checksums, `--path` dump (library) - databricks#5738 Plugin-first install command - **databricks#5739 Update + prune of vanished skills ← this PR** - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state <!-- /aitools-stack --> ## Why With install now plugin-first, `update` has to know about both worlds: update the plugin for plugin agents, and reconcile raw skills for the rest. This PR also makes the one intended behavior change from the redesign: a skill that disappears from a release is now removed, not warned-about-and-kept, so users don't accumulate dead skills forever. Stacked on databricks#5738 (install command). ## Changes Before: `update` only reconciled skill files, and a skill that vanished from the manifest was kept with a warning. Now: - **Plugin agents:** every agent recorded in `state.Plugins` is updated through its own plugin CLI (`UpdateInstalledPlugins`). The plugin's own update handles content the release dropped, so plugin agents have no per-skill prune. - **Prune vanished skills:** a skill that disappeared from the manifest is pruned, but **only** when the CLI installed it and the on-disk files still match the recorded sha256. A user-modified skill, or one with no recorded provenance (legacy v1 state), is kept with a warning. `--no-prune` keeps vanished skills; `--check` previews the removals without deleting. - **No duplicate skills:** the file-skills reconcile excludes agents managed as plugins in this scope (so a plugin agent never gets duplicate raw skill files), and is skipped entirely for a pure-plugin install. - `FormatUpdateResult` gains "removed" lines and a "Removed N skills." summary; the existing updated/added lines and summary are byte-identical. ## Test plan - [x] Unit tests: prune of a vanished unmodified skill (state + canonical dir cleaned), `--no-prune` keeps it, a user-modified vanished skill is kept, `--check` shows the prune without deleting, `UpdateInstalledPlugins` runs the plugin update and bumps the recorded version, and the `--no-prune` flag wiring. - [x] Acceptance: new `update-prune` test installs two skills then updates against a release missing one — alpha updates, beta is pruned ("Removed 1 skill."). - [x] `go test ./libs/aitools/... ./cmd/aitools/... ./acceptance -run TestAccept/experimental/aitools` passes. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Jun 29, 2026
<!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Open PRs, merge bottom to top: - #5740 Uninstall teardown + legacy skills cleanup - **#5741 list + version plugin state ← this PR** - #5745 Bug bash (wording, latest-by-default skills, project-scope plan, version reporting) - #5746 Bug bash round 2 (uninstall confirm, picker, Cursor, official marketplace, version scope) Merged: #5734, #5736, #5737, #5738, #5739. <!-- /aitools-stack --> ## Why `list` and `version` only knew about raw skills. Now that the CLI installs plugins, they should report the real per-agent plugin state so users (and the plugin's SessionStart nudge) can see what's installed and whether it's current. Stacked on #5740 (uninstall). ## Changes - **`list --output json`** gains an additive `agents[]` array: each plugin agent with a recorded install (its `version` and an `up_to_date` / `update_available` status, `managed: true`), plus Cursor as `manual_add_plugin` (`managed: false`) when it's present. The existing `release` / `skills` / `summary` keys and shapes are byte-identical (additive `omitempty` field). The text view adds an `AGENT / STATUS` block only when there are agent entries, leaving the skills table and summary line unchanged. - **`version`** prints a `Plugin (<Agent>): vX` line per recorded plugin, and only prints the skills line when skills are actually installed, so a plugin-only install no longer reports "0 skills". Existing skills output is unchanged. ## Test plan - [x] Unit tests: `list` JSON includes `agents[]` with the right statuses/managed flags while keeping `release`/`skills`/`summary` intact; `buildAgentEntries` maps recorded plugins to up_to_date/update_available and surfaces Cursor as manual; `version` prints the plugin line for a plugin-only install. - [x] Existing `list`/`version` tests pass unchanged (JSON round-trip, both-scopes skills output). - [x] `go test ./libs/aitools/... ./cmd/aitools/...` passes. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 29, 2026
…all (databricks#5740) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Open PRs, merge bottom to top: - **databricks#5740 Uninstall teardown + legacy skills cleanup ← this PR** - databricks#5741 list + version plugin state - databricks#5745 Bug bash (wording, latest-by-default skills, project-scope plan, version reporting) - databricks#5746 Bug bash round 2 (uninstall confirm, picker, Cursor, official marketplace, version scope) Merged: databricks#5734, databricks#5736, databricks#5737, databricks#5738, databricks#5739. <!-- /aitools-stack --> ## Why To finish the lifecycle: `uninstall` has to remove the plugin we installed (not just skills), and `install` has to clean up any raw skills a user had from the old skills-everywhere model, so a plugin agent doesn't end up with the plugin *and* leftover loose skill files showing the same skills twice. Stacked on databricks#5739 (update). ## Changes - **Uninstall tears down plugins.** On a full uninstall (no `--skills` filter), each agent recorded in `state.Plugins` has its plugin removed through the agent's own CLI, and the marketplace is de-registered, but only when this CLI registered it and `--keep-marketplace` wasn't passed, so we never remove a marketplace another plugin may share. Skills teardown is unchanged for file agents; the state file is removed only when no skills and no plugins remain in the scope. - **Install cleans up legacy raw skills.** After installing the plugin for an agent, `RemoveLegacyRawSkills` removes skill dirs the CLI previously dropped there: a symlink pointing into our canonical dir, or a copy whose files all match the recorded checksums. User-modified dirs, third-party dirs, and copies with no recorded provenance are left untouched. - New `--keep-marketplace` flag on `uninstall`. ## Test plan - [x] Unit tests: uninstall tears down the plugin and de-registers the marketplace, removing the state file when nothing remains; `--keep-marketplace` skips the de-register; `RemoveLegacyRawSkills` removes our symlink and a checksum-matched copy while keeping a user-modified copy and a third-party dir. - [x] Existing skills-uninstall tests still pass byte-for-byte ("Uninstalled N skills.", selective removal, orphan cleanup, "no skills installed"). - [x] `go test ./libs/aitools/... ./cmd/aitools/...` passes. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 29, 2026
…lan, version reporting) (databricks#5745) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Open PRs, merge bottom to top: - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state - **databricks#5745 Bug bash (wording, latest-by-default skills, project-scope plan, version reporting) ← this PR** - databricks#5746 Bug bash round 2 (uninstall confirm, picker, Cursor, official marketplace, version scope) Merged: databricks#5734, databricks#5736, databricks#5737, databricks#5738, databricks#5739. <!-- /aitools-stack --> ## Why Testing the built CLI surfaced several issues in `databricks aitools`: 1. Inconsistent, plugin-blind copy ("AI Tools" / "AI skills") even though most agents now get a plugin. 2. Skills pinned to a cli-compat version (e.g. `0.2.5`) while plugin agents installed latest (e.g. `0.2.7`). Two different versions for the same content, and list/version misreported the plugin version. 3. Project-scope install offered files-only agents (OpenCode, Antigravity) that can't do project scope, then failed after the fact without installing anything. ## Changes **Wording.** Everything under `databricks aitools` now reads "skills and plugins" (help, version output, install log); empty-state errors say "no skills or plugins installed". The legacy skills alias and `experimental aitools` are untouched. **Skills track latest by default.** Plugin agents' CLIs have no version flag, so they only ever install the marketplace's latest. Skills now match that: - `GetSkillsRef` precedence: `DATABRICKS_SKILLS_REF` (exact ref, for evals), then cli-compat.json, then default latest (`main`). - cli-compat.json is the remote safety valve: its `skills` field is now `"latest"` (track latest), but it can be edited to a concrete version to pin older CLIs after a breaking change, with no CLI release needed. AppKit version resolution is unchanged (cli-compat still pins it via its own field). - Plugins (and unpinned skills) report `latest` instead of a stale concrete version, so list/version are honest. - `update` reconciles against latest when unpinned instead of falsely reporting "already up to date". **Project-scope plan is honest.** `buildPlan` skips files-only agents that don't support project scope (the way plugin agents already were), and the picker is scope-aware, so incompatible agents are labeled and not pre-checked. No more "offer then fail with nothing installed". ## Test plan - [x] Unit: `GetSkillsRef` (default latest / env pin / cli-compat pin), `DisplaySkillsVersion`, `buildPlan` project-scope skip for files-only agents; clicompat allows the `latest` sentinel. - [x] Acceptance `experimental/aitools` unchanged (tests pin the ref via env). - [x] `go test ./libs/aitools/... ./cmd/aitools/... ./libs/clicompat/...` passes. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
bradleyjamrozik-origindigital
pushed a commit
to bradleyjamrozik-origindigital/databricks-cli
that referenced
this pull request
Jun 29, 2026
… marketplace) (databricks#5746) <!-- aitools-stack --> ### Stack Part of the `aitools` plugin-first redesign. Open PRs, merge bottom to top: - databricks#5740 Uninstall teardown + legacy skills cleanup - databricks#5741 list + version plugin state - databricks#5745 Bug bash (wording, latest-by-default skills, project-scope plan, version reporting) - **databricks#5746 Bug bash round 2 (uninstall confirm, picker, Cursor, official marketplace, version scope) ← this PR** Merged: databricks#5734, databricks#5736, databricks#5737, databricks#5738, databricks#5739. <!-- /aitools-stack --> ## Why A second round of testing the plugin-first `databricks aitools` CLI. Findings are tracked in `documents/proposals/aitools-bugbash-findings.md`. ## Changes - **uninstall confirms in interactive mode.** It removed skills and de-registered plugins immediately; now (on a TTY) it summarizes what will be removed and asks "Proceed?". Non-interactive runs are unaffected. - **version labels the scope.** Skills and plugins are now always labeled global/project (e.g. `Plugin (Claude Code, global): latest`). - **Claude installs from the official marketplace.** The databricks plugin is in Claude's built-in `claude-plugins-official` marketplace, so Claude installs `databricks@claude-plugins-official`. A built-in marketplace (empty PluginSpec.Source) is never added or de-registered. Codex/Copilot keep our own marketplace. - **Picker only offers actionable agents.** Every detected agent still shows in the detection list with its state/reason, but only agents that will do something (plugin or skills) are selectable; agents skipped in the scope are no longer checkboxes. - **Cursor is a plain skills agent.** Cursor was a confusing "manual, run /add-plugin" option that did nothing. Since the Cursor plugin can't be installed or interacted with headlessly, all references to it are removed: Cursor now installs raw skills like OpenCode/Antigravity, labeled simply "skills". This removed the whole manual-only concept (PluginSpec.ManualOnly/ManualInstructions, StateManualOnly, ReasonManualOnly, the manual_add_plugin list status, and the deliveryManualCursor path). - **Help links the source repo.** `databricks aitools` help points at https://github.com/databricks/databricks-agent-skills so users know where skills and plugins come from. ## Test plan - [x] Unit: uninstall confirm; version scope labels; built-in marketplace install (no `marketplace add`) and uninstall (no de-register); picker offers only actionable agents; Cursor plan = skills; no-plugin install guard. - [x] `go test ./libs/aitools/... ./cmd/aitools/...` and acceptance `experimental/aitools` pass. - [x] `./task fmt-q`, `./task lint-q` (0 issues), `./task checks` (no dead code) clean. This pull request and its description were written by Isaac.
deco-sdk-tagging Bot
added a commit
that referenced
this pull request
Jul 2, 2026
## Release v1.6.0 ### CLI * `ssh connect` now accepts a `--base-environment` flag to run a serverless session on a custom base environment. It takes an `env.yaml` path, a `workspace-base-environments/...` resource ID, or a base environment display name, and is rejected together with `--environment-version` or `--cluster` ([#5706](#5706)). * `databricks aitools install` is now plugin-first: it installs the Databricks plugin through each agent's own CLI (Claude Code, Codex, GitHub Copilot) instead of copying raw skill files. Agents without a plugin (OpenCode, Antigravity) still get skill files, and Cursor prints the `/add-plugin databricks` step. Use `--skills-only` to force raw skill files for every agent, or `--path <dir>` to write skills to a directory ([#5738](#5738)). * `databricks labs list` now only shows projects that can be installed ([#5560](#5560)). ### Bundles * direct: Fixed persistent drift on `model_serving_endpoints` caused by the `traffic_config` field ([#5708](#5708)). * direct: Fix spurious update when `apply_policy_default_values: true` is set on job task, for-each-task, or job cluster new_cluster ([#5731](#5731)). Also fix spurious updates for for-each-task clusters due to missing backend defaults for `data_security_mode`, `node_type_id`, `driver_node_type_id`, `driver_instance_pool_id`, `enable_elastic_disk`, and `enable_local_disk_encryption`. * direct: Cluster resize now falls back to regular update if resize fails due to `INVALID_STATE` ([#5716](#5716)). * `bundle generate dashboard` now honors the `--key` flag when naming the generated resource, and rejects combining `--existing-path`, `--existing-id`, and `--resource` instead of silently ignoring all but one ([#5492](#5492)). * Fixed `bundle deployment migrate` failing on `model_serving_endpoints`/`database_instances` with permissions (regression since v1.5.0) ([#5775](#5775)). * After a terraform deploy, the CLI now dry-runs a migration to the direct engine (writing nothing locally or remotely) and reports the outcome via telemetry, warning if the migration could not be completed ([#5797](#5797)). ### Dependency updates * Bump `github.com/databricks/databricks-sdk-go` from v0.147.0 to v0.152.0 ([#5773](#5773)). * Bump Terraform provider from v1.118.0 to v1.120.0 ([#5792](#5792)).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack
Part of the
aitoolsplugin-first redesign. Merge bottom to top:--pathdump (library)Why
This is the user-visible flip of the
aitoolsredesign:databricks aitools installnow installs the Databricks plugin through each coding agent's own CLI instead of copying raw skill files into every agent. Raw skills alongside a plugin produce duplicate, hard-to-update content; the plugin is how those agents expect third-party content to arrive.Stacked on #5737 (plugin engine).
Changes
Before: install copied skill files into each detected agent's skills dir.
Now: install is plugin-first, with explicit escape hatches.
/add-plugin databricksstep and copies nothing.--skills-onlyforces raw skill files for every agent;--path <dir>is a dumb dump (no agents, no state).--skills-only+--pathis rejected.mapAgentScope): CLIglobal→ agent user scope; CLIproject→ agent project scope only where supported (Claude), otherwise the agent is skipped with a reason. No silent fallback to user scope.--agents.--skills-onlyselection stays config-dir based and PATH-independent.experimental skills installalias pins--skills-onlyto preserve its behavior.Test plan
buildPlandeliveries (plugin/skills/manual/skip) and--skills-onlyforcing skills;mapAgentScopematrix;executePlanskip-with-warning vs error-on-explicit; plugin-first default (with a controlled PATH),--agentsfor an undetected agent, no-agents no-op,--skills-only/--pathconflict, scope flags, interactive picker + confirm.experimental aitools installgoldens switch to--skills-onlyand keep their behavior strings byte-identical (only the>>>echo gains the flag); a newpath-dumptest covers--path.go test ./libs/aitools/... ./cmd/aitools/... ./acceptance -run TestAccept/experimental/aitoolspasses../task fmt-q,./task lint-q(0 issues),./task checks(no dead code) clean.This pull request and its description were written by Isaac.