Skip to content

v0.3.0: Project sync into sandboxes, background processes - #2

Open
cooleel wants to merge 8 commits into
mainfrom
sw/new_features
Open

v0.3.0: Project sync into sandboxes, background processes#2
cooleel wants to merge 8 commits into
mainfrom
sw/new_features

Conversation

@cooleel

@cooleel cooleel commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

New features added:

  • Project sync into sandbox
    • Git repos: worktree pushed to a TensorLake-hosted repo and cloned inside the sandbox, with credentials set up so the agent can push changes back.
    • Plain folders: uploaded to a cloud volume and mounted (writes persist durably); skips node_modules and other build junk.
    • Mode auto-detected, overridable via TENSORLAKE_SYNC_MODE=git|volume|off.
    • bash/ls/glob/grep now default to the synced project directory, and the system prompt tells the model where the project lives.
  • Real background processes in the bash tool
    • background=true now uses sandbox.startProcess() and returns a real pid instead of fire-and-forget.
    • New bash_output tool (status + output lines new since last call) and bash_kill tool.
    • Processes stay queryable after exit/kill.
  • Reliability hardening
    • Stale sandbox handles (e.g. sandbox resumed on another host) are detected via typed SDK errors, dropped, and idempotent calls retried once — commands never retry, so nothing runs twice.
    • Re-sync is fast-forward-only, so commits made inside the sandbox are never clobbered.
    • Fixed a sandbox stuck mid-suspension being treated as live, and a latent deadlock in the cached-terminated path.
    • Project re-sync no longer blocks the first tool call when the sandbox already has a project copy — refresh runs in the background.
    • bash_output replay after a plugin restart is capped at 200 lines with stale-pid cleanup.

- Sync the local project into the sandbox: git repos push to a
  Tensorlake-hosted sync repo and clone inside the sandbox (with
  automatic sync-back of agent commits), tl fs mounts attach directly,
  and plain folders upload to a cloud volume
- bash background=true starts a long-running sandbox process; new
  bash_output and bash_kill tools read output and stop it
- Rename TensorLake -> Tensorlake throughout
- Treat 'timeout' sandbox status as terminal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cooleel and others added 7 commits August 23, 2026 10:15
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Re-sync: explicit sync tool plus automatic re-push when local HEAD
  or dirty state changed since the last sync (15 s throttle).
- Uncommitted sandbox work: each idle turn captures the sandbox's
  dirty tree as a WIP commit and stages it locally on
  tensorlake-wip/<branch>; never applied to the user's tree.
- Post-sync setup command: plugin option {"setup": "..."} (env
  TENSORLAKE_SETUP_COMMAND wins), runs once per sandbox lifetime via a
  marker file inside the stateful sandbox.
- Volume-mode sync-back: on idle, one status() call detects changes;
  a contentId-pruned tree walk downloads changed files. Local edits
  are never clobbered (per-file hash guard, conflicts reported),
  remote deletions never delete local files, and uploads pull pending
  agent changes down first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The SDK now derives organization/project scope from the API key at
ingress: introspectApiKey() is gone, explicit scope options are
deprecated, PATs are no longer accepted, and RepositoryClient.url()
became async.

- Drop resolveScope/introspection; cloudOptions() is now synchronous
  and passes only apiKey/apiUrl
- Await all five repos.url() call sites (one was interpolated into the
  sandbox clone script and would have failed only at runtime)
- Stop forwarding TENSORLAKE_ORGANIZATION_ID/PROJECT_ID in client
  options and remove the PAT env-var escape hatch from the project-key
  warning
- Update README: project API keys only, drop the org/project env rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Track exec bits in the volume manifest so exec-only changes sync back,
  and preserve non-exec permission bits when applying them
- Refuse sync-back writes that resolve through symlinks to outside the
  worktree, and keep user-deleted files deleted (report as conflicts)
- Keep skipped-but-present paths tracked so later deletes still propagate
- Fingerprint repos with no commits via a temp-index tree hash so edits
  still trigger re-sync
- Replace only the sync host's line in ~/.git-credentials instead of
  overwriting the whole file
- Detach a stale filesystem before attaching a different one at the same
  mount path, waiting for the guest to unmount
- Await the background refresh sync when the setup command has not yet
  run, so setup always completes before the first tool call

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OpenCode ships a built-in apply_patch tool that edits files on the local
machine. The plugin replaced bash/read/write/edit/ls/glob/grep but not
apply_patch, so an agent could bypass the sandbox and modify the host
project directly. Shadow it by name with a sandbox-side implementation
of the same patch format (*** Begin Patch envelope with Add/Update/
Delete File sections):

- Context hunks match exactly, then ignoring trailing whitespace, then
  ignoring edge whitespace; the file's own context lines are preserved
  so a fuzzy match does not churn whitespace
- All updates are planned (read + hunks applied in memory) before any
  write, so a bad hunk cannot leave earlier files half-applied
- Supports @@ anchors, pure insertions at EOF, and Move to renames;
  relative paths resolve against the sandbox project directory

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cooleel cooleel changed the title v0.2.0: Project sync into sandboxes, background processes, and opencode auth login v0.3.0: Project sync into sandboxes, background processes Aug 24, 2026
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