osdk-core 0.0.1

Core library for the cross-platform osdk toolchain manager
Documentation

osdk — one SDK manager

English · 简体中文 · Documentation · Releases

osdk gives Windows, macOS, and Linux projects one CLI for language runtimes, package managers, developer tools, and model snapshots. Use it to:

  • install and switch complete project toolchains with one command style;
  • keep platform-aware project locks that teammates and CI can reuse;
  • choose responsive SDK mirrors and dependency registries automatically;
  • work from downloaded metadata and artifacts when the network is unavailable;
  • manage Hugging Face and ModelScope snapshots alongside development tools;
  • inspect Docker, containerd, Buildx, OCI registries, mirror benchmarks/plans, and native caches, then deliberately apply mirror config, pull images, or approve narrowly scoped native cleanup;
  • inspect storage, caches, active versions, and environment health in English or Chinese.

Start with the getting-started guide, or see the complete feature overview.

Install

Linux and macOS:

curl --proto '=https' --tlsv1.2 -sSf \
  https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.ps1 | iex

The installers download the latest release and verify it against SHA256SUMS. To choose a version or destination, download the script first:

curl -sSfLO https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.sh
sh install.sh --version 0.0.1 --install-dir "$HOME/bin"
Invoke-WebRequest `
  https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.ps1 `
  -OutFile install.ps1
.\install.ps1 -Version 0.0.1 -InstallDir "$HOME\bin"

If Rust is already installed, cargo install osdk-cli --locked installs the main osdk command and its private osdk-aube helper. Use the Release installer for the complete three-program installation, including osdk-shim.

If GitHub downloads are slow, route both the installer and release downloads through a trusted proxy:

curl --proto '=https' --tlsv1.2 -sSf \
  https://gh-proxy.com/https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.sh |
  OSDK_DOWNLOAD_BASE_URL=https://gh-proxy.com/https://github.com sh

See Installation for PATH setup, installer options, source builds, and verification.

Quick start

# Install several runtimes; downloads can run concurrently.
osdk --jobs 4 install node@20 python@3.12 go@1.22

# Choose a user-wide default.
osdk use -g node@20

# Pin a version for the current project.
osdk use python@3.12

# See what this directory will use.
osdk current

# Enable automatic per-directory switching.
eval "$(osdk activate bash)"

node --version
python --version

Activation also supports zsh, fish, and PowerShell. Run osdk --help or osdk <command> --help whenever you need the full command reference.

Scenario: make a project toolchain reproducible

Pin tools in the repository, resolve them, and install the matching lock for the current platform:

osdk use node@20
osdk use python@3.12
osdk use go@1.22
osdk lock
osdk install

Check for newer matching versions or run a command without changing project pins:

osdk outdated
osdk upgrade
osdk exec --tool node@20 -- node --version

For immutable Rust reproduction, pin an explicit or dated toolchain. Floating rustup channels such as stable, beta, and nightly remain floating when written to the lock.

osdk can also follow existing .tool-versions, .nvmrc, .node-version, .python-version, .java-version, go.mod, rust-toolchain.toml, and Node version declarations in package.json. Data-only declarative backends use the same locked artifact URL, checksum, download cache, and offline reinstall path as built-in archive backends. For osdk-owned dynamic npm:<package>, cargo:<crate-or-https-url>, go:<module-or-command-path>, and github:owner/repo installs, options and managed-runtime dependencies that change the selected or built output are part of the installation identity. osdk records that identity in .osdk-install.json schema 1 and places each b3-v2: identity under its own fingerprinted install root, so multiple identities of the same backend and version can coexist. Reuse, activation, shims, where, uninstall, and reshim all select the exact configured identity. Older .osdk-tool.json manifests are detected only as legacy state and are never reused or executed.

Guides: Project toolchains · Lockfiles and repeatable environments

Scenario: install a tool from a direct HTTPS artifact

For a tool without a dedicated backend, bind one exact semantic version to an HTTPS {version} URL template and the publisher's SHA-256. A bare executable can be installed directly:

# Replace the example digest with the SHA-256 of the exact 1.2.3 artifact.
osdk install \
  'http:https://downloads.example.com/acme-{version}[sha256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef,kind=file,rename=acme]@1.2.3'

The same backend supports tar.gz, tar.xz, and ZIP archives with explicit bin/bins, subdir, strip-components, and single-binary rename layout options. Plain HTTP, credentials, query strings, cross-origin redirects, floating versions, and missing checksums fail closed. Downloads bypass proxies, pin DNS results only after every address passes a conservative public-address check, and have a 512 MiB transfer cap and 10-minute HTTP request timeout. Archives are limited to 16,384 entries and 2 GiB of cumulative declared expanded size; publication also requires at least one executable, and Windows publishes only .exe-named outputs. After an online install and osdk lock, osdk --offline install can replay the locked URL, filename, and checksum from the exact identity-scoped cache; the lock does not embed the artifact bytes.

Guide: Direct HTTPS artifacts

Scenario: use package managers with an available registry

Install npm, pnpm, or Yarn independently, or let an exact package.json#packageManager selection join the project toolchain:

osdk install npm@11.5.2
osdk install pnpm@9.15.0
osdk install yarn@4.9.1

Before a package-manager process starts, osdk can select a healthy configured registry for npm, pnpm, Yarn, Bun, and Deno. Inspect the current choice with:

osdk registry test
osdk registry test pnpm

Explicit registry flags, environment variables, private registries, and native package-manager configuration remain under your control.

Guide: Package managers and registry selection

Scenario: add an npm-published developer tool

Prefix a package with npm: to distinguish it from the npm package manager. In a Node project, use adds the package to the nearest package.json, keeps an existing dependency section (or defaults to devDependencies), and makes its local command available after shell activation. Activation exposes only an osdk-curated generation of the configured packages' validated commands, never the project's entire node_modules/.bin:

osdk use npm:prettier@3
eval "$(osdk activate bash)"
prettier --check .

# Force a particular installer when the automatic choice is not wanted.
osdk use npm:eslint@9 -o installer=pnpm

# Install a user-wide tool without changing the current project.
osdk use --global 'npm:@antfu/ni@0.21.12' -o installer=aube
osdk where --global 'npm:@antfu/ni'
osdk uninstall --global 'npm:@antfu/ni@0.21.12'

Project use respects the nearest package.json and exactly one compatible existing native lock. Automatic selection prefers Aube when that lock is compatible; installer=aube, installer=npm, and installer=pnpm select one explicitly. Shell activation exposes only validated commands from packages selected by the trusted project configuration, never the project's entire node_modules/.bin. Without a package.json, local use retains the isolated osdk-managed installation and shim behavior. The generated .osdk/npm-bin/ directory is local derived state and should normally be ignored by version control. Commit the package manager's native lock alongside osdk.lock; the latter does not replace the transitive dependency graph.

Global npm, pnpm, and Aube choices each run that manager's real global-add operation inside an osdk-controlled prefix, leaving the ambient Node installation untouched. Release installs include the osdk-aube companion needed for Aube global mode. Aube 2.1 needs network access for a new or repaired global install, although an already complete exact install with matching options can be selected again offline without launching Aube; choose npm or pnpm when the install itself must use a native offline mode. where --global and uninstall --global explicitly target the user-wide npm installation whose exact configured identity matches. Without that flag, the existing project/isolated behavior is preserved; uninstall removes only the selected identity root, while sibling identities of the same package version remain installed. A global uninstall also removes its user config, lock entry, and now-unowned shims. Project-managed npm dependencies and their curated .osdk/npm-bin generation remain separate from these osdk-owned roots.

Guide: npm developer tools

Scenario: install a Rust CLI from Cargo

Choose one exact managed Rust version, then install a crate by exact version, latest stable release, or numeric prefix:

osdk use rust@1.91.1
osdk use cargo:ripgrep@14.1 -o features=pcre2 -o locked=true
eval "$(osdk activate bash)"
rg --version

Cargo tools reject floating or linked Rust toolchains. Registry requests use cargo:<crate>; HTTPS Git requests use latest, tag:<ref>, branch:<ref>, or an immutable rev:<40 lowercase hex> selector:

osdk use \
  'cargo:https://github.com/BurntSushi/ripgrep.git@rev:0123456789abcdef0123456789abcdef01234567'

Supported build options are features, default-features, bin, locked (default false), and Git-only crate. A complete exact installation can be reused offline, but Cargo locks do not contain the complete source graph needed for a cold offline build. Registry versions are recorded as version-only, full Git revisions as immutable-revision, and Git HEAD/tags/branches as floating-ref.

Guide: Cargo developer tools

Scenario: install a Go command package

Keep the Go runtime and Go command namespaces separate, then install a command with an exact managed Go toolchain:

osdk use go@1.24
osdk use go:golang.org/x/tools/gopls@0.20.0
eval "$(osdk activate bash)"
gopls version

go: accepts module or nested command paths, latest, numeric prefixes, exact semantic versions, and canonical pseudo-versions. tags and a restricted env option are identity-bearing; CGO_ENABLED=0 is supported, while enabling cgo is rejected until a C toolchain can be bound to the install identity. osdk chooses and records one Go proxy, invokes the exact managed go once with a staged GOBIN, and keeps module/build caches under its cache root. The compact schema-4 lock records the proxy, module root, and exact Go runtime—not the transitive module graph—so an exact completed install can be reused offline, but a cold offline build cannot.

Guide: Go developer tools

Scenario: work in each language ecosystem

The same command style applies across ecosystems, while backend-specific capability notes live in their guides. Runtime-specific commands cover the workflows that need them.

Node.js

osdk install node@20 -o corepack=true
osdk lock node@20 -o arch=arm64
osdk node migrate-packages --from 20.19.0 --to 22.17.0
osdk node migrate-packages --from 20.19.0 --to 22.17.0 --apply

Python

osdk install python@3.14
osdk install python@cpython-3.14+freethreaded
osdk install python@pypy-3.11
osdk python find
osdk python find pypy-3.11

Java and JVM tools

osdk install java@21
osdk install java@21 -o package-type=jre
osdk install java@21 -o distribution=zulu -o package-type=jdk
osdk install maven@3.9.16 gradle@9.7.0 kotlin@2.4.10

Go

osdk install go@1.22
osdk use go@1.22
osdk exec --tool go@1.22 -- go version

Rust

osdk install rust@stable -o profile=minimal -o components=clippy,rustfmt
osdk rust component add rustfmt --toolchain stable
osdk rust target add x86_64-pc-windows-gnu --toolchain stable
osdk rust check --repair

Guide: Runtime and ecosystem workflows

Scenario: pin a model snapshot

Pull selected files from Hugging Face or ModelScope, verify the local snapshot, and obtain its path:

export HF_TOKEN=... # optional for private or gated repositories

osdk model pull qwen25 \
  hf:Qwen/Qwen2.5-7B-Instruct@main \
  --include '*.json' --include '*.safetensors'
osdk model pull qwen25-ms \
  ms:Qwen/Qwen2.5-7B-Instruct@master \
  --include '*.json' --include '*.safetensors'
osdk model verify qwen25
osdk model path qwen25
osdk model list

Enable provider endpoint and cache variables for activated shells when model tools should share the osdk environment:

osdk model env enable
osdk model env list
osdk model env disable huggingface

Guide: Model snapshots

Scenario: control sources, offline use, and trust

Let osdk rank available sources, pin a preferred mirror, add a trusted internal source, or override the source for one command:

osdk source list node
osdk source test node
osdk source pin node tuna
osdk source add node --id mycorp \
  --download-url https://mirror.corp/node/ \
  --index-url https://mirror.corp/node/index.json
osdk --source official install go@1.22

After a successful online download, require cache-only operation with --offline. Tighten artifact policy when your environment requires it:

osdk --offline install node@20
osdk --require-checksums install github:sharkdp/fd
osdk --attestations required install github:cli/cli@latest

Review and explicitly trust project configuration that changes sources or execution behavior:

osdk --yes trust ./osdk.toml
osdk trust list
osdk untrust ./osdk.toml

Guide: Sources, offline use, and security

Scenario: inspect and operate native container runtimes

Docker Hub works out of the box with two operator-documented public pull-through caches, mirror.gcr.io and docker.m.daocloud.io. osdk benchmarks them anonymously against library/alpine:latest, verifies manifest equivalence and a bounded layer sample, and recommends the passing mirrors by measured latency. An explicit policy in trusted user or project configuration fully replaces those built-ins:

[containers.registries."docker.io"]
mirrors = ["https://mirror.example/"]
anonymous_only = true
resolve = "mirror"
osdk container doctor
osdk container doctor --runtime docker --builder my-builder
osdk container doctor --json
osdk container registry test docker.io
osdk container registry test docker.io \
  --image ubuntu:24.04 --platform linux/amd64 --json
osdk container mirrors plan docker.io --runtime docker
osdk container mirrors plan docker.io --runtime docker \
  --native-config /etc/docker/daemon.json --json
osdk container mirrors apply docker.io --runtime docker \
  --native-config /etc/docker/daemon.json
# Automation is two-step and binds the exact fresh plan:
plan_id=$(osdk container mirrors apply docker.io --runtime docker \
  --native-config /etc/docker/daemon.json --dry-run --json | jq -r .plan_id)
osdk --yes container mirrors apply docker.io --runtime docker \
  --native-config /etc/docker/daemon.json --accept-plan "$plan_id" --json
osdk container cache status
osdk container cache status --runtime buildkit --builder my-builder
osdk container pull ubuntu:24.04
osdk container pull ghcr.io/example/tool:1.0 \
  --runtime containerd --platform linux/amd64 \
  --address unix:///run/containerd/containerd.sock --namespace default
osdk container prune --runtime docker --scope images
osdk container prune --runtime buildkit --scope build-cache --builder my-builder

container doctor reports the selected runtime first, then the typed facts already obtained by that probe: Docker versions/platform/rootless/Desktop and mirror origins; containerd versions and registry-config state; and Buildx driver, node state, BuildKit versions, endpoints, and platforms. Its schema-version-2 JSON omits context, builder and node names, namespaces, native config paths, and secret-bearing endpoint paths or queries.

Registry tests use anonymous HTTPS only, validate image digests, platform selection, bounded Range support, and rank verified mirrors. A mirror plan always targets one configured or Docker Hub built-in registry policy and one explicit Docker, containerd, or BuildKit control plane. It reports a deterministic plan_id; without an explicit native config path a locally actionable plan is manual-only. Planning never writes native configuration, starts builders, or restarts daemons. Plan JSON can expose operational absolute paths, builder names, and mirror origins plus whether a path prefix exists; exact mirror prefixes, existing configuration contents, and generated candidate bytes remain hidden. mirrors apply performs that benchmark and plan in one invocation, prompts interactively without asking you to copy the ID, then rechecks the input under a lock and atomically replaces the file. It never elevates privileges or restarts/recreates the native service. Unattended --yes requires the exact fresh --accept-plan; use --dry-run --json to obtain it.

container pull uses the effective runtime and platform unless you override them. In auto mode it performs one bounded read-only Docker/containerd resolution, then starts exactly one native foreground pull. Explicit containerd selection requires paired --address and --namespace values; auto requires them only if containerd wins, so Docker can proceed without them. The child inherits stdio and osdk waits for it, returning its direct exit code or, on Unix, normalized 128 + signal; it does not fall back to another runtime or copy the image into an osdk store.

container prune is preview-only by default. It can preview one discovered Docker context or Buildx builder and binds a secret-safe fingerprint of the Docker endpoint or Buildx driver/node endpoint topology. Execution is available only for Docker contexts backed by a directly addressable local Unix socket or Windows named pipe without context-held TLS material; it uses docker --host and removes only dangling images. To execute, repeat the command with both --execute and the exact reported --accept-preview sha256:..., then confirm the execution prompt (or use global --yes). BuildKit remains preview-only because its mutable builder name cannot be pinned atomically. Although --scope remains required, containerd has no accepted scope pairing: a selector-free, non-executing request reports typed unsupported, while selectors and execution flags are rejected. The command never expands into system-wide cleanup of containers, volumes, networks, or implementation-private stores.

Guide: Container runtimes, registries, and native operations

Scenario: inspect caches and reclaim storage

osdk cache dir
osdk cache env
osdk --yes cache clean
osdk prune --dry-run
osdk --yes prune

cache clean removes downloaded archives. prune reclaims unreferenced shared content; prune --dry-run does not delete anything.

Guide: Storage, caches, and shell integration

Scenario: diagnose an environment or switch language

osdk doctor
osdk current
osdk where node
osdk config path
osdk config list
osdk --lang zh doctor
OSDK_LANG=en osdk --help
osdk completions bash > osdk.bash

osdk localizes commands, help, prompts, errors, and diagnostics in English and Chinese. --lang overrides the locale for one command; OSDK_LANG sets the session preference.

Guide: Storage, shell integration, diagnostics, and i18n

Support matrix

Area Supported
Platforms Windows, macOS, Linux
Runtimes Node.js, Python, Java JDK/JRE, Go, Rust, Deno, Bun
Package and JVM tools npm, pnpm, Yarn, Maven, Gradle, Kotlin
Other developer tools npm packages through npm:<package>, registry crates or HTTPS Git repositories through cargo:..., Go command packages through go:<module-or-command-path>, public GitHub Releases through github:owner/repo, and exact checksum-pinned HTTPS artifacts through http:https://...{version}...
Model providers Hugging Face, ModelScope
Native container operations Docker Engine, containerd, Docker Buildx, anonymous OCI registry tests, built-in Docker Hub mirror benchmarking, safe native mirror apply, direct native image pulls, native cache status, Docker local-endpoint pruning, and BuildKit prune previews
Project inputs osdk.toml, .tool-versions, common ecosystem version files
Shells Bash, zsh, fish, PowerShell
CLI languages English, Chinese

Documentation

Contributions are welcome through issues and pull requests.

License

MIT