Skip to content

Product

Direct the work. See it land.

One session the team types into, a box the agent works in, and the previews, docs, media and merge queue it writes to.

01Direct it

One shared session. Chat, terminal, or phone.

One agent session per workspace, the whole team in it. @agent from the web, the desktop app or your phone.

  • Say what you want in the chat, the terminal or from your phone. The message reaches the same session either way, and the agent picks it up immediately.
  • Terminal is the live pane. Conversation is the same session parsed into messages, easier to read back and what the phone shows.
  • A browser-based VS Code with every repo cloned on the workspace's branch, the same container for everyone. The session sits beside it; Pop out gives it the whole window.
upload-rate-limit Agent working
  1. M
    Maya09:41
    @agent rate-limit /api/upload, 20 a minute per user, answer 429 with Retry-After.
  2. A
@agentType here from the web, the desktop app or your phone.
02Track it

How far the work has physically reached.

Columns are your organization's own stages, not a fixed set, and dragging a card between them is how a workspace's state changes.

  • Every card shows its tasks, its deadline, whether an agent is working in it, and how far the work has reached: preview, test, staging, production.
  • Three views: Board is the kanban, Cards is the denser list, Calendar is workspaces against their deadlines.
  • Only workspaces in the active column may keep a container running.
Backlog2
Invoice PDF export
0/4
0%
Q3 performance review
0/0Info only
In progress3default
upload-rate-limit@14
4/5Working
80%
Onboarding emails
2/6 2 days
33%
Mobile push channels
0/3
0%
Review1
Media share-link audit2
7/7 1 day late
100%
Completed4
Release 2.14.0
5/5
Fix flaky upload test
1/1
Backup to S3 nightly
3/3
Inbox3 unread, pushed to your phone
  • Jonas mentioned you in upload-rate-limit09:50
  • Agent finished Onboarding emails, step 2 of 609:12
  • Nightly backup run was silent03:00
03Build it

What an agent has in its box.

A container with the repos, the CLI, and a git that enforces your rules.

  • git in the box pushes the workspace's own branch and refuses your protected branches. The push relay on the server refuses them again.
  • Tools run with named credentials. The key is in an encrypted profile, never in the prompt.
  • A preview it can bring up itself: the whole repo set as containers on DevBench compute.
upload-rate-limit, the agent's boxinside the box
agent › 
04See it

See it before you merge.

Every branch gets a live preview as containers, a test run with its log, and a recorded video of the change working. They land on the task where the work was asked for, not in a link somebody has to open.

  • Agents do not just flip a task to done; they leave a note saying how.
  • Nobody operates the recorder and there is no editing pass. An agent writes a take, and the video falls out of running it.
  • What was done and how it was done are in the same place, and neither is in someone's memory.
Rate-limit /api/upload, 20 a minute per user
done #12 due Sep 14 Maya
  • Agenttodo → in progressSep 12, 09:41

    Reading the upload view and settings. Adding a per-user token bucket in throttle.py.

  • AgentSep 12, 09:45

    Tests: pytest backend/api -q, 42 passed in 3.1s. Preview is up on this branch.

  • AgentSep 12, 09:47

    Recorded the change working.

    settings / api
    Upload
    Filereport-q3.pdf
    Folder/reports
    Upload Uploaded report-q3.pdf
    Uploads this minute8 / 20
    Every user gets 20 uploads a minute.
    0:12 / 0:38
  • Agentin progress → doneSep 12, 09:48

    Opened !184, project/upload-rate-limit → develop. Needs a person to merge.

  • mayaSep 12, 09:52

    Watched it, clicked through the preview. Merging.

Add a note…Status: done ▾Add note
05Merge it

A person is always in charge.

The agent opens the merge request. Only a person can press Merge, and the rule holds for every caller, not just the button.

  • Every commit is authored as the person who asked for it.
  • Promotion follows your git flow left to right, and a release cuts one version across every repo.
  • Undoing a merge comes back as a merge request, so it goes through the same read as making one.
Merge requestsWaiting: 2develop → staging → main
  • WaitingRate-limit /api/upload (20/min per user)!184 project/upload-rate-limit → developMerge
  • WaitingPromote develop → staging!183 develop → stagingMerge
  • MergedFix flaky media upload test!181 project/media-flake → develop, by maya
  • MergedRelease 2.14.0release/2.14.0 → main, 3 repos, by jonas
Release 2.14.0shippedgate → cut → ship → tag
  • devbench/backendv2.14.0
  • devbench/frontendv2.14.0
  • devbench/mobilev2.14.0

One version across every repo, tagged by jonas.

A real chat, not a log.

Every workspace has one conversation, shared by the web app, the desktop app and the phone. Agents post into it, people reply, and a reply that asks for something is acted on in the same request that stored it.

No webhook, no polling loop, no wait for a channel to exist. @agent hands the message to this workspace's agent, /restart restarts its box, and an answer to a question the agent asked is routed back to it. A pending question shows up as a card with the options to tap, on the phone as well as on the web.

devbenchinside the box
  • $ devbench notify "<message>"

    Post to the workspace chat and the team Inbox from inside the box.

  • $ devbench notify "<message>" --video <url>

    Post with a video that plays inline in the thread.

  • $ devbench ask_question '<json>'

    Ask the team a question. They answer in the chat or the terminal panel.

  • Replies quote

    Reply to a message and the quote travels with yours, so the answer is readable without scrolling.

  • Mentions push

    @ a teammate and they get an Inbox notification and a push to their phone.

  • Permalinks and search

    Every message has a link you can point somebody at, and search runs over the whole thread.

  • Attachments play inline

    Images and video play in the thread. Anything else arrives as a file.

  • Relays

    How many recent messages go to the agent along with your request. Set per conversation.

  • Live, or honestly not

    Served over WebSockets. If the socket cannot connect the client polls and says Polling in the header, so a stalled thread never passes for a quiet one.

  • Mute is yours

    Mute silences your @mention notifications for this thread and nobody else's. Whether a workspace reaches your phone at all is a separate switch, in the mobile app.

  • Interrupting is the point

    @agent interrupts the workspace's live session. A teammate mid-flow in the terminal will notice, which is usually what you want.

A workspace

A branch across a set of repositories, plus a box to work in.

Creating one asks four questions. Everything after the first is optional: a name and a list of repos still gets you a workspace.

  1. 1

    Workspace

    The name, the description, an optional deadline, and whether the workspace may change code at all. The description is saved as REQUIREMENTS.md in the box and kept in sync with it, so the agent reads the same brief you wrote.

  2. 2

    Repositories

    Pick an App and its repos come with it. Narrowing to one is worth doing when the work only touches one, because the agent reads what is in the workspace.

  3. 3

    Branching

    The branch every repo's working branch is cut from, and this workspace's own promotion chain, ending at production. It starts from your organization's git flow, so most workspaces leave it alone.

  4. 4

    Environments

    Where each of those branches runs, one row per branch. Only shown to people who can manage deployments. A step you may not answer is not a step.

  • Info only, fixed at creation

    For work that reads code and never changes it: an audit, a performance review, an investigation. The repos are still cloned so the agent can read them, and every path by which code could leave is closed.

    No working branch is created, git push is refused in the box and again on the server, and merge requests cannot be opened or landed. The deliverable is a document, not a diff. It cannot be undone afterwards, because it is a promise the product makes about that workspace.

  • Provisioning happens in the background

    Creating the workspace returns immediately. A volume is made, every repo is cloned onto the shared branch in one shot, then the editor container comes up. The Inbox tells you when it is ready to open.

    Everyone in the organization opens the same container: two people opening the workspace are in one editor and one terminal, not two copies.

  • Stopping is safe and reversible

    The volume and every file on it survive a stop; opening the workspace starts it again where it was. A workspace outside the board's active column has no reason to hold memory, so once it has been quiet for half an hour it is stopped, unless Keep this box running is set on it.

    Every automatic stop is written to the workspace's Activity tab, so “why did my box stop?” has an answer.

devbenchon your machine
  • $ devbench create -n "Name" -r <repo-id>

    Create a workspace from your own machine.

  • $ devbench setup <id>

    Clone a workspace locally, on its branch, in an empty folder.

  • $ devbench list

    Your workspaces.

Not an editor plugin.

A container with the repos, the CLI, a git that enforces your rules, tools with named credentials, and a preview it can bring up itself.

  • A git that knows the rules

    git in the box is DevBench's shim. It pushes the workspace's own branch and refuses your protected branches. The push relay on the server refuses them again, so a box that got around the shim still cannot reach the provider.

    agent › git push origin main
    refused: main is protected. Reach it through a merge request.
    
  • Commits authored as the person who asked

    The shim sets the author from whoever's message reached the agent. DevBench stays the committer and is the one co-author; trailers the agent adds are removed.

    agent › git commit -am "Rate-limit /api/upload (20/min per user)"
    [project/upload-rate-limit a41c9e] Rate-limit /api/upload
    Author: Maya <maya@…> Co-authored-by: DevBench
    
  • The devbench CLI

    devbench mr create, devbench video record, devbench doc create, devbench deploy. The same commands you run on your machine, so what the agent did is on the task.

  • Tools with named credentials

    devbench tools run stripe --env test. The key is in an encrypted profile, never in the prompt, never returned by the API.

  • A preview it can bring up itself

    The whole repo set as containers on DevBench compute. An agent may deploy a preview and never an environment.

The board says where everything is.

Columns are your organization's own stages, not a fixed set, and dragging a card between them is how a workspace's state changes. Every card shows its tasks, its deadline, whether an agent is working in it, and how far the work has physically reached: preview, test, staging, production.

  • Three views

    Board is the kanban, grouped by Stage or by Task Status. Cards is the denser list, for detail rather than position. Calendar is workspaces against their deadlines.

  • The active column has a rule

    Only workspaces in it may keep a container running. The column you mark as default is that statement; there is no second setting to keep in step, and renaming it is fine.

  • Who sees what

    Owners and maintainers see every workspace. Members see the ones they are assigned to, plus any they created. A maintainer can hide workspaces from their own board; that choice is per person and cannot widen access.

  • One person at a time

    The people row above the board filters to one person's workspaces. Everyone puts them all back. Search finds a workspace by name on a board of a few hundred cards; Archived holds the ones taken off it.

What was asked, its state, and how it was done.

A task is one piece of work in a workspace: a title, a description, a status, a due date, an assignee and a parent. Subtasks under one heading are a real structure, not a convention.

The part worth knowing about is the note timeline. Agents do not just flip a task to done; they leave a note saying how, and notes carry attachments: a document, a shared file, a link, or a recorded video of the change working. A video attached to a note plays in the timeline rather than arriving as a link somebody has to decide to open.

That is what makes the board readable weeks later. What was done and how it was done are in the same place, and neither is in someone's memory. Recheck against implementation has the agent compare the board with what is actually built.

Tasks for you

The workspace board is work for the agents. Tasks for you is the other list: things a person has to decide, approve, unblock or go and look at. A scheduled run that finds something needing a human puts an item here, and it stays until somebody closes it. It is a guarded channel, because an unguarded one turns into the chat it replaced.

  • Each item's body is capped. The detail goes in a document, linked from the item.
  • The same automation asking for the same thing twice re-surfaces the existing item instead of adding a row.
  • One automation may hold only so many open items before it is told to consolidate.
devbenchinside the box
  • $ devbench task add "<title>"

    Add a task from inside the workspace's box.

  • $ devbench task show <id>

    One task in full, with its note timeline.

  • $ devbench task note <id> "text" --video <url>

    Add context, or a recorded demo, without changing the task.

  • $ devbench task done <id> --note "how"

    Close it, recording how it was done.

  • $ devbench todo "<list>" <item>…

    A parent task with subtasks under it, in one command.

Recorded demos

A green test says the code does not break. A video says what it does.

Every workspace box carries devbench video. It drives the deployed app with a real browser, draws a cursor and a highlight ring, records the session, and burns a camera move and captions into an MP4.

Nobody operates it and there is no editing pass. An agent writes a take, and the video falls out of running it.

devbench/takes/upload-rate-limit.pya take, committed next to the feature
def take(t):
    t.goto("/settings/uploads")
    t.mark_ready()                      # everything before this is trimmed off
    t.say("Uploads are now limited to 20 a minute per user.", 4.0)
    t.beat("[data-testid='upload-form']", "The form itself is unchanged.", 3.0)
    t.click("button[type='submit']", after=2.0)
    t.beat(".toast", "The 21st request answers 429 with Retry-After.", 3.5)

A take is content

It lives in the repo at devbench/takes/<name>.py, committed next to the feature it shows. It reads like a narration script, and it runs for real: anything it clicks, it actually clicks. Selectors anchor on data-testid, aria-label and href, because workspace names and task titles are real data and change between deployments.

The live page is never transformed

The obvious way to zoom is to scale the page while it records, and it fails twice: the browser's click coordinates stop matching where elements are, and the app's own responsive layout shifts while it is being filmed, so the video stops showing the app as users see it. Instead the browser captures a flat frame and the take only logs where the camera should have been. The camera move is a post-process.

how a recording is madecapture and timeline are separate files
real page (untouched)
     |
     |  Playwright  ---------->  capture.webm    (flat, no transform)
     |
     +- take logs ------------>  timeline.json   {zooms, captions, trim}
                                       |
                 ffmpeg: trim -> zoompan -> drawtext -> H.264
                                       |
                                  <name>.mp4

Terminal is the live session; Conversation is the same session as messages.

The recording opens a workspace. Every repository is cloned and checked out on the workspace's branch in a browser editor, and it is the same container for everyone. The panel on the right is the session. Terminal is the live TTY, and Conversation is the same session parsed into messages, which is what the phone shows. Open in Code gives the editor its own tab. The recording has no sound.

A merge request and the evidence beside it.

The recording opens a waiting merge request. Review checks, CI on the head commit, the changed files and the review threads are all on the one page. The Did it work panel names the task's latest test note and its recording, or says there is none. A blocking finding disables Merge. Merge anyway is the written way past a block: it asks for a reason, and the reason is recorded with the merge. The recording has no sound.

  • Two things follow

    Captions are drawn after the zoom, so a push-in can never magnify a caption and slice it off at the frame edge. And because the capture and the timeline are separate, re-rendering is free: a caption typo never means re-shooting, which matters when the take submitted a form for real.

  • Where the MP4 goes

    The finished MP4 is uploaded to the workspace's shared files, posted into the chat, and attached to the task it belongs to, where it plays inline. With no --base, the recorder points itself at this workspace's latest deployment, which is exactly the preview of the change.

devbenchinside the box
  • $ devbench video check

    Can this box record? Playwright, ffmpeg, the font and the browser are reported separately, because they fail differently.

  • $ devbench video setup

    Install Playwright and ffmpeg here. No root needed, which a workspace box does not have.

  • $ devbench video new <take>

    Scaffold a take next to the feature it shows.

  • $ devbench video record <take> --notify "…" --task <id>

    Record against the deployed app, render, share, post to the chat and attach to the task.

  • $ devbench video rerender <take>

    Rebuild the MP4 from the kept capture after editing captions. No browser, no side effects, seconds rather than minutes.

Two tabs answer two questions.

Changes is the diff: what this branch has that the branch it was cut from does not. It is the read you do before you ask for anything to be merged. Git is the plumbing: per repo, whether there is uncommitted work, whether the branch has been pushed, and what merge requests are open.

Changes

Push all commits and pushes every repo in one go. The distinction that matters: uncommitted work is not in a merge request. The Git tab says so plainly rather than letting you find out at review time.

Guardrails

The agent's git is scoped to this workspace's repos. It always allows the workspace's own branch and refuses your protected branches outright; reaching main happens through a merge request or a release, never a raw push. Per repo you can switch pushing off entirely, or add extra branches it may push, globs like release/* included. The box picks a change up immediately, with no restart.

It is enforced twice: in the git shim inside the box, and again in the push relay on the server, so a box that got around the first still cannot reach the provider. Guardrails are owner-edited, so loosening one is a real decision, not a suggestion to the agent.

The git flow

Which branch a workspace is cut from, and which branches its merge requests promote through, is one setting for the organization: an ordered list of stages. The first stage is what work is cut from, promotion runs left to right, and the last stage is production. Every branch in the flow is protected from direct agent pushes. A stage stores its key rather than its branch name, so renaming a branch leaves merge requests already opened against it intact.

devbenchinside the box
  • $ devbench mr status

    Uncommitted and unpushed work, per repo.

  • $ devbench ci

    CI runs and releases for this workspace's repos. A box holds no provider token, so gh and glab cannot work there.

Where the work lands.

Four surfaces the agent writes to and the team reads from.

Merge requests

An agent opens them. A person lands them.

The Merge button is the last place somebody reads a diff before it reaches a shared branch, and the rule is enforced for every caller rather than by each screen remembering to check.

  • History is kept

    Waiting is the queue; All is everything ever opened. Only still-open rows are re-checked against the provider before the page answers. A merged merge request does not change again, and asking about a year of history would make the page unusable exactly as it got useful.

  • Reverting goes through review

    Undoing a merge that has landed is computed with real git in the workspace's own box, not through a provider API; GitHub's REST API has no revert at all. Nothing is pushed to the target branch. The revert lands on revert/<repo>-<iid> and comes back as a merge request, so undoing a merge goes through the same read as making one.

  • Self-merge, if you choose it

    A per-workspace opt-in, off everywhere by default, owner-only to change, and never available on an info-only workspace. Every self-merge is audited and announced to the organization. The point of the switch is that the human read is skipped, so the team finds out it happened rather than discovering it later in the git history.

devbenchinside the box
  • $ devbench mr targets

    The stages --target accepts, and which are open.

  • $ devbench mr create --target <stage>

    Open merge requests promoting this workspace's branch.

  • $ devbench mr list

    This workspace's merge requests, with ids.

  • $ devbench mr approve <mr_id>

    Land one. Only where the workspace allows self-merge.

  • $ devbench mr reply <mr> <discussion> "…"

    Reply to a review thread at the provider.

  • $ devbench mr resolve <mr> <discussion>

    Resolve a review thread.

Docs that know which answer is current.

A doc is Markdown with a share link. Anyone can write one in the app, and any workspace's box can publish one from the CLI. Public, or kept inside the organization; attached to a workspace, or standing on its own.

Two things turn a pile of documents into something a program can search.

devbenchinside the box
  • $ devbench doc create <title> --file <path>

    Publish a Markdown doc and print its share link.

  • $ devbench doc list

    Docs and their share links.

  • $ devbench doc get <id>

    Print a doc's Markdown.

  • $ devbench doc from-memory

    Publish everything the agent has learned about this workspace as one shareable doc.

  • Subjects

    Subjects file a doc under a topic. Slugs are normalized, so these are one node rather than three synonyms nothing can be found under:

    Security Auditsecurity_auditSECURITY-AUDIT

  • Edges

    Edges say how two docs relate. A tag index cannot express this:

    relates tofollowssupersedesderived fromanswerscontradicts

    “This week's findings supersede last week's” and “this week's findings contradict last week's” are both two docs tagged security-audit to a tag index, and they mean opposite things to whoever has to act.

  • A summary, read instead of the body

    Each doc also carries a summary: one paragraph read instead of the whole body. A briefing that pastes five documents into a prompt is one nobody reads, so the summary is what a scheduled run is given.

  • List and Graph

    List answers “where is that document”. Graph answers “what do we know about X, and what replaced what”.

Invite only

We set your organization up with you.

Tell us about your team and the repositories you would bring; we reply within a working day.