Commit 3a4087b
authored
skills: add download mode to
* skills: add UC download client (list schemas, list bundle files, fetch bytes)
Adds the read-only client layer for `ucode configure skills` download mode:
- `list_schema_skills` — finalized skill leaf names in a schema via the UC
skills API (`/api/2.1/unity-catalog/skills`, paginated). Uses `bundle_name`
as the leaf and `finalize_time` as the readiness signal.
- `list_skill_files` — a skill bundle's files (relative paths), by recursively
walking its UC Volume directory via the Files API.
- `fetch_skill_file` — one bundle file's raw bytes via the Files API.
- `_http_get_bytes` — raw-bytes GET helper (skill bundles may be binary).
Library only; no CLI wiring yet. All functions return (value, reason) and reuse
the existing `_http_get_json` error convention.
Verified end-to-end against a staging workspace with a user OAuth token: all
three endpoints (skills list, Volume directory listing, raw file bytes) resolve
directly with the client token — no storage-credential vending required.
Co-authored-by: Isaac
* skills: add on-disk writer for downloaded skills
New `skills_download.py` owns the filesystem side of `ucode configure skills`
download mode:
- `skill_dir_roots` — the `.claude/skills` + `.agents/skills` roots for a
download, at user scope (`~/`) or a project `--path`.
- `write_skill` — writes a skill's `{relpath: bytes}` bundle into every root,
one flat `<root>/<leaf>/` dir per skill. Re-downloading the same skill in a
run rewrites silently; a different schema colliding on the same leaf prompts
keep/overwrite (or overwrites under `--yes`). Rejects invalid leaf names and
`..`/absolute paths in the bundle.
Transport-agnostic (no HTTP) so it's unit-testable with a literal dict; the
bytes come from the download client in `databricks.py`. No CLI wiring yet.
Co-authored-by: Isaac
* skills: simplify writer — required absolute --path, drop --yes
Per review feedback, simplify the download writer:
- `skill_dir_roots` now requires an existing absolute `--path` (raises
ValueError otherwise); no `~/` user-scope default.
- Drop `--yes`/`assume_yes`; a cross-schema leaf collision always prompts.
- Rename `written` -> `written_leaves`, extract `_write_bundle`, and flatten
the collision decision into one readable conditional.
Co-authored-by: Isaac
* skills: always prompt on existing skill dir; drop per-run ledger
`write_skill` no longer tracks which leaves it wrote this run. Any pre-existing
skill directory now prompts before overwrite, uniformly — including
re-downloading the same skill.
The per-run `written_leaves` ledger only made same-run duplicate leaves rewrite
silently, but it added state and a subtle branch to cover a rare case, and it's
fragile: ucode doesn't persist which schema wrote a given dir, and users can
edit the filesystem, so "it's the same skill" was never reliable. Always asking
is simpler and consistent.
Co-authored-by: Isaac
* skills: address review — tighter docstrings, clearer names
- Condense the module and write_skill docstrings.
- Rename SKILL_DIR_NAMES -> SKILL_BASE_DIR_NAMES.
- Rename _LEAF_PATTERN -> SKILL_NAME_PATTERN, drop its redundant comment.
- Rename write_skill's schema_ref param -> location (it's the
<catalog>.<schema> string).
Co-authored-by: Isaac
* skills: add fetch_skill_bundle to compose a skill's full download
`fetch_skill_bundle(workspace, token, catalog, schema, leaf)` lists a skill's
files then fetches each into a `{relpath: bytes}` map, all-or-nothing. This is
the one-skill assembler the download command will call per leaf; keeping it in
databricks.py (next to its list_skill_files/fetch_skill_file parts) keeps the
writer transport-agnostic and the eventual command loop thin.
Co-authored-by: Isaac
* skills: wire download mode into configure skills
Flip --mcp to optional and add a download-only --path. Without --mcp,
configure skills downloads every skill in each --location schema into
<path>/.claude/skills + <path>/.agents/skills and registers a
schema-less skills MCP connection, leaving any prior --mcp scope intact.
Adds configure_skills_download_command and the _skill_mcp_locations
read accessor in mcp.py; download persists no disk state.
Co-authored-by: Isaac
* skills: address review — consolidate download in skills_download.py
- Move the UC skill-download client (list/fetch) and the download
orchestration out of databricks.py and mcp.py into skills_download.py,
so mcp.py keeps only MCP-connection glue and databricks.py only the
shared HTTP transport helpers.
- Make --path optional: omitted, downloads write under the home dir.
- Parallelize per-skill bundle fetches; keep writes sequential (prompts).
Add progress messages so users see skills being downloaded.
- Drop write_skill's unused return value; it prints its own outcome.
Co-authored-by: Isaac
* skills: move download command out of mcp.py into skills_download.py
configure_skills_download_command now lives in skills_download.py alongside
the client, writer, and orchestration. mcp.py keeps only the MCP-connection
glue it exposes as setup_mcp_clients and register_schemaless_skills_connection,
and no longer imports skills_download — the dependency flows one way
(cli -> skills_download -> mcp -> databricks).
Co-authored-by: Isaac
* skills: show a progress bar and k/n summary during download
Replace the per-skill [i/total] prefixes with a Rich progress bar that
advances as concurrent fetches complete (transient, tty-only so CI logs
stay clean), followed by a 'Downloaded k/n skill(s) from <location>'
summary. Adds a reusable progress_bar helper to ui.py.
Co-authored-by: Isaac
* skills: drop redundant cast and make _fetch_bundles self-contained
- Remove the no-op cast(dict, payload) (the isinstance guard already
narrows the type) and its now-unused typing.cast import.
- Guard _fetch_bundles against empty leaves with an early return, so it
no longer relies on the caller to avoid ThreadPoolExecutor(max_workers=0).
Co-authored-by: Isaacucode configure skills (client, writer, CLI wiring) (#237)1 parent 0fed5fd commit 3a4087b
10 files changed
Lines changed: 900 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
105 | 127 | | |
106 | 128 | | |
107 | 129 | | |
| |||
118 | 140 | | |
119 | 141 | | |
120 | 142 | | |
| 143 | + | |
| 144 | + | |
121 | 145 | | |
122 | 146 | | |
123 | 147 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
62 | 63 | | |
63 | 64 | | |
64 | 65 | | |
| |||
1403 | 1404 | | |
1404 | 1405 | | |
1405 | 1406 | | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
1406 | 1411 | | |
1407 | | - | |
| 1412 | + | |
| 1413 | + | |
1408 | 1414 | | |
1409 | | - | |
| 1415 | + | |
1410 | 1416 | | |
1411 | 1417 | | |
1412 | 1418 | | |
1413 | | - | |
1414 | | - | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
1415 | 1423 | | |
1416 | 1424 | | |
1417 | | - | |
1418 | | - | |
1419 | | - | |
1420 | | - | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
1421 | 1432 | | |
1422 | 1433 | | |
1423 | 1434 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
290 | 290 | | |
291 | 291 | | |
292 | 292 | | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
293 | 322 | | |
294 | 323 | | |
295 | 324 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1190 | 1190 | | |
1191 | 1191 | | |
1192 | 1192 | | |
1193 | | - | |
| 1193 | + | |
1194 | 1194 | | |
1195 | 1195 | | |
1196 | 1196 | | |
| |||
1253 | 1253 | | |
1254 | 1254 | | |
1255 | 1255 | | |
1256 | | - | |
| 1256 | + | |
1257 | 1257 | | |
1258 | 1258 | | |
1259 | 1259 | | |
| |||
1424 | 1424 | | |
1425 | 1425 | | |
1426 | 1426 | | |
1427 | | - | |
| 1427 | + | |
1428 | 1428 | | |
1429 | 1429 | | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
0 commit comments