The IDE that talks back.

A full IDE for Claude Code. It reads the answer out loud and walks you through the changes one diff at a time.

Get Codeio
codeio Sessions drop after deployOpus 5 · 38%

Sessions are dropping a few days after every deploy. Can you find out why?

Opus 5Thinking

Watch your code explain itself.

One change at a time, in the right order, with the right reasons. It is the difference between reading a wall of code and watching a YouTube tutorial of the work that just happened.

Code review made easy

Spot something wrong when the AI was explaining the code? Drop a comment and claude will take it from there. Your comments sits on the diff itself, not three scrolls up the chat.

Stop reading. Start listening.

Reading every answer is exhausting. With Codeio, the answers go to your ears, not eyes. Give it one afternoon and scrolling a wall of text feels like something you used to do.

  • Click a sentence to hear it
  • step a sentence
codeio Sessions drop after deployOpus 5 · 38%

Sessions are dropping a few days after every deploy. Can you find out why?

GreprevokeSession|refreshToken
Readauth/session.ts
Readauth/refreshToken.ts

Found it — and it isn’t the deploy. revokeSession() clears the cookie, but it never touches the token store, so auth/refreshToken.ts goes on serving the old refresh token until it expires by itself.

That’s up to fourteen days, which is why it reads as a deploy problem: the deploy is only what rotates the pods and drops the in-memory cache that was hiding it.

Editauth/session.ts+6−1

I’ve moved the revocation into revokeSession() itself and made it idempotent, so a double logout can’t throw.

auth/session.tsts
export async function revokeSession(sid: string): Promise<void> {
  await cookies.clear(sid)

  // The half that was missing: the token store outlives the cookie,
  // so the family has to die here or it does not die at all.
  await tokens.revokeFamily(sid)
}
Editauth/refreshToken.ts+4−1

The refresh path was the accomplice, so auth/refreshToken.ts now refuses a revoked family instead of quietly minting from it.

Edittest/auth/session.test.ts+7−0

And there’s a test pinning it down: log out, replay the old refresh token, expect a refusal.

One caveat: this only helps sessions minted after it ships. The ones already out there, like a3f9c1e8-7b42-4d15-9e33-0c8f7a2b6d41, still have to age out.

Ready

Review the plan,
not just the code.

Highlight the line that is wrong, say what you want instead, press Refine — and the code you were dreading never gets written at all.

It tells you
when it is done.

Claude can take minutes to finish. If you have walked away from the screen, sound is the only way it can reach you.

  • Working

  • Waiting for your answer

  • Finished while you were away

  • Ended in an error

It is a full IDE

Codeio has the whole workspace built into it, so you never miss your code.


                
                
                
                  1
                
                function apply(): void {
                
                
              
                
                
                
                  2
                
                  hold(forWork, working && getSettings().keepAwake, 'prevent-display-sleep')
                
                
              
                
                
                
                  3
                
                  // No setting consulted, deliberately. See the note above.
                
                
              
                
                
                
                  4
                
                  hold(forVoice, announcing, 'prevent-app-suspension')
                
                
              
                
                
                
                  5
                
                }
                
                
              
                
                
                
                  6
                
                /** The first turn started, or the last one ended. */
                
                
              
                
                
                
                  7
                
                export function setWorking(next: boolean): void {
                
                
              
                
                
                
                  8
                
                  working = next
                
                
              
                
                
                
                  9
                
                  apply()
                
                You, just now · uncommitted
              
                
                
                
                  
                      1098
                    
                
                }
                
                
              
                
                
                
                  
                      11109
                    
                
                /** The voice took the floor, or the queue drained. */
                
                
              
                
                
                
                  
                      121110
                    
                
                export function setAnnouncing(next: boolean): void {
                
                
              
                
                
                
                  
                      131211
                    
                
                  announcing = next
                
                
              
                
                
                
                  
                      141312
                    
                
                  apply()
                
                
              
                
                
                
                  
                      151413
                    
                
                }
                
                
              
                
                
                
                  
                      161514
                    
                
                /** Shutting down. Drop both holds; nothing here outlives the app. */
                
                
              
                
                
                
                  
                      171615
                    
                
                export function dispose(): void {
                
                
              
                
                
                
                  
                      181716
                    
                
                  working = false
                
                
              
                
                
                
                  
                      191817
                    
                
                  announcing = false
                
                
              
                
                
                
                  
                      201918
                    
                
                  apply()
                
                
              
                
                
                
                  
                      212019
                    
                
                }
                
                
              
Playing “…so a turn you walk away from does not die with the machine.”
Problems Output Terminal
~/codeio $ npm test
  holds the display only while a turn runs
  holds the system for as long as the voice speaks
  28 passing (412ms)
~/codeio $ 

The same shortcuts
you already use.

The editor keeps VS Code’s bindings rather than inventing a dialect, and the voice is driven the same way. There is nothing new to learn to move over.

The editor

P
Open any file by name
F
Search the project
S
Save
J
Terminal
1–9
Jump to a tab

The voice

T
Hold to talk
Space
Play or pause
Back or forward a sentence
,.
Speak slower or faster
Esc
Stop talking

These are the ten you will use most. There are plenty more available.

The voice runs on
your own computer.

Both models come inside the app. There is no voice service to sign up for and nothing to download later. The voice works the first time you open it, even with no internet.

your computer

  • Kokoro 82M Speaks the answers ~90 MB
  • Whisper base.en Hears what you say ~76 MB
  • codeio.db Every chat, on your disk SQLite

Both models are in the download. The app is not allowed to fetch one while it runs.

  • what you type
  • the code Claude reads

Anthropic

Claude Code still does the thinking, so what you type and the code it reads go to Anthropic — exactly as they do when you run claude in a terminal. Codeio only changes how the answer comes back. Full details

No new subscription.
No sign-up.

Codeio runs on the Claude Code you already pay for. Nothing else to buy, paste, or set up.

  • A second subscription It runs on the Claude Code plan you already pay Anthropic for.
  • An API key Codeio never asks for one, and never handles billing.
  • An account with us There is no Codeio server for one to live on.
  • Models to download The voice and transcription models are already inside the app.

A working claude command If that runs in your terminal, you are ready. How to check

Put your headphones on and get back to work.

Codeio is in beta. macOS first, then Windows and Linux.

Get Codeio

Free while it is in beta · Uses the Claude Code login you already have