# Give a sandboxed Claude or Codex agent a GitHub repository to work in

> Agno's ClaudeAgent and CodexAgent take repository=Repository(url, branch="main") next to sandbox=, pin the branch's commit on a session's first turn and carry the engineer's edits from turn to turn.

- Published: 2026-10-19
- Author: Ashpreet Bedi
- Categories: Changelog
- Canonical: https://www.agno.com/blog/give-a-sandboxed-claude-or-codex-agent-a-github-repository-to-work-in
- Markdown: https://www.agno.com/blog/give-a-sandboxed-claude-or-codex-agent-a-github-repository-to-work-in.md

Agno's `ClaudeAgent` and `CodexAgent` accept `repository=Repository(url, branch="main")` beside `sandbox=`, and on a session's first turn the sandbox resolves that branch to one commit, fetches it with `--depth=1` and starts the harness in `/workspace/repository`. Every committed run then reports the pin at `metadata.sandbox.repository` as its url, branch and commit.

```python
import os

from agno.agents.codex import CodexAgent
from agno.db.postgres import PostgresDb
from agno.sandbox import Repository
from agno.sandbox.checkpoint import FileCheckpointStore
from agno.sandbox.docker import DockerSandbox

engineer = CodexAgent(
    id="product-engineer",
    db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
    sandbox=DockerSandbox(
        image="agno-sandbox:local",
        network="isolated",  # the computer needs egress to reach GitHub
        checkpoints=FileCheckpointStore("/srv/agno/checkpoints"),
        env={"GITHUB_READ_TOKEN": os.environ["GITHUB_READ_TOKEN"]},  # private repositories only
    ),
    repository=Repository(url="https://github.com/acme/app", branch="main"),
    sandbox_mode="workspace-write",
)

result = engineer.run("Run the test suite and report what fails", session_id="upgrade-1")
print(result.metadata["sandbox"]["repository"])  # url, branch and the commit turn 1 pinned
```

Later turns read the pin back from `native/repository.json` and skip the fetch, so new pushes to the branch leave a running session where it started. The engineer's commits and uncommitted files travel in each turn's checkpoint, which covers both a warm resume and a restore into a new computer.

We ran a `FixtureAgent` with the same `repository=` on a real `DockerSandbox` and Postgres, with the fixture runtime standing in for the model, against the public octocat/Hello-World repository. Turn 1 pinned master at `7fd1a60`. A shell command in the warm computer, playing the engineer, appended a line to README. Turn 2 resumed that computer. We then removed the container, and turn 3 came up on a new one restored from turn 2's checkpoint, with HEAD still at `7fd1a60` and `git status` still showing `M README`.

![One session on DockerSandbox with Repository pointing at octocat/Hello-World and the fixture runtime standing in for the model, real output. Every turn reports sandbox.repository as branch master, commit 7fd1a60b01f91b314f59955a4e4d4e80d8edf11d. Turn 1 runs on a new computer with master pinned and checked out, resumed False, HEAD 7fd1a60, git status clean. README is then edited in the warm computer. Turn 2 resumes turn 1's computer, resumed True, HEAD 7fd1a60, git status M README. The container is then destroyed. Turn 3 runs on a new computer restored from turn 2's checkpoint, resumed False, HEAD 7fd1a60, git status M README.](https://www.agno.com/images/v3-1-5-repository-pinned-workspace.png)

Private repositories authenticate with `GITHUB_READ_TOKEN` from the sandbox environment. Git receives it only through the child process environment, with prompts, redirects, credential helpers and hooks turned off. An agent with a repository refuses `GITHUB_TOKEN` with `Sandbox repository access requires GITHUB_READ_TOKEN; remove GITHUB_TOKEN`. On the first turn, run metadata can also choose the starting point with `{"repository": {"commit": "<40-hex sha>"}}` or `{"repository": {"branch": "release"}}`, and later turns ignore it once the pin exists.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/repository_workspace.py), and learn more about [working files for harness agents](https://docs.agno.com/agent-os/multi-framework/sessions#working-files-are-separate) in the documentation.
