Skip to content

Commit 39ee67f

Browse files
justinmerrellclaude
andcommitted
feat!: remove OCI layer, deprecated aliases, and stub methods
Remove the OCI module and constants, drop deprecated `api_key`/`api_url` parameter aliases from `configure()`, remove unimplemented stub methods (`install_vscode_skills`, `write_lockfile`, `verify`), and add dynamic version resolution from package metadata. BREAKING CHANGE: `OCI_MEDIA_TYPE_ASSET`, `OCI_MEDIA_TYPE_CONFIG`, `api_key`, `api_url`, `install_vscode_skills()`, `write_lockfile()`, and `verify()` have been removed from the public API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 88c0805 commit 39ee67f

16 files changed

Lines changed: 3069 additions & 3149 deletions

File tree

.github/release-please/config.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@
99
"include-component-in-tag": false,
1010
"bump-minor-pre-major": true,
1111
"bump-patch-for-minor-pre-major": true,
12-
"extra-files": [
13-
{
14-
"type": "toml",
15-
"path": "pyproject.toml",
16-
"jsonpath": "$.project.version"
17-
}
18-
],
1912
"changelog-sections": [
2013
{ "type": "feat", "section": "Features" },
2114
{ "type": "fix", "section": "Bug Fixes" },
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
{
2-
".": "0.1.1"
3-
}
1+
{
2+
".": "0.1.1"
3+
}

.github/workflows/release.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ on:
77
permissions:
88
contents: write
99
pull-requests: write
10-
id-token: write
11-
attestations: write
1210

1311
jobs:
1412
release-please:
@@ -27,6 +25,10 @@ jobs:
2725
needs: release-please
2826
if: ${{ needs.release-please.outputs.release_created }}
2927
runs-on: ubuntu-latest
28+
permissions:
29+
contents: read
30+
id-token: write
31+
attestations: write
3032
steps:
3133
- uses: actions/checkout@v4
3234

@@ -53,6 +55,8 @@ jobs:
5355
needs: build
5456
runs-on: ubuntu-latest
5557
environment: testpypi
58+
permissions:
59+
id-token: write
5660
steps:
5761
- uses: actions/download-artifact@v4
5862
with:
@@ -62,19 +66,18 @@ jobs:
6266
- uses: pypa/gh-action-pypi-publish@release/v1
6367
with:
6468
repository-url: https://test.pypi.org/legacy/
65-
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
6669

6770
publish-pypi:
6871
needs: [build, release-please]
6972
if: ${{ !contains(needs.release-please.outputs.tag_name, '-') }}
7073
runs-on: ubuntu-latest
7174
environment: release
75+
permissions:
76+
id-token: write
7277
steps:
7378
- uses: actions/download-artifact@v4
7479
with:
7580
name: dist
7681
path: dist/
7782

7883
- uses: pypa/gh-action-pypi-publish@release/v1
79-
with:
80-
password: ${{ secrets.PYPI_API_TOKEN }}

CHANGELOG.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# Changelog
2-
3-
## [0.1.1](https://github.com/musher-dev/python-sdk/compare/0.1.0...0.1.1) (2026-03-24)
4-
5-
6-
### Features
7-
8-
* stub out musher Python SDK package ([a1d952b](https://github.com/musher-dev/python-sdk/commit/a1d952b56a2f1acf20f968ed6bcf841241789d0b))
9-
10-
11-
### Bug Fixes
12-
13-
* remove CRLF line endings from post-create.sh ([4f85ffa](https://github.com/musher-dev/python-sdk/commit/4f85ffabddfeb9b54022b99c7c67dfd8b19df041))
1+
# Changelog
2+
3+
## [0.1.1](https://github.com/musher-dev/python-sdk/compare/0.1.0...0.1.1) (2026-03-24)
4+
5+
6+
### Features
7+
8+
* stub out musher Python SDK package ([a1d952b](https://github.com/musher-dev/python-sdk/commit/a1d952b56a2f1acf20f968ed6bcf841241789d0b))
9+
10+
11+
### Bug Fixes
12+
13+
* remove CRLF line endings from post-create.sh ([4f85ffa](https://github.com/musher-dev/python-sdk/commit/4f85ffabddfeb9b54022b99c7c67dfd8b19df041))

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pip install musher-sdk
1717
import musher
1818

1919
# Explicit token
20-
musher.configure(api_key="your-token")
20+
musher.configure(token="your-token")
2121

2222
bundle = musher.pull("myorg/my-bundle:1.0.0")
2323

@@ -64,8 +64,8 @@ import musher
6464

6565
# All parameters are optional — omitted values auto-discover
6666
musher.configure(
67-
api_key="your-token", # or token="your-token"
68-
api_url="https://custom.dev", # or registry_url="https://custom.dev"
67+
token="your-token",
68+
registry_url="https://custom.dev",
6969
cache_dir=Path("/tmp/cache"),
7070
)
7171
```
@@ -87,12 +87,8 @@ The SDK uses a content-addressable disk cache:
8787
- Sync (`Client`) and async (`AsyncClient`) clients
8888
- Content-addressable cache with TTL and garbage collection
8989
- Typed handles: skills, prompts, toolsets, agent specs
90-
91-
## What's Stubbed
92-
93-
- `export_claude_plugin()`, `install_vscode_skills()`, `install_claude_skills()`
94-
- `write_lockfile()`, `verify()`
95-
- OCI direct pull (`OCIClient`)
90+
- `export_claude_plugin()` — export bundle as a Claude plugin
91+
- `install_claude_skills()` — install skills to a directory
9692

9793
## License
9894

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "musher-sdk"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
description = "Python SDK for the Musher bundle distribution platform"
55
readme = "README.md"
66
license = "Apache-2.0"

src/musher/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Musher Python SDK — programmatic access to the Musher bundle registry."""
22

3+
from importlib.metadata import PackageNotFoundError, version as _metadata_version
4+
35
from musher._auth import resolve_registry_url
46
from musher._bundle import Asset, Bundle, Manifest, ManifestAsset, ResolveResult
57
from musher._client import AsyncClient, Client
@@ -25,18 +27,19 @@
2527
ToolsetHandle,
2628
)
2729
from musher._types import (
28-
OCI_MEDIA_TYPE_ASSET,
29-
OCI_MEDIA_TYPE_CONFIG,
3030
AssetType,
3131
BundleRef,
3232
BundleSourceType,
3333
BundleVersionState,
3434
BundleVisibility,
3535
)
3636

37+
try:
38+
__version__ = _metadata_version("musher-sdk")
39+
except PackageNotFoundError:
40+
__version__ = "0.0.0+unknown"
41+
3742
__all__ = [
38-
"OCI_MEDIA_TYPE_ASSET",
39-
"OCI_MEDIA_TYPE_CONFIG",
4043
"APIError",
4144
"AgentSpecHandle",
4245
"Asset",
@@ -68,6 +71,7 @@
6871
"SkillHandle",
6972
"ToolsetHandle",
7073
"VersionNotFoundError",
74+
"__version__",
7175
"configure",
7276
"get_config",
7377
"pull",

src/musher/_bundle.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class Bundle:
182182
_toolset_handles: dict[str, ToolsetHandle] | None = field(default=None, repr=False)
183183
_agent_spec_handles: dict[str, AgentSpecHandle] | None = field(default=None, repr=False)
184184

185-
# ── File access (replaces asset/assets/assets_by_type) ──────────
185+
# ── File access ──────────────────────────────────────────────
186186

187187
def file(self, logical_path: str) -> FileHandle | None:
188188
"""Get a single file by logical path."""
@@ -288,7 +288,7 @@ def select(
288288
_files=sel_files,
289289
)
290290

291-
# ── Export / install stubs ──────────────────────────────────────
291+
# ── Export / install ───────────────────────────────────────────
292292

293293
def export_claude_plugin(
294294
self,
@@ -299,16 +299,6 @@ def export_claude_plugin(
299299
"""Export bundle as a Claude plugin."""
300300
return self.select(skills=skills).export_claude_plugin(plugin_name, dest=dest)
301301

302-
def install_vscode_skills(
303-
self,
304-
_dest: Path,
305-
_skills: list[str] | None = None,
306-
*,
307-
_clean: bool = False,
308-
) -> None:
309-
"""Install skills to a VS Code skills directory. Raises NotImplementedError (stub)."""
310-
raise NotImplementedError
311-
312302
def install_claude_skills(
313303
self,
314304
dest: Path,
@@ -345,14 +335,6 @@ def install_claude_skills(
345335
_json.dumps(marker_data, indent=2) + "\n", encoding="utf-8"
346336
)
347337

348-
def write_lockfile(self, _dest: Path | None = None) -> Path:
349-
"""Write a lockfile for the current bundle. Raises NotImplementedError (stub)."""
350-
raise NotImplementedError
351-
352-
def verify(self) -> bool:
353-
"""Verify all asset checksums. Raises NotImplementedError (stub)."""
354-
raise NotImplementedError
355-
356338
# ── Internal ────────────────────────────────────────────────────
357339

358340
def _build_handles(self) -> None:

src/musher/_config.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ class MusherConfig:
3939
def configure( # noqa: PLR0913
4040
*,
4141
token: object = _UNSET,
42-
api_key: object = _UNSET,
4342
registry_url: str | None = None,
44-
api_url: str | None = None,
4543
cache_dir: Path | None = None,
4644
config_dir: Path | None = None,
4745
data_dir: Path | None = None,
@@ -52,23 +50,20 @@ def configure( # noqa: PLR0913
5250
) -> None:
5351
"""Set global SDK configuration.
5452
55-
``api_key`` is an alias for ``token``; ``api_url`` is an alias for
56-
``registry_url``. When neither ``token`` nor ``api_key`` is provided,
57-
the credential chain is used to auto-discover a token.
53+
When ``token`` is not provided, the credential chain is used to
54+
auto-discover a token.
5855
"""
5956
from musher._auth import resolve_registry_url, resolve_token # noqa: PLC0415
6057

6158
global _global_config # noqa: PLW0603
6259

6360
# Resolve URL and data_dir first so token resolution can use them
64-
resolved_url = registry_url or api_url or resolve_registry_url()
61+
resolved_url = registry_url or resolve_registry_url()
6562
resolved_data_dir = data_dir or _default_data_dir()
6663

67-
# Resolve token: explicit token > explicit api_key > credential chain
64+
# Resolve token: explicit token > credential chain
6865
if token is not _UNSET:
6966
resolved_token = cast("str | None", token)
70-
elif api_key is not _UNSET:
71-
resolved_token = cast("str | None", api_key)
7267
else:
7368
resolved_token = resolve_token(registry_url=resolved_url, data_dir=resolved_data_dir)
7469

src/musher/_http.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717
from musher._config import MusherConfig
1818

1919

20+
def _get_version() -> str:
21+
"""Read version from package metadata, with fallback."""
22+
from importlib.metadata import version # noqa: PLC0415
23+
24+
try:
25+
return version("musher-sdk")
26+
except Exception: # noqa: BLE001
27+
return "0.0.0"
28+
29+
2030
class HTTPTransport:
2131
"""Thin wrapper around ``httpx.AsyncClient`` with auth and error mapping."""
2232

@@ -26,7 +36,7 @@ def __init__(self, config: MusherConfig) -> None:
2636

2737
def _ensure_client(self) -> httpx.AsyncClient:
2838
if self._client is None:
29-
headers: dict[str, str] = {"User-Agent": "musher-python/0.1.0"}
39+
headers: dict[str, str] = {"User-Agent": f"musher-python/{_get_version()}"}
3040
if self._config.token:
3141
headers["Authorization"] = f"Bearer {self._config.token}"
3242

0 commit comments

Comments
 (0)