Skip to content

feat(examples): add Tenki Cloud sandbox TypeScript example - #3476

Open
camcalaquian wants to merge 2 commits into
different-ai:devfrom
camcalaquian:tenki-sandbox-example
Open

feat(examples): add Tenki Cloud sandbox TypeScript example#3476
camcalaquian wants to merge 2 commits into
different-ai:devfrom
camcalaquian:tenki-sandbox-example

Conversation

@camcalaquian

Copy link
Copy Markdown

What

Adds examples/tenki-openwork-ts: a small standalone TypeScript example that boots the headless OpenWork server inside a Tenki Cloud sandbox using the @tenkicloud/sandbox SDK, exposes it on a public preview URL, and verifies it end to end.

It mirrors the smoke flow of examples/microsandbox-openwork-rust:

  1. Create an ephemeral sandbox (2 vCPU / 4 GB / 10 GB).
  2. Install the published openwork-server npm package (compiled Linux binary — no in-sandbox build) and the OpenCode release pinned in the repo-root constants.json (v1.17.11).
  3. Start the server with OPENWORK_MANAGE_OPENCODE=1, same contract as packaging/docker/microsandbox-entrypoint.sh.
  4. Expose port 8787 via a Tenki preview URL and verify from outside the sandbox: /health, unauthenticated /workspaces → 401, authenticated → 200, POST /w/:id/opencode/session, session + message reads.
  5. Print startup timings, then terminate the sandbox.

OPENWORK_TENKI_KEEP_ALIVE=1 keeps it running for the desktop app's Add a worker → Connect remote flow; Ctrl+C terminates the sandbox.

Sandbox lifecycle

Ephemeral by default. Termination is guaranteed via a memoized shutdown shared by finally and SIGINT/SIGTERM handlers (installed before sandbox creation), with maxDurationMs/idleTimeoutMinutes backstops if the process is killed outright. Verified after all test runs below by listing sessions by tag: 6 sessions total, 0 alive (including failed and interrupted runs).

Tests run

  • pnpm typecheck — clean (strict, no any/as).
  • pnpm start e2e against real Tenki sandboxes — 3 clean runs, all checks passed. Representative run: sandbox ready 2043 ms, provisioning 7000 ms, server ready 3385 ms, total 23133 ms (server ready = server spawn → /health 200 through the public preview URL; total includes the ~9 s first POST .../opencode/session).
  • Keep-alive run: reached steady state, SIGINT → exit 130, sandbox terminated.
  • SIGINT 1 s in (during sandbox creation): exit 130, sandbox terminated.

The branch also went through an adversarial review pass before submission (second commit): a provisioning deadline enforced locally (the Tenki SDK's declared ExecOptions.timeoutMs is a no-op in 0.5.4 — reported to Tenki as a bug), fail-fast when the server process exits early instead of hanging on health polls, signal handlers installed before sandbox creation, UTF-8-safe log line buffering, port validation, and a documented OPENWORK_APPROVAL_MODE=auto trust model in the README.

Testkit evidence tape: not applicable — this is a standalone example outside the pnpm workspace (like the Rust microsandbox example); it does not touch app/server runtime code. The example itself is the executable end-to-end check; validation needs a TENKI_API_KEY, so it cannot run in CI. Repro steps are in the example README.

Note: packaging bug found while testing

openwork-server@0.18.13 on npm ships dist/bin/openwork-server without the executable bit, so the bin/openwork-server.mjs wrapper fails with EACCES on Linux after a plain npm install — the README quick start (npm install -g openwork-server && openwork-server ...) hits this too. The example works around it with a chmod +x after install (commented in the provision script). Happy to file/fix separately — likely a publish-pipeline fix (chmod before npm publish or an install script).

Boot the headless OpenWork server inside a Tenki sandbox with the
@tenkicloud/sandbox SDK, expose it on a public preview URL, and run the
same smoke checks as the microsandbox Rust example (health, 401/200
token auth, OpenCode session create/read). Ephemeral by default with
guaranteed termination on success, failure, and Ctrl+C; optional
keep-alive mode for connecting the desktop app via Connect remote.
- Enforce the provisioning deadline locally: @tenkicloud/sandbox 0.5.4
  declares ExecOptions.timeoutMs but does not apply it.
- Fail fast (instead of hanging) when the server process exits early,
  including during keep-alive.
- Install signal handlers before sandbox creation and terminate the
  live session carried by WaitReadyFailedError.
- Memoize shutdown so signal handlers and finally cannot double-terminate.
- Buffer partial log lines and decode UTF-8 across chunk boundaries.
- Validate OPENWORK_PORT; drop the misleading arm64 branch (the npm
  package ships a single x86_64 binary); document the auto-approval
  trust model in the README.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@camcalaquian is attempting to deploy a commit to the Different AI Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-landing Ready Ready Preview, v0 Aug 3, 2026 7:48pm

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