Free and open-source desktop workspace for Codex, Claude Code, and OpenCode. Carry context between threads, decide in tasks, and read the diff before you commit.
Message from the thread "Billing page" (id 8d3f1a9c-2b47-4e6d-9a51-c07e3b2f6d18):The billing page is about to read the user’s plan. What does it look like after your migration?Show detailsHide details
Working · 0sWorked for 3s
ThinkingThought for 1sSending messageSent message
It becomes user.subscription, with statusand trialEndsAt. Trial users have no card yet, so I told Billing page to hide invoices for them. Back to the migration.
Working · 0s
Editing files
Message Codex…Say it during this turn…
openorc/plans-migration-4b7e2cAsk for approvalGPT-6-AstraHigh
What does the plan look like after your migration?
user.subscription, and no invoices on trials
Tasks/Rate-limit the public APIstudio
Rate-limit the public API
BacklogIn progressHighstudio
Text, images, and / commandsMarkdown
Goal
Stop one client from exhausting the API for everyone else.
Acceptance criteria
100 requests per minute per API key
Return 429 with a Retry-After header
Covered by tests
LabelsAPI
Comments
Mention a model to discuss this task. Clear work requests continue in a linked thread.
You
@GPT-6-Astra - High @Opus 5.5 - High How should we rate-limit the public API?
Reply
GPT-6-AstraHigh · Codex
A token bucket per API key, kept in memory in the API process. It is fast and needs no new infrastructure.
Replying…
ReplyCancel response
Opus 5.5High · Claude Code
That works on one server, but deploy/fly.tomlruns 3 instances. Each would keep its own count, so the real limit becomes 300 a minute. Keep the counts in the Redis we already use for sessions.
Replying…
ReplyCancel response
You
@Opus 5.5 - High Good catch. Build it with Redis.
Reply
Opus 5.5High · Claude Code
Building it on Redis with a sliding window per API key, so all three instances share one count. The work continues in a linked thread.
Replying…
Starting work…
Working in thread
ReplyCancel responseOpen thread
Leave a note, or type @ to ask a model…@@Opus 5.5 - High
@GPT-6-Astra - HighCodex
@Opus 5.5 - HighClaude Code
Type @ to choose a model and effortComment
Live dashboard updatesopenorc/team-5f1c8e2a-7d34-4b9e-a0c6-3e8d27f19b54studioworking
Product teamVersion 2ReadyWorkingCompletedShow activityCompact lead context
Send an instruction to start this team.
Replace dashboard polling with live updates.
Seen by LeadSeen by everyone
LeadGPT-6-Astra - High
Writing response
One contract for everyone: the server emits thread.updatedwith { id, updatedAt }on the existing socket. @Serversends it, @Clientdrops polling for it, @Reviewerchecks both sides.
ServerOpus 5.5 - High
Writing response
Emitting thread.updatedafter each write. I added versionso late events can be ignored. @Client, order by version, not by arrival.
ClientGrok 4.7
Writing response
Ordering by versionfrom Server. Polling is gone; the dashboard updates when an event lands.
ReviewerOpus 5.5 - High
Writing response
Reading both sides: the server sends updatedAtin seconds, the client compares it to Date.now()in milliseconds. Every event looks older than what is on screen, so none are shown. @Server, send milliseconds.
ServerOpus 5.5 - High
Writing response
Fixed: updatedAtis in milliseconds, and a new test sends one event from write to screen.
Edited 1 file+6−2Review
Shared workspace checkpoint · may include concurrent edits
server/events.ts+6−2
LeadGPT-6-Astra - High
Writing response
Live updates work end to end. Ready for your review.
Working for 0s
Mention @name to address a member, @everyone for the whole team. Without a mention the lead replies.Enter sends to the active turn where supported. Queue keeps it for the next turn.
Built for the agents you already have. Bring your Codex and Claude Code subscriptions, and the provider accounts you sign into in OpenCode. Keep their own tools and configuration. OpenOrc gives their conversations, tasks, and reviews one home.
Plan, Review, Ship
Turn a conversation into tasks, weigh the approach with more than one model, and read the diff where the work happened. Commit, push, or open a pull request when it is ready.
Render transcript rows by blockPerformancestudiojust now
Defer font and icon loadingPerformancestudiojust now
Write useful empty statesstudiojust now
In progress1
Cache dashboard queriesPerformancestudiojust now
Review2
Create the welcome flowOnboardingstudiojust now
Polish the project pickerOnboardingstudiojust now
Changes1+8-2CommitPushPR
Msrc/Welcome.tsx+8-2
1import { ProjectPicker } from'./ProjectPicker';
2import { Button } from'./ui';
3
4exportfunctionWelcome() {
5return (
5 <mainclassName="empty">
6 <p>No projects yet.</p>
6 <mainclassName="welcome">
7 <h1>Make yourself at home.</h1>
8 <p>Connect a project to start building.</p>
9 <ProjectPicker />
10 <ButtononClick={startConversation}>
11 Start a conversation
12 </Button>
13 <KeyboardHint />
14 </main>
15 );
16}
Organize the work without losing the thread.
Questions, decisions, and results stay connected, even when different agents take a turn.
New threadstudio
What should we work on?
The agent works in your repository. You may create a task first or go straight into building.
@mention a file
⌘Vpaste an image
⌘Ksearch
What would you like to do?Say it during this turn…
mainAsk for approvalGPT-6-AstraHigh
App performancestudioworking
Investigate overall app performance improvements
Working · 0sWorked for 7s
ThinkingThought for 1sReading filesRead 6 filesRunning commandRan a command
Three upgrades stand out, ordered by impact.
Area
Finding
Estimated gain
Dashboard queries
Every render refetches listProjects and listThreads together.
40% faster first paint
Transcript rendering
Rows re-render on each stream event, not just the changed block.
Smooth scrolling under load
Startup
Fonts and icons load before the first window paints.
300 ms sooner to interactive
Want me to create tasks for these, or work on them in this thread?
How should we take these on?
Create tasksOne task per upgrade, ready for discussion.
Implement itWork through all three in this thread now.
Create tasks
AnswerDecline
answered
Working · 0sWorked for 3s
Created three tasks. Each one carries the finding, the scope, and what done looks like.
Cache dashboard queries
Backlogjust now
Render transcript rows by block
Backlogjust now
Defer font and icon loading
Backlogjust now
Message Codex…Say it during this turn…
mainAsk for approvalGPT-6-AstraHigh
Tasks/Cache dashboard queriesstudio
Cache dashboard queries
BacklogIn progressHighstudio
Goal
Open the dashboard once per project without refetching what is already on screen.
Scope
Memoize listProjects and listThreads per project.
Invalidate the cache on thread events instead of on every render.
Serve the first paint from the cache when it exists.
Acceptance criteria
The dashboard makes two requests on open, not one per render
Thread changes appear within one refresh window
First paint is measurably faster on a project with 50 threads
LabelsPerformance
Comments
Mention a model to discuss this task. Clear work requests continue in a linked thread.
You
@GPT-6-Astra - High Which of these queries repeats the most while the dashboard is open?
Reply
GPT-6-AstraHigh · Codex
listThreads. The hook depends on the selection, so every selection change refetches all threads for the project. One memoized query per project cuts the dashboard to two requests.
Replying…
ReplyCancel response
You
@Opus 5.5 - High What do you think?
Reply
Opus 5.5High · Claude Code
Agreed. Cache per project with a five-second window and invalidate on thread events. Serve the first paint from the cache so the dashboard never waits on the network.
Replying…
ReplyCancel response
You
@GPT-6-Astra - High Build this.
Reply
GPT-6-AstraHigh · Codex
Starting from the plan above: a per-project cache with event invalidation, and the first paint served from it.
Starting work…
Working in thread
ReplyCancel responseOpen thread
Leave a note, or type @ to ask a model…@@GPT-6-Astra - High @Opus 5.5 - High
Dashboard queries are cached per project. Selection changes reuse the cache, thread events invalidate it, and the first paint comes from the last known state. The dashboard now makes two requests on openinstead of one per render.
Give a thread its own worktree and branch. Agents work side by side without touching each other’s files, and you decide when a branch lands.
Simplify the design tokensopenorc/design-tokens-2c91f0studio
Worked for 41s
Every color, radius, and spacing step now comes from one tokens.css. The old per-component values are gone, and nothing outside this worktree has changed.
openorc/design-tokens-2c91f0+12−4Commit
Message Codex…Say it during this turn…
Ask for approvalGPT-6-AstraHigh
Pick up the conversation from Slack.
Mention your personal bot in a channel. Your agent works on your computer and replies in the thread. Open the same conversation in OpenOrc whenever you want the full picture.
Thread#engineering···
DC
David
@openorc The studio welcome screen gives people too many choices. Can you simplify it?
OpenOrcAPP
@DavidWorking · Opus 5.5 · ReadShould “Connect a project” be the one clear next step?
DC
David
Yes. Keep the layout, but make that the main action.
OpenOrcAPP
@DavidWorking · Opus 5.5 · EditWaiting for your approval or answer
Only you can decide. Allow applies once. Buttons expire after 10 minutes.
Allow onceDeny
BIS
Reply to thread…
+Shift ↵ for new line
Start where you are
Ask from a channel, then keep going with ordinary replies.
Stay in control
Follow progress and answer permission requests without leaving the thread.
Return to the workspace
Open the conversation on desktop to inspect its work and continue.
Slack runs through your desktop connection. Keep OpenOrc open and your computer awake.
Your setup stays yours.
Your accounts and agent configuration stay as they are. In your repositories, OpenOrc adds only its own branches under openorc/, Git refs under refs/openorc/, and worktrees for isolated work.
Keep your provider setup
Choose Codex, Claude Code, or OpenCode for each conversation, with the sign-in and configuration you already have.
CodexClaude CodeOpenCode
Bring conversations forward
Import Claude Code and Codex sessions and continue them with their history intact.
Carry the useful context
Keep decisions and lessons in optional shared project memory, so the next task starts with what you already learned.
Good to know.
What is OpenOrc?
A desktop workspace for coding agents. Conversations, tasks, project context, and code review stay together across your projects.
Can I use my existing agents?
Yes. OpenOrc works with the Codex, Claude Code, and OpenCode tools you already have installed, through their own sign-in and configuration. Provider subscriptions and API usage stay separate.
Where does my work live?
Projects, conversation history, tasks, and project memory are stored on your computer. Each agent’s requests go to that agent’s provider, under its data policies. So do conversation titles, and run summaries once you turn memory on, unless you choose another provider in settings.
Does saving a task start work?
No. A task waits in the backlog until you start it. Discuss it first, then begin when the approach is settled.
Can I review changes before they ship?
Yes. The Changes panel sits beside the conversation. Read the diff, ask for another pass in the thread, then commit, push, or open a pull request when your Git setup supports it.
Does scheduled or Slack work run while OpenOrc is closed?
No. Agents run on your computer. Keep OpenOrc open and your computer awake for scheduled work and Slack replies.
Every agent. One workspace.
Start a conversation with the agents you already have, and keep every decision and review in one place.
Mention a model to discuss this task. Clear work requests continue in a linked thread.
Replying…
deploy/fly.tomlruns 3 instances. Each would keep its own count, so the real limit becomes 300 a minute. Keep the counts in the Redis we already use for sessions.Replying…
Replying…
Starting work…
Working in thread