Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
95aefdc
feat(sdk): add TypeScript SDK (@nvidia/openshell-sdk)
maxdubrinsky Jul 2, 2026
fbcf790
chore(sdk): adopt TypeScript 6, tidy @types/node range
maxdubrinsky Jul 6, 2026
883d9fb
refactor(sdk): group operations under a composable SandboxClient
maxdubrinsky Jul 6, 2026
d364134
chore(sdk): generate TypeScript SDK stubs with buf
maxdubrinsky Jul 7, 2026
ddd0dbd
build(proto): add repo-level buf module with lint
maxdubrinsky Jul 7, 2026
b1f6f74
chore(sdk): publish as unscoped openshell-sdk on public npm
maxdubrinsky Jul 9, 2026
69070f4
chore(sdk): publish @nvidia/openshell-sdk to GitHub Packages
maxdubrinsky Jul 9, 2026
fe0e444
feat(sdk-ts): add streaming exec, forward, ssh, provider, and config …
maxdubrinsky Jul 15, 2026
fe76093
build(sdk-ts): add Biome and Vitest tooling
maxdubrinsky Jul 15, 2026
c7f8dce
test(sdk-ts): cover the sandbox surface with in-memory transport tests
maxdubrinsky Jul 15, 2026
84536d6
docs(sdk-ts): document the new surface and connect/upload/download bo…
maxdubrinsky Jul 15, 2026
dce6eb0
feat(sdk-ts): support mTLS client authentication
maxdubrinsky Jul 20, 2026
fdf11e2
chore(sdk-ts): drop the demo script and its tsx dependency
maxdubrinsky Jul 20, 2026
ff71bd9
fix(sdk-ts)!: harden exec streaming, waits, SSH, and forwarding
maxdubrinsky Jul 20, 2026
bf7b074
feat(sdk-ts): export error contract, enum unions, and caller cancella…
maxdubrinsky Jul 21, 2026
25b7290
feat(sdk-ts): add raw escape hatch for uncurated gateway RPCs
maxdubrinsky Jul 30, 2026
73235b6
fix(sdk-ts): address review feedback on exec, forward, and auth trans…
maxdubrinsky Aug 3, 2026
3b227ba
fix(sdk-ts): address review feedback
drew Aug 13, 2026
2db9385
docs(sdk-ts): defer published sdk guide
drew Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/skills/test-release-canary/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ does not contribute to product usage metrics.

`install.sh` defaults to the *latest tagged* release — the canary is therefore checking that the most recent public release still installs, not the just-published `dev` build. The `kubernetes` job is the exception: it pins to `0.0.0-dev` chart + `:dev` images.

The canary does not install or import `@nvidia/openshell-sdk`. TypeScript SDK
validation lives in the `TypeScript SDK` branch check, including a publish
dry-run. The tagged release workflow publishes the package to GitHub Packages;
verify that job directly when diagnosing SDK publication failures.

## Trigger paths

The workflow has two triggers:
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,32 @@ jobs:

- name: Lint
run: mise run markdown:lint

sdk-typescript:
name: TypeScript SDK
needs: pr_metadata
if: needs.pr_metadata.outputs.should_run == 'true'
runs-on: linux-amd64-cpu8
container:
image: ghcr.io/nvidia/openshell/ci:latest
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Install tools
run: mise install --locked

- name: Check TypeScript SDK
run: mise run sdk:ts:ci

# Exercise the full release publish path (version stamp, dist-tag,
# prepublishOnly, tarball) without uploading. Uses the off-tag dev
# version, which validates the prerelease dist-tag branch too.
- name: Verify publishable artifact (dry-run)
env:
OPENSHELL_NPM_PUBLISH_ARGS: --dry-run
run: |
OPENSHELL_NPM_VERSION="$(uv run python tasks/scripts/release.py get-version --npm)" \
mise run sdk:ts:publish
40 changes: 40 additions & 0 deletions .github/workflows/release-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
outputs:
python_version: ${{ steps.v.outputs.python }}
cargo_version: ${{ steps.v.outputs.cargo }}
npm_version: ${{ steps.v.outputs.npm }}
deb_version: ${{ steps.v.outputs.deb }}
rpm_version: ${{ steps.v.outputs.rpm_version }}
rpm_release: ${{ steps.v.outputs.rpm_release }}
Expand All @@ -65,6 +66,7 @@ jobs:
set -euo pipefail
echo "python=$(uv run python tasks/scripts/release.py get-version --python)" >> "$GITHUB_OUTPUT"
echo "cargo=$(uv run python tasks/scripts/release.py get-version --cargo)" >> "$GITHUB_OUTPUT"
echo "npm=$(uv run python tasks/scripts/release.py get-version --npm)" >> "$GITHUB_OUTPUT"
echo "deb=$(uv run python tasks/scripts/release.py get-version --deb)" >> "$GITHUB_OUTPUT"
echo "rpm_version=$(uv run python tasks/scripts/release.py get-version --rpm-version)" >> "$GITHUB_OUTPUT"
echo "rpm_release=$(uv run python tasks/scripts/release.py get-version --rpm-release)" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -1071,6 +1073,44 @@ jobs:
working-directory: ./fern
run: fern generate --docs

publish-sdk-typescript:
name: Publish TypeScript SDK
needs: [compute-versions, release]
runs-on: linux-amd64-cpu8
timeout-minutes: 15
permissions:
contents: read
packages: write
container:
image: ghcr.io/nvidia/openshell/ci:latest
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ inputs.tag || github.ref }}

- name: Mark workspace safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Install tools
run: mise install --locked

- name: Configure npm auth for GitHub Packages
working-directory: ./sdk/typescript
run: |
{
echo "@nvidia:registry=https://npm.pkg.github.com"
echo '//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}'
} > .npmrc

- name: Publish
env:
OPENSHELL_NPM_VERSION: ${{ needs.compute-versions.outputs.npm_version }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: mise run sdk:ts:publish

release-helm:
name: Release Helm Chart (OCI)
needs: [compute-versions, release, tag-ghcr-release]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pip-delete-this-directory.txt

# Unit test / coverage reports
coverage.out
coverage/
htmlcov/
.tox/
.nox/
Expand Down
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ These pipelines connect skills into end-to-end workflows. Individual skill files
| `crates/openshell-supervisor-process/` | Process supervisor | Process lifecycle, namespace, and bypass monitoring |
| `crates/openshell-vfio/` | VFIO support | PCI and GPU passthrough preparation and lifecycle |
| `python/openshell/` | Python SDK | Python bindings and CLI packaging |
| `sdk/typescript/` | TypeScript SDK | Native Connect client, curated sandbox API, and generated protobuf types |
| `proto/` | Protobuf definitions | gRPC service contracts |
| `deploy/` | Docker, Helm, K8s | Dockerfiles, Helm chart, manifests |
| `docs/` | Published docs | MDX pages, navigation, and content assets |
Expand Down Expand Up @@ -213,6 +214,14 @@ ocsf_emit!(event);
- Converters in `sdk/go/openshell/v1/internal/converter/` deep-copy slices and maps at boundaries.
- Tests use bufconn for in-process gRPC and testify for assertions.

## TypeScript SDK (`sdk/typescript/`)

- Run `mise run sdk:ts:ci` for codegen, proto lint, Biome lint, type checking, unit tests, coverage, and build validation.
- Proto bindings are generated with `mise run sdk:ts:proto` from the files selected in `sdk/typescript/buf.gen.yaml`.
- Generated files under `sdk/typescript/src/gen/` are build outputs and must not be committed.
- Keep the curated API free of generated wire types; expose full generated messages and RPCs through `@nvidia/openshell-sdk/raw`.
- The release workflow publishes the package to GitHub Packages. Branch checks exercise the publish path with `npm publish --dry-run`.

## Python

- Always use `uv` for Python commands (e.g., `uv pip install`, `uv run`, `uv venv`)
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ Bazel does not yet cover `mise run gateway`, `mise run sandbox`, `mise run e2e`,
| `crates/` | Rust crates |
| `python/` | Python SDK and bindings |
| `sdk/go/` | Go SDK (types, gRPC clients, converters) |
| `sdk/typescript/` | TypeScript SDK (Connect client and generated protobuf bindings) |
| `proto/` | Protocol buffer definitions |
| `tasks/` | `mise` task definitions and build scripts |
| `deploy/` | Dockerfiles, Helm chart, Kubernetes manifests |
Expand Down
15 changes: 15 additions & 0 deletions architecture/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ OpenShell builds these main artifacts:
|---|---|
| Gateway binary | `crates/openshell-server` |
| CLI package and Python SDK | `python/openshell` plus Rust binaries where packaged |
| TypeScript SDK package | `sdk/typescript` |
| Gateway container image | `deploy/docker/Dockerfile.gateway` |
| Supervisor container image | `deploy/docker/Dockerfile.supervisor` |
| Helm chart | `deploy/helm/openshell` |
Expand Down Expand Up @@ -213,6 +214,20 @@ pins them back in with `[tool.maturin].include` globs. The release workflows
install each Linux wheel in a clean image and import `openshell.sandbox` as a
smoke check.

## TypeScript SDK Packaging

The native TypeScript SDK in `sdk/typescript` uses Connect over the generated
OpenShell protobuf surface. `sdk/typescript/buf.gen.yaml` selects the client
proto closure, and `mise run sdk:ts:proto` generates gitignored sources under
`src/gen`. TypeScript compilation includes those sources in `dist`, so package
consumers do not run code generation.

Branch checks run `mise run sdk:ts:ci`, enforce an 80% line-coverage floor, and
exercise version stamping plus `npm publish --dry-run`. Tagged releases publish
`@nvidia/openshell-sdk` to GitHub Packages. The repository keeps package version
`0.0.0`; the release task derives and temporarily stamps the npm version from
the release tag.

## CI and E2E

Required checks run on GitHub Actions. Workflows that use NVIDIA self-hosted runners trigger from copy-pr-bot mirror branches, so trusted PRs are mirrored into `pull-request/<N>` branches before those workflows run. `main` also uses GitHub merge queue so the final queued integration commit is validated before it merges.
Expand Down
3 changes: 3 additions & 0 deletions docs/_components/jsx.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

declare const React: unknown;
3 changes: 3 additions & 0 deletions fern/components/CustomFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

/**
* Custom footer for NVIDIA docs (Fern native header/footer).
* Markup and class names match the original custom-app footer 1:1 so that
Expand Down
9 changes: 9 additions & 0 deletions scripts/update_license_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
".yaml": "#",
".yml": "#",
".rego": "#",
".ts": "//",
".tsx": "//",
".mts": "//",
".cts": "//",
}

# Directories to skip entirely (relative to repo root).
Expand All @@ -55,6 +59,7 @@
".git",
".cache",
"python/openshell/_proto",
"sdk/typescript/src/gen",
}

# Individual filenames to skip.
Expand Down Expand Up @@ -103,6 +108,10 @@ def is_excluded(rel: Path) -> bool:
"""Return True if a path should be skipped."""
rel_str = rel.as_posix()

# Vendored dependencies never carry our headers, at any depth.
if "node_modules" in rel.parts:
return True

# Exact filename exclusions.
if rel.name in EXCLUDE_FILES:
return True
Expand Down
5 changes: 5 additions & 0 deletions sdk/typescript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
src/gen/
dist/
*.tsbuildinfo
.npmrc
Loading
Loading