Skip to content

[SDK-003] Add Hub API client #5

Description

@AdeGneus

Context

The CLI needs a typed client for listing, downloading, verifying, and installing Hub skills without hardcoding HTTP and JSON parsing.

Scope

  • Create ori_sdk/hub.py.
  • Define HubSkillEntry, HubInstallResult, and SkillHubClient.
  • Use guarded httpx import.
  • Orchestrate download -> signature verification -> safe extraction for install.

Non-Goals

  • Does not implement the Hub server.
  • Does not bypass signature verification.
  • Does not execute downloaded skill code.

Technical Specification

SkillHubClient should provide list_available(), fetch_metadata(name), download_tarball(entry), and install(name, target_dir). Install refuses invalid signatures and path traversal.

Acceptance Criteria

  • Client models are typed.
  • HTTP failures map to typed SDK errors.
  • Invalid signature refuses install.
  • pytest, mypy, and ruff pass.

Tests Required

Test Verifies
test_list_available_parses_entries Hub list response parsed.
test_install_refuses_invalid_signature Signature gate enforced.
test_download_http_error_maps_to_sdk_error HTTP failures are typed.

Additional Test Coverage / Edge Cases

  • Mock Hub 200, 404, 500, timeout, and malformed JSON responses.
  • Reject downloads whose signature does not verify before extraction.
  • Reject tarballs containing path traversal entries or absolute paths.
  • Ensure install is atomic: failed install leaves no partial skill directory.
  • Handle pending-review/unlisted skill metadata without treating it as installable.
  • Verify client methods do not execute downloaded Python hook files.

Invariants — Do Not Violate

  • SDK must not execute skill hooks.
  • All community skill installs verify signature before extraction.

Dependencies

Blocked by:

Unblocks:

Contract References

  • Skills Hub API contract
  • ori-specs/signing/v1.md

Priority

post-poc

Suggested Labels

blocked, post-poc

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedWaiting on another issue or external dependency.post-pocImportant but not blocking PoC.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions