Skip to content

feat: rewrite sdk with strict bundled types - #11

Merged
aaqaishtyaq merged 12 commits into
mainfrom
agent/rewrite-strict-sdk
Aug 14, 2026
Merged

feat: rewrite sdk with strict bundled types#11
aaqaishtyaq merged 12 commits into
mainfrom
agent/rewrite-strict-sdk

Conversation

@aaqaishtyaq

@aaqaishtyaq aaqaishtyaq commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

This is a clean follow-up to PR 10 that rewrites the SDK packaging and type boundaries for a modern Node.js 22/Bun project.

  • Switch TypeScript to bundler resolution and remove .js relative import specifiers from source and tests.
  • Keep Vite as the library bundler and target Node 22, emitting a single ESM runtime bundle.
  • Replace the inline import('./zeish.types.js') ingress type and inline API response/action shapes with named exported contracts.
  • Enable strict optional-property, unchecked-index, and unknown-catch-variable checks.
  • Add Node/Bun engine requirements, pnpm package-manager metadata, and a unified check script.

Why

PR 10 made Git installs buildable, but the SDK still exposed ad-hoc type expressions and NodeNext source import conventions that leaked .js specifiers into the codebase. This refactor centralizes the public contract and lets Vite own the runtime module graph.

Validation

  • pnpm typecheck
  • pnpm test — 5 files, 29 tests
  • pnpm build
  • git diff --check

The repository's contract verification scripts were inspected but could not run because this checkout does not contain the expected generated/ and contracts/ artifact directories.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Without a stable Idempotency-Key, request() minted a fresh random UUID
per call, defeating Edge's server-side idempotency store: every retry
of a create -- including a full re-attach after a crash -- looked like
a brand-new request and could create a duplicate sandbox.

ZeishCreateSandboxOptions gains an optional idempotencyKey; createSandbox
passes it through as the request's Idempotency-Key header instead of a
random one. createAndStartSandbox keys it per attempt
(`${idempotencyKey}:attempt-${n}`) so a genuine retry-with-a-fresh-machine
still creates a new sandbox, while a raw transport retry of the same
attempt's HTTP call reuses it.
createSandbox already sets desiredStatus "running" and boots the
machine on its own. createAndStartSandbox called startSandbox() again
right after, unconditionally -- reproduced via raw curl (no SDK, no
other client): calling POST /sandboxes/{id}/start immediately after
POST /sandboxes races Edge's state machine and kills the machine
outright, landing on status "failed" with an empty
"runtime terminal state: " lastError. machined's own StartService.Start
permits starting from the "created" state, so it doesn't reject the
redundant call -- it forwards it into the FSM while create is still
in flight.

Only call start when the freshly created sandbox isn't already on its
way up (desiredStatus / status not already running).
Expose raw_l4 ingress with explicit tcp or udp transport in the public SDK and document exposedPorts as a deprecated TCP compatibility shorthand.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Expose runtime service metadata in the SDK so URL-based services and native UDP endpoints use distinct client representations. Add transport, host, and port fields without changing the raw_l4 creation contract.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Require generic protocol-aware ingress in the public SDK and stop
emitting the removed exposedPorts compatibility field.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Bump the provider package version and run the package build from the
prepare lifecycle so Git-based consumers receive generated declarations
and runtime dist files even though dist remains a publish artifact.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Avoid reading ingress from omitted sandbox options, keep idempotency
keys stable across ambiguous create transport failures, and advance the
key only after a sandbox identity is returned. Run the package prepare
hook through the locally installed Vite binary so Git installs do not
require a global pnpm executable.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Refactor the Zeish ComputeSDK around a strict TypeScript contract and a
modern Node.js 22/Bun package runtime. Use TypeScript bundler resolution
and Vite output so source and generated declarations do not require .js
relative import specifiers, and keep the published runtime as one bundled
ES module.

Replace the inline ingress import type and inline API response/action
shapes with named SDK contracts. Enable exact optional properties,
unchecked-index safety, and unknown catch variables, then update request
construction to preserve those guarantees without undefined properties.

Add Node.js and Bun engine requirements, a package manager declaration, and
a single check script for typecheck, tests, and build. Keep the existing
public exports and contract behavior intact while updating tests to the
extensionless module convention.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Introduce a transport Strategy boundary with a Fetch implementation and a
transient-read retry Decorator. Keep authentication and response parsing
behind the transport-aware API factory while allowing callers to inject a
custom transport for tests and alternate runtimes.

Add a lazy async Iterator for sandbox pagination so provider listing does
not duplicate cursor traversal or eagerly couple callers to page envelopes.
Add a typed lifecycle State policy for validating sandbox transitions and a
Command serializer for the desktop action wire contract.

Integrate the iterator into the provider facade, export the new extension
points, and add focused coverage for retries, pagination, lifecycle rules,
and command serialization.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
@aaqaishtyaq

Copy link
Copy Markdown
Member Author

Implemented the design-pattern refactor:

  • Strategy + Decorator: injectable ZeishTransport, Fetch transport, and transient-read retry wrapper.
  • Iterator: lazy api.iterateSandboxes() consumed by the provider facade.
  • State: typed sandbox lifecycle transition policy with early validation.
  • Command: typed desktop action serializer for the sandboxd wire contract.
  • Facade/Adapter remain the primary public architecture through createZeishSandboxClient() and the ComputeSDK provider.

Added focused tests; validation is now 7 test files / 33 tests, plus typecheck and build.

@aaqaishtyaq
aaqaishtyaq marked this pull request as ready for review August 14, 2026 15:32
Merge the latest main branch into the strict SDK rewrite while preserving
both feature sets. Keep main's sandbox port-sharing API and its public
contract tests, and route the new operation through the injected transport
strategy and shared response parser.

Retain the rewrite's lazy sandbox iterator, strict ingress contracts,
transport decorators, lifecycle state policy, and desktop command tests.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36eca628bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/index.ts
Comment thread src/sandbox-lifecycle.ts Outdated
Comment thread src/transport.ts Outdated
Remove explicit pnpm 10 action inputs from CI, contract, and release
workflows. pnpm/action-setup now reads the single authoritative
packageManager declaration from package.json, which pins pnpm 11.17.0
without triggering ERR_PNPM_BAD_PM_VERSION.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
Bundle published declarations into dist/index.d.ts so NodeNext and Node16
consumers do not receive extensionless internal module references.

Keep the create payload name stable while an idempotency key is still
ambiguous, then derive a retry suffix only after Edge returns the created
sandbox identity.

Extend the read-only transport retry decorator to retry thrown network
failures as well as transient HTTP responses, with focused coverage.

Signed-off-by: Aaqa Ishtyaq <aaqaishtyaq@gmail.com>
@aaqaishtyaq
aaqaishtyaq merged commit 17d5eb9 into main Aug 14, 2026
2 checks passed
@aaqaishtyaq
aaqaishtyaq deleted the agent/rewrite-strict-sdk branch August 14, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant