Skip to content

Feat/k8s sandbox#3171

Draft
pedrofrxncx wants to merge 3 commits intomainfrom
feat/k8s-sandbox
Draft

Feat/k8s sandbox#3171
pedrofrxncx wants to merge 3 commits intomainfrom
feat/k8s-sandbox

Conversation

@pedrofrxncx
Copy link
Copy Markdown
Collaborator

@pedrofrxncx pedrofrxncx commented Apr 24, 2026

What is this contribution about?

Describe your changes and why they're needed.

Screenshots/Demonstration

Add screenshots or a Loom video if your changes affect the UI.

How to Test

Provide step-by-step instructions for reviewers to test your changes:

  1. Step one
  2. Step two
  3. Expected outcome

Migration Notes

If this PR requires database migrations, configuration changes, or other setup steps, document them here. Remove this section if not applicable.

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working
  • Documentation is updated (if needed)
  • No breaking changes

Summary by cubic

Adds a Kubernetes sandbox runner and moves repo bootstrap to run in the background with live setup logs. Mesh/SDK accept runnerKind: "kubernetes"; the daemon adds a per-boot bootId, and the image bumps to Bun 1.3.11.

  • New Features

    • Kubernetes runner: KubernetesSandboxRunner in mesh-plugin-user-sandbox/runner/k8s (opt in with MESH_SANDBOX_RUNNER=kubernetes). Uses per-claim DAEMON_TOKEN, Bun-native TLS fetch with kubeconfig creds, readiness watch, and deterministic local port-forward; supports previewUrlPattern for ingress-based previews, and refreshes claim TTL via shutdownTime. Rehydrates state and forces re-bootstrap if bootId changes. Added @kubernetes/client-node, loaded only when this runner is used.
    • Bootstrap/logs: run repo bootstrap in the background for Docker and Kubernetes; persist the handle before clone so /api/sandbox/<handle> resolves immediately; stream setup logs via logSource: "setup" over the daemon’s SSE ring.
    • Mesh app/SDK: widened runnerKind to include "kubernetes" across API, tools, UI, and VmMapEntry; sandbox proxy now accepts "kubernetes". Mesh dynamically imports mesh-plugin-user-sandbox/runner/k8s only when selected.
    • Daemon/image: /health returns bootId; /bash accepts logSource and streams output; log splitting handles CR/LF; dev server sets CI=1 to avoid TTY prompts; Bun upgraded to 1.3.11.
  • Migration

    • Default remains Docker; no changes required.
    • To try k8s locally: run deploy/k8s-sandbox/local/up.sh, set MESH_SANDBOX_RUNNER=kubernetes, start Mesh. Use reload-image.sh to iterate and smoke.ts to verify. Tear down with down.sh.

Written for commit 4c63497. Summary will update on new commits.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

Release Options

Suggested: Patch (2.275.2) — default (no conventional commit prefix detected)

React with an emoji to override the release type:

Reaction Type Next Version
👍 Prerelease 2.275.2-alpha.1
🎉 Patch 2.275.2
❤️ Minor 2.276.0
🚀 Major 3.0.0

Current version: 2.275.1

Note: If multiple reactions exist, the smallest bump wins. If no reactions, the suggested bump is used (default: patch).

@github-actions
Copy link
Copy Markdown
Contributor

🧪 Benchmark

Should we run the Virtual MCP strategy benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

New Kubernetes runner lives at mesh-plugin-user-sandbox/runner/k8s and sits
behind its own subpath export so docker/freestyle deploys never pull in
@kubernetes/client-node. Opt in with MESH_SANDBOX_RUNNER=kubernetes; docker
stays the dev default.

Image side: bumps Bun to 1.3.11 so the daemon can read modern bun.lock
(configVersion: 1), and adds a per-boot BOOT_ID to /health so the runner can
detect container restarts (OOMKill, eviction) and re-bootstrap the workdir
instead of stranding a live pod with an empty /app.
- Bumped version of decocms to 2.274.0.
- Updated various dependencies including @ai-sdk/anthropic, @ai-sdk/gateway, @ai-sdk/google, @ai-sdk/openai, and @ai-sdk/provider-utils to their latest versions.
- Added new entries for @anthropic-ai/claude-agent-sdk and its platform-specific variants.
@tlgimenes
Copy link
Copy Markdown
Contributor

Heads up — PR #3178 lands a unified daemon codebase at packages/sandbox/daemon/ shared by freestyle and docker, shipped as a single daemon/dist/daemon.js bundle. Once it merges, your K8s runner can COPY (or mount) the same bundle instead of duplicating image/daemon.mjs.

The unified daemon already exposes /health with bootId for restart detection, so your runner can drop that bit and consume it from the shared surface. Paths are /_decopilot_vm/* with base64-wrapped bodies everywhere.

Happy to pair on the rebase when #3178 is in — should be small for the k8s side since the daemon contract is the same across runners.

VM_START used to block until clone+install finished (~30s on medium
repos). The Terminal tab opens its SSE connection only after VM_START
returns, so users saw the entire setup output dumped at once via
`replayTo` instead of streaming live.

Run repo bootstrap in the background (Docker + K8s runners) and persist
the handle BEFORE bootstrap so /api/sandbox/<handle> resolves while clone
is still running. Bootstrap output streams through the daemon's log ring
under a `setup` source so the Terminal tab can subscribe via SSE.

Daemon side: split bash output on any CR/LF run so git's progress
reports surface as distinct log lines instead of accumulating until the
trailing newline. Set CI=1 in dev-process env so Vite's interactive
shortcut reader doesn't EOF and exit when stdio is ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants