Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

99 lines · 8.8 KBRaw History

title: Terminals description: Open a shell in a sandbox with your repository checked out, right in the browser, and work there with Claude Code or Codex signed in to your own subscription.

A terminal is a sandbox with a repository checked out, in your browser. You type into a real shell, and you can start Claude Code or Codex there and sign in with your own Claude or ChatGPT plan, instead of an API key. Whatever you push from it is pushed as one of your agents, so its pull requests need a person's approval like any agent's.

Terminals are optional. Nothing changes for a repository until someone opens one.

Before you start

You need:

  1. Write access to the repository.
  2. An agent you manage, with write access to the repository, as for tasks.
  3. A browser session. Terminals open only from a signed-in browser. Tokens, the REST API and MCP can't open one or connect to one.

Open a terminal

  1. Open the repository's Project tab and click Terminals (the Agent tasks page has the same button), or go to /<owner>/<repo>/terminals.
  2. Pick the agent and the branch.
  3. The first time, tick the notice: you use Claude Code and Codex with your own Anthropic or OpenAI account, under that provider's terms, and usage is billed to your account. Diffinery records when you accepted it and which version of the notice it was. When the notice changes, you're asked again. It also says what a task in your terminal can reach (see Give it a task).
  4. Click Open a terminal.

The page shows Starting while the sandbox starts, then the terminal. Reloading the page, or opening it in another tab, connects to the same shell and redraws its recent output. Only one tab is connected at a time: the newest one wins, and the older tab says so.

Signing in

The toolbar has buttons that type a command for you:

ButtonWhat it runs
Start Claude CodeInstalls Claude Code at the version Diffinery pins for tasks if it isn't installed, then starts it. Type /login, choose your Claude subscription, open the link it shows, sign in with Anthropic and paste the code back. You can use an API key instead: export ANTHROPIC_API_KEY=… before starting it.
Start CodexInstalls Codex the same way, runs codex login --device-auth if you aren't signed in, then starts it. Open the link it shows, sign in with OpenAI and enter the code. A ChatGPT workspace admin may have to allow device codes. Offered on private repositories only, because OpenAI allows signing in with a ChatGPT plan only there; on a public repository you can still use an OpenAI API key.

The sign-in happens in the provider's own flow and stays in that sandbox. Diffinery never sees or keeps it, and it's gone when the terminal ends. The providers' terms: Anthropic's Consumer Terms, Claude Code's legal and compliance page and OpenAI's Terms of Use.

Give it a task

Your terminal can run agent tasks with the Claude Code or Codex you signed in to there, on your own subscription, with no API key.

  • Start one from the terminal. Under the terminal, Give it a task takes a goal and Runs with Claude Code or Codex (Codex on private repositories only). Click Run with my subscription. The task's page opens and shows the transcript as it runs.
  • Run a task again in it. On a task you started, with the same agent as an open terminal of yours, Run in my terminal runs it again there, and Send to my terminal sends your follow-up there.

What happens:

StepWhat Diffinery does
CheckChecks again, on each click, that the terminal is yours, open and acting as the task's agent, that you accepted the notice, and that you and the agent may still write to the repository.
CheckoutChecks out the task's branch (or the terminal's branch, for a new task) in a directory of its own beside yours, so your checkout and anything you're doing in it are left alone.
RunRuns the CLI headless with the goal, as a task run does, with no model key or token: it uses the account you signed in to in the terminal. If it isn't installed yet, Diffinery installs the pinned version first.
PushPushes the work to the task's branch as the agent and opens a pull request, as for any task. Then it removes the task's directory.

Only your own click starts a run in your terminal. Nothing else does: not a coordinator, a schedule, a retry, Best of N or a failing check. A task whose last run was in a terminal doesn't start a fix run when its checks fail; run it again yourself. A terminal runs one task at a time, it counts as attached while it does (so it doesn't end for being idle), and ending the terminal stops the task. Tasks that plan first or have more than one attempt run in sandboxes of their own.

The task's transcript is kept, as for any task: it is the CLI's output for that run, not what you type in the terminal.

Give it tasks only in repositories whose contents you trust. A task runs the agent without asking before each step, in your terminal, where your sign-in is. Anything in the repository the agent reads (a CLAUDE.md, a file, an issue the goal quotes) can steer it, for example into reading your sign-in and sending it somewhere. A task in its own sandbox can't do that: it holds only a token for that run. The notice says this too.

Who can reach it

  • Only you. Nobody else sees your terminal or connects to it: not a repository admin, not the repository's owner, not a site administrator. The terminal may hold your provider sign-in.
  • Only from a browser on this Diffinery. The connection must come from a page on the instance's own address with your session cookie. A request without that Origin, from another site, or with a token is refused.
  • Not through the sandbox API. A terminal's sandbox isn't listed by the sandbox API or MCP tools, and they can't run commands in it, read its files or close it, whoever asks.

What the sandbox can do

  • Git in the sandbox acts as the agent you picked, at most with write access to this one repository. The credential stops working when the terminal ends, and it's checked again every minute: if you or the agent lose write access, the terminal ends.
  • Your provider sign-in and anything else you type into the shell can be read by any process in the sandbox, including the sandbox's own server and its credentials, which reach only this sandbox. Don't paste secrets you wouldn't keep on that machine.
  • The sandbox has outbound internet access, as other sandboxes do (only HTTP and HTTPS on instances that set EGRESS=web).

When it ends

A terminal ends, and its sandbox stops with everything on its disk, when:

ReasonWhat the page says
You click EndYou ended it.
No tab was connected for 30 minutesNobody was attached for 30 minutes.
It ran for 8 hoursIt reached the 8-hour limit.
You or the agent lost write accessYou or the agent no longer have write access here.
The sandbox stopped or didn't startIts sandbox stopped. / Its sandbox didn't start.
An administrator switched terminals offTerminals were switched off on this Diffinery.

Push your work before it ends: nothing in the sandbox is kept. Exiting the shell starts a new one in the same sandbox.

Limits

You can have 2 terminals open in a repository and 5 in all. Opening another one is refused with 429 until you end one.

A terminal's sandbox counts toward the account quotas of the account that owns the repository, like any agent sandbox: its sandboxes open at once and its hosted minutes for the month. Past either, opening a terminal is refused with 429 and the quota's message.

Nothing is stored

What you type and what the shell prints go only between your browser and the sandbox. Diffinery keeps no copy and doesn't log it: the recent output that redraws the screen lives in the sandbox's memory and is gone when the terminal ends. The audit log records only that a terminal was opened or ended, by whom, in which repository, with which agent and branch and the Claude Code and Codex versions its buttons install, and that you accepted the notice (terminal.terms, terminal.open, terminal.task, terminal.end).

For administrators

Terminals are on by default. Set the Worker variable TERMINALS to off to switch them off: nobody can open one, and the ones that are open end within a minute. See Configuration.