Skip to content

[skills] Take cross-schema FQNs for named skill downloads - #583

Merged
xsh310 merged 2 commits into
mainfrom
skills-picker-skills-fqn
Sep 16, 2026
Merged

xsh310 merged 2 commits into
mainfrom
skills-picker-skills-fqn

Conversation

@xsh310

@xsh310 xsh310 commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

What

Rework the "download these named skills" path so a selection is a set of fully-qualified <catalog>.<schema>.<name> names that may span any number of schemas, downloaded through download_selected_skills (the same flow the interactive picker uses). This applies to both:

  • ug skill add --skills <fqn>[,<fqn>...]
  • ug configure skills --skill <fqn>[,<fqn>...]

Why

The old --skills/--skill was coupled to a single --location: bare leaf names required exactly one location, fully-qualified names had to all share one <catalog>.<schema>, and entries had to match --location. That could not express "download these specific skills from several schemas". Routing named downloads through the existing selected-download flow removes the limit.

Behavior

  • Each --skills/--skill entry must be a 3-part FQN; a bare or malformed name is now an error listing the offenders.
  • --skills/--skill no longer takes --location; passing both is an error ("takes fully-qualified names; drop --location").
  • Named downloads still register the schema-less skills MCP connection. download_selected_skills alone does not register, so a shared configure_selected_skills_download_command does the download then the register, mirroring the picker.
  • An FQN that GetSkill cannot resolve (unknown or unfinalized) warns and is skipped per skill, not a hard error.
  • --skills "" still downloads nothing.

Unchanged: whole-schema downloads via --location, --mcp, --path, and the no-arg interactive picker.

Cleanup

Both CLI paths were the only callers of the subset filter on download_skills_from_schema_locations / configure_skills_download_command, so that now-dead skills parameter is removed; the schema-location path is whole-schema only.

Stack

Part of gh stack #576, on top of #581 (skills-picker-download-preview).

Testing

uv run ruff check ., ruff format --check, ty check src, and uv run pytest all pass (the 2 pre-existing test_e2e_user_agent / test_claude_smart_routing_v2 failures also fail on the base). Rewrote TestSkillsAddCommand and the configure skills --skill cases, added TestConfigureSelectedSkillsDownloadCommand, and updated the README.

This pull request and its description were written by Isaac.

@xsh310
xsh310 added this pull request to stack #576 September 12, 2026 16:06
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from d733722 to 0b93d52 Compare September 12, 2026 16:18
Comment thread src/ucode/cli.py Outdated
Comment thread src/ucode/skills_download.py Outdated
@xsh310
xsh310 marked this pull request as ready for review September 12, 2026 17:06
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from fe09f96 to fceb369 Compare September 14, 2026 03:08
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from fceb369 to d2c1240 Compare September 14, 2026 20:09
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from d2c1240 to ddf8d81 Compare September 14, 2026 22:32
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from ddf8d81 to befe738 Compare September 14, 2026 23:20
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from befe738 to 222e30f Compare September 15, 2026 00:53
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch 2 times, most recently from 81cc04f to effb8b7 Compare September 15, 2026 01:41
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from effb8b7 to 5bfa17f Compare September 15, 2026 03:30
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 5bfa17f to 76d9ac0 Compare September 15, 2026 03:40
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 76d9ac0 to 180e604 Compare September 15, 2026 04:42
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 180e604 to 0d239e5 Compare September 15, 2026 14:43
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 7f49f60 to 25aef26 Compare September 15, 2026 23:20
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch 2 times, most recently from ff2d0c9 to 55d61b6 Compare September 15, 2026 23:50
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 55d61b6 to a5bab6d Compare September 16, 2026 00:51
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from a5bab6d to 399fd8b Compare September 16, 2026 01:00
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 399fd8b to 507b886 Compare September 16, 2026 03:59
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 507b886 to 55d61b6 Compare September 16, 2026 05:19
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 55d61b6 to e76d6f1 Compare September 16, 2026 19:03
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from e76d6f1 to 3580fb3 Compare September 16, 2026 19:11
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from 3580fb3 to fe8174a Compare September 16, 2026 20:08
@xsh310

xsh310 commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator Author

/trigger

Base automatically changed from skills-picker-download-preview to main September 16, 2026 20:21
xsh310 and others added 2 commits September 16, 2026 13:21
`ug skill add --skills` and `ug configure skills --skill` now take exactly these fully-qualified `<catalog>.<schema>.<name>` names, which may span any number of schemas, and route them through download_selected_skills (already used by the interactive picker). Both drop the old bare name plus single `--location` coupling: a bare name is now an error, and passing `--location` alongside `--skills`/`--skill` is rejected.

Whole schemas still download via `--location`; the now unused subset filter on download_skills_from_schema_locations and configure_skills_download_command is removed. A new configure_selected_skills_download_command shares the download and register tail with the picker.

Co-authored-by: Isaac <no-reply@databricks.com>
…mmand

Move the `--location` rejection into each command's guard block, next to the other mutual-exclusion checks, and inline the FQN validation and dispatch, dropping _download_selected_skills_route. _is_qualified_skill_name stays shared.

Rename configure_skills_download_command to configure_location_skills_download_command so its name makes clear it downloads every skill in the selected `<catalog>.<schema>` locations, distinct from configure_selected_skills_download_command.

Co-authored-by: Isaac <no-reply@databricks.com>
@xsh310
xsh310 force-pushed the skills-picker-skills-fqn branch from fe8174a to 098c60e Compare September 16, 2026 20:21
@xsh310
xsh310 merged commit d06e67e into main Sep 16, 2026
18 of 20 checks passed
@xsh310
xsh310 deleted the skills-picker-skills-fqn branch September 16, 2026 20:29
xsh310 added a commit that referenced this pull request Sep 16, 2026
…584)

## What

Track which on-disk skill directories ucode downloaded from Unity
Catalog, in a
single manifest at `~/.ucode/skills.json`, so ucode can tell a
downloaded skill
from a user-authored one and (in a later PR) remove downloads by their
UC schema.

Skill attribution design doc:

https://doc-center-6051921418418893.staging.aws.databricksapps.com/d/hbzhsbid

## Why

The download path kept no record of what it wrote or where it came from,
so there
is no safe way to remove a downloaded skill without risking a same-named
skill the
user authored themselves. This is the foundation (PR 1 of the
attribution work): it
populates the manifest but adds no user-facing command yet.

## Changes

- New `skills_state.py` owns the manifest and its
read/write/query/reconcile logic.
  Records are keyed by `(metastore_id, fqn, base)`; query helpers are
`list_downloaded`, `attribution_for_dir`, `records_for_schema`, and
`forget`.
- `record_downloads` reconciles superseded records on write: it drops
the stale
record for a directory just overwritten (keeping the freshly written
files) and
deletes the orphaned old directory when the same skill's bundle name
changed.
- `SkillRef` now also carries `metastore_id`, `skill_id`, and
`uc_update_time`,
read for free from the `ListSkills`/`GetSkill` response ucode already
fetches.
- The three download flows (whole-schema, named FQNs, picker) and the
managed-launch
  download record each skill after it reaches disk.

Kept separate from `state.json` so a state-version change and `ug
revert` leave it
untouched.

## Testing

`uv run ruff check`, `ruff format --check`, `ty check src`, and `uv run
pytest` all
pass (the pre-existing `test_e2e_user_agent` /
`test_claude_smart_routing_v2`
failures also fail on the base). New `tests/test_skills_state.py` covers
the manifest
round-trip, corrupt/version handling, the queries, and all three
reconciliation
cases; `tests/test_skills_download.py` gains coverage that a download
records
attribution and that `SkillRef` captures the UC metadata.

## Stack

Part of gh stack #576, on top of #583 (`skills-picker-skills-fqn`).

This pull request and its description were written by Isaac.

Co-authored-by: Isaac <no-reply@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants