feat(sdk): add TypeScript SDK (@nvidia/openshell-sdk)#2122
feat(sdk): add TypeScript SDK (@nvidia/openshell-sdk)#2122maxdubrinsky wants to merge 4 commits into
Conversation
First native, per-language SDK for the OpenShell gateway: a thin, idiomatic TypeScript client over proto-generated gRPC stubs (connect-es), no FFI. Covers the v0.1 surface — sandbox lifecycle (create/get/list/delete + waitReady/ waitDeleted), health, and streamed exec. - sdk/typescript/: package, client/transport/errors, protoc + protoc-gen-es codegen (gen/ gitignored, absorbed into dist/ at build), committed lockfile. - tasks/typescript.toml: sdk:ts install/proto/typecheck/build/ci/publish; sdk:ts:typecheck wired into `check`; sdk-typescript job in branch-checks (typecheck, build, and a --dry-run publish that validates the release path). - Enforce SPDX headers on .ts/.tsx/.mts/.cts (skip node_modules and gen/); back-fill docs/_components/jsx.d.ts and fern/components/CustomFooter.tsx. - release.py gains an npm version format; release-tag.yml publishes to GitHub Packages on tag, stamping the version (0.0.0 placeholder in git); prerelease builds publish under the `next` dist-tag, not `latest`. Ships as @nvidia/openshell-sdk on GitHub Packages pre-GA; public npm (@openshell/sdk) follows at GA with an unchanged public API. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
| @@ -0,0 +1,46 @@ | |||
| { | |||
| "name": "@nvidia/openshell-sdk", | |||
There was a problem hiding this comment.
Naming decision to settle here (resolvable thread).
GH Packages forces the @nvidia scope, so pre-GA ships as @nvidia/openshell-sdk. Proposed GA target: @openshell/sdk on public npm — and reserve the @openshell org now to pre-empt squatting. Public API is identical across the move, so GA is an install-specifier change only.
👍 to confirm, or propose an alternative scope/name.
|
🌿 Preview your docs: https://nvidia-preview-pr-2122.docs.buildwithfern.com/openshell |
benoitf
left a comment
There was a problem hiding this comment.
question: can it generate with namespaces ?
like one sandbox with list() method vs tons or root methods like listSandboxes, createSandbox
const myClient = OpenShellClient.connect(...);
await myClient.sandbox.create(...)
await myClient.sandbox.list(...)
await myClient.gateway.add(...)
await myClient.gateway.list(...)like the CLI where we have verbs gateway, sandbox, policy, provider , etc.
- typescript ^5.7.2 -> ^6.0.3 (6.0 is now `latest`; the old caret capped at 5.x) - @types/node ^24.0.0 -> ^24 (same range, tidier) No source changes; codegen, typecheck, and build pass on 6.0.3. Verified the emitted d.ts still type-check for downstream consumers on TypeScript 5.0.4 through 5.9.3, so this does not raise the SDK's consumer TS floor. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
Reshape the client from flat methods (createSandbox, listSandboxes, exec) to a scoped SandboxClient reached as `client.sandbox.create/get/list/delete/exec` (+ waitReady/waitDeleted), mirroring the CLI's noun-verb model and the Python SDK's SandboxClient. SandboxClient is also usable standalone via SandboxClient.connect(); OpenShellClient composes it over a single shared transport, so future service/provider clients reuse one connection. health() stays top-level as a gateway call. No behavior change; types are unchanged. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
@benoitf good question, no we can't but the client isn't generated so namespacing is something we can just do. Refactored this to be closer to the existing Python SDK with a |
Replace the protoc gen.sh with `buf generate` + buf.gen.yaml. `buf` (@bufbuild/buf) is a package devDependency and self-compiles the protos, so the TS SDK no longer depends on the mise-pinned protoc; it drives the same connect-es plugin. Generation stays limited to the client-surface closure (openshell/sandbox/datamodel) via the input paths. Output is byte-identical to the previous protoc + protoc-gen-es pipeline. Lays the groundwork for a shared buf.yaml (lint/breaking/LSP) as a follow-up. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
Summary
Adds the first native TypeScript SDK for the OpenShell gateway
(
@nvidia/openshell-sdk), generated from the protobufs over connect-es with noFFI or napi. It covers the v0.1 surface (sandbox lifecycle, health, streamed
exec) and wires up codegen, CI, and tagged publishing to GitHub Packages.
Related Issue
Supersedes the shared-FFI-core direction from RFC-0008 (#1764): the
frequently-changing surface (RPCs and messages) is already shared through
proto/, so each language builds a native client over the generated stubsinstead of binding a common Rust core.
Changes
sdk/typescript/— new package.OpenShellClient(create/get/list/deleteplus
waitReady/waitDeleted,health, streamedexec), transport/auth(h2c + Node TLS + OIDC bearer / CF-Access), and typed errors. Stubs are
generated with
protoc+@bufbuild/protoc-gen-es(pinned protoc 29.6);src/gen/anddist/are gitignored, anddist/ships the compiled stubs soconsumers never regenerate.
tasks/typescript.toml(install/proto/typecheck/build/ci/publish);
sdk:ts:typecheckadded tocheck; newsdk-typescriptjob inbranch-checks.ymlrunning typecheck,build, and a
--dry-runpublish that validates the release path..ts/.tsx/.mts/.cts(skipsnode_modulesand generatedgen/); two back-filled headers.release.pygains an npm version format;release-tag.ymlpublishes to GitHub Packages on tag, stamping the version from the tag (repo
keeps a
0.0.0placeholder). Prerelease builds publish under thenextdist-tag, stable under
latest.Open decision (for review)
Package name/scope is unsettled; see the resolvable thread on
package.json(the
namefield). Pre-GA is@nvidia/openshell-sdk; the proposed GA name is@openshell/sdkon public npm.Testing
protoccodegen,tsctypecheck, and build all green;npm publish --dry-runproduces a valid 30-file tarball (dist/**+ README +package.json) and restores the placeholder.
ruffclean on changed Python.mise run pre-commit: validated in CI. (Locally the alias alsobuilds/tests the Rust workspace, which the sandbox blocks; that workspace
is untouched here.)
Not included: a vitest unit suite and a gateway-gated live e2e test, both
follow-ups.
Checklist