Clones a Git repository into a sandbox, reads files, and proposes a patch. Exercises the primitives the personal-assistant sample does not touch:
Sandbox— every file and command goes through the SPI. Docker is the production default; the in-process provider is the dev fallback.AgentResumeHandle— a long-running clone + patch flow registers with theRunRegistryso a disconnected client can reattach byrunIdand replay missed events (wire-in lands in Phase 1.5).
# Build
./mvnw compile -pl samples/spring-boot-coding-agent
# Run with an OpenAI key (optional — sample works without)
export OPENAI_API_KEY=sk-your-key
# Start the sample
./mvnw spring-boot:run -pl samples/spring-boot-coding-agent
# Open http://localhost:8081 and ask:
# "clone https://github.com/atmosphere/atmosphere.git and read README.md"The sample prefers the Docker sandbox backend. If docker is on PATH and
the daemon is reachable, operations run inside a fresh alpine:3.20
container with 1 CPU / 512 MB / 5 min / no network beyond the initial
clone.
When Docker is absent, the sample falls back to the in-process provider for demonstration purposes only. The in-process provider is NOT a security boundary — never expose the in-process backend to untrusted input in production.
- Extracts the repo URL from the user message.
- Provisions a sandbox with default limits.
- Clones the repository at depth 1.
- Reads
README.md(orREADME) and returns the first 800 characters.
Extending to real patch proposals is left to the reader — the @SandboxTool
annotation wires a method to a sandbox backend, and Sandbox.writeFile +
Sandbox.exec(List.of("git", "diff", ...)) produce the diff.
- The sample does not
git committhe proposed patch. A production coding agent pairs this flow withPermissionMode.PLANfrom theAgentIdentityprimitive so the user approves before the commit lands. - Egress policy extension (per v0.6 follow-up): swap
SandboxLimits.networkfrom boolean toNetworkPolicy(NONE/GIT_ONLY/ALLOWLIST) so the clone step can reach GitHub while downstream tool calls cannot reach the wider internet.