@dongkseo/sandbox-remote
v0.2.2
Published
Readme
@dongkseo/sandbox-remote
Stability: experimental · pnpm add @dongkseo/sandbox-remote
원격/클라우드 sandbox에 붙는
SandboxClient. 로컬 sandbox 클라이언트를 이걸로 교체만 하면 에이전트·도구 코드를 바꾸지 않고 워크스페이스 경계를 provider-관리 호스트로 옮긴다(포터빌리티 축).
무엇인가 / 무엇이 아닌가
- ✅ 담는 것:
RemoteSandboxClient— Nexora sandbox wire 프로토콜(@dongkseo/sandbox-server)로 원격 세션을 프로비저닝하고, 원격 exec·워크스페이스 persist/hydrate·살아있는 세션 reattach를 수행.SandboxClient+WorkspaceProvider양쪽을 구현하며resume(SandboxSessionState)를 제공 →ContinuousWorkspaceProvider에 그대로 주입 가능. - ❌ 안 담는 것: OS 격리 그 자체(서버가 자기 backend로 강제한다). 상용 provider 어댑터(Cloudflare/Modal 등 — 후속).
원격 세션은 서버가 격리하므로 wrapCommand를 의도적으로 구현하지 않는다(로컬에서 감쌀 jail이 없음). detached/background
실행이 필요하면 호스트에서 비격리 spawn으로 폴백하지 말고 서버측 task로 라우팅해야 한다. 이 규칙은 이제 문서가 아니라
@dongkseo/tools의 exec 툴이 강제한다 — run은 있는데 wrapCommand가 없는 세션에서 run_in_background는 거부된다.
핵심 개념
- create →
POST /sessions(manifest seed) → 원격 세션. - run →
POST /sessions/:id/exec→ 버퍼링된SandboxCommandResult(기존 seam과 동일). - 파일 I/O →
WorkspaceSession.fs(WorkspaceFs: read/write/stat/readdir/realPath)를 wire(GET·PUT /fs,GET /stat,GET /readdir)로 구현. root-jail 재검증은 서버가 강제(탈출은 403). - snapshot / sessionState →
POST /persist로 tar를 받아 로컬에 스풀 →SandboxSessionState{ backend:'remote', ref:<원격 세션 id>, snapshot }. - resume →
ref가 살아있으면POST /reattach로 재접속(HOT), 아니면 새 세션 +POST /hydrate로 재수화(COLD). - 자격증명(토큰)은 옵션/헤더에만 존재하며
SandboxSessionState·로그·에러에 절대 실리지 않는다.
원격-root 파일 I/O는 완결됐다: 빌트인 파일 도구(read/write/edit)가 로컬
node:fs가 아니라ctx.workspace.fs(WorkspaceFsseam)를 통과하도록 리팩터됐고(@dongkseo/tools),RemoteSandboxClient가 그 seam을 위 wire 라우트로 구현한다. detached/background 실행만은 호스트 비격리 spawn으로 폴백하지 말고 서버측 task로 라우팅한다(위 참고).
사용 레시피
import { RemoteSandboxClient } from '@dongkseo/sandbox-remote';
import { ContinuousWorkspaceProvider } from '@dongkseo/core';
import { AgentRunner } from '@dongkseo/core';
const remote = new RemoteSandboxClient({ endpoint: 'https://sbx.example.com', token: process.env.SBX_TOKEN });
// 대화 연속성까지: 원격 세션 재접속/재수화를 conversationId 기준으로.
const provider = new ContinuousWorkspaceProvider(remote, workspaceStateStore, conversationId);
const runner = new AgentRunner({ /* … */, workspaceProvider: provider });로컬↔원격 교체는 workspaceProvider 한 줄뿐 — 나머지는 동일.
API 표면 (소스 안 열고 타입만)
ctx_read(path="packages/sandbox-remote/src/index.ts", mode="map")
ctx_read(path="packages/sandbox-remote/src/client.ts", mode="signatures")유지보수 (drift 방지)
- API 정본은 소스 TSDoc. wire DTO 정본은
@dongkseo/contracts의sandbox-protocol.ts. - 프로토콜을 바꾸면
@dongkseo/sandbox-server와 동시에 갱신하고 통합 테스트로 고정.
Tests
cd packages/sandbox-remote && pnpm test # 서버를 띄워 end-to-end 포터빌리티 검증Part of the Nexora multi-tenant agent framework. · Package map
