osdk-core 0.0.1

Core library for the cross-platform osdk toolchain manager
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
# osdk — one SDK manager

**English** · [简体中文](README.zh-CN.md) ·
[Documentation](https://lejunyang.github.io/one-sdk/en/) ·
[Releases](https://github.com/lejunyang/one-sdk/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](site/en/guide/getting-started.md), or see
the [complete feature overview](site/en/guide/features.md).

## Install

Linux and macOS:

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

Windows PowerShell:

```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:

```bash
curl -sSfLO https://raw.githubusercontent.com/lejunyang/one-sdk/main/install.sh
sh install.sh --version 0.0.1 --install-dir "$HOME/bin"
```

```powershell
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:

```bash
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](site/en/guide/installation.md) for PATH setup, installer
options, source builds, and verification.

## Quick start

```bash
# 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:

```bash
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:

```bash
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](site/en/guide/projects.md) ·
[Lockfiles and repeatable environments](site/en/guide/lockfiles.md)

## 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:

```bash
# 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](site/en/guide/http-artifacts.md)

## 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:

```bash
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:

```bash
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](site/en/guide/package-managers.md)

## 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`:

```bash
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](site/en/guide/npm-tools.md)

## 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:

```bash
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:

```bash
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](site/en/guide/cargo-tools.md)

## 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:

```bash
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](site/en/guide/go-tools.md)

## 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

```bash
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

```bash
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

```bash
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

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

### Rust

```bash
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](site/en/guide/runtimes.md)

## Scenario: pin a model snapshot

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

```bash
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:

```bash
osdk model env enable
osdk model env list
osdk model env disable huggingface
```

Guide: [Model snapshots](site/en/guide/models.md)

## 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:

```bash
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:

```bash
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:

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

Guide: [Sources, offline use, and security](site/en/guide/sources-security.md)

## 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:

```toml
[containers.registries."docker.io"]
mirrors = ["https://mirror.example/"]
anonymous_only = true
resolve = "mirror"
```

```bash
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](site/en/guide/containers.md)

## Scenario: inspect caches and reclaim storage

```bash
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](site/en/guide/storage-shell.md)

## Scenario: diagnose an environment or switch language

```bash
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](site/en/guide/storage-shell.md)

## 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

- [Feature overview]site/en/guide/features.md
- [Getting started]site/en/guide/getting-started.md
- [Project toolchains]site/en/guide/projects.md
- [Lockfiles and repeatable environments]site/en/guide/lockfiles.md
- [Runtime and ecosystem workflows]site/en/guide/runtimes.md
- [Package managers and registry selection]site/en/guide/package-managers.md
- [npm developer tools]site/en/guide/npm-tools.md
- [Cargo developer tools]site/en/guide/cargo-tools.md
- [Go developer tools]site/en/guide/go-tools.md
- [Direct HTTPS artifacts]site/en/guide/http-artifacts.md
- [Model snapshots]site/en/guide/models.md
- [Sources, offline use, and security]site/en/guide/sources-security.md
- [Container runtimes, registries, and native operations]site/en/guide/containers.md
- [Storage, shell integration, diagnostics, and i18n]site/en/guide/storage-shell.md
- [Implementation docs]site/en/guide/implementation/index.md

Contributions are welcome through
[issues](https://github.com/lejunyang/one-sdk/issues) and pull requests.

## License

MIT