Aleksandar's Online Notes

Personal ramblings and thoughts on Life, the Universe and Everything — including but not limited to Infosec & Tech

PyCodeBridge Grew Up: Agentic Coding from Discord

Back in February I wrote about PyCodeBridge as a way to doom-vibe-code from wherever I happened to be: phone in hand, Discord open, local development machine doing the real work somewhere else.

That version was fun. It was also a bit of a prototype in spirit: a chat bridge into Codex CLI sessions, with dreams of multiple transports and just enough command handling to make mobile coding feel possible.

Several months later, the project has become something more serious.

PyCodeBridge is now an agentic coding bridge. It still lets me drive local repo work from chat, but the shape is different: Discord is the supported transport, channels are mapped to repos with code-<repo>, Codex is just the default backend, and Claude Code or Gemini CLI can be selected per session when I want a different agent.

In other words, it moved from “Codex in chat” to “a Discord control plane for agentic coding on my own machine.”

The New Mental Model

The basic idea is still simple:

  1. A private Discord channel named code-myrepo maps to a local git repository under code_root.
  2. Messages and commands in that channel are routed to an agent session for that repo.
  3. The agent runs locally, with access to the actual working tree, local tooling, credentials, and git state I have configured.
  4. Results stream back into Discord.

The important change is that the “agent” is now an abstraction, not a synonym for one CLI.

The default backend is Codex. That remains the out-of-the-box path and the config section is still named codex for compatibility. But sessions can now use:

The command is straightforward:

!c agent claude
!c agent gemini gemini-2.5-pro
!c agent codex gpt-5.4 medium

There are also helper commands:

!c agents
!c models
!c efforts
!c agent
!c model
!c effort

The no-argument versions show what the current session is actually using. That matters more than it sounds, because once you have multiple threads, sessions, models, and backends, guessing is a great way to confuse yourself.

Discord Won

The original post talked about Discord, Telegram, and Slack. That is no longer true.

The code still keeps a transport-aware architecture internally, but the supported transport is Discord. I use Discord. Discord has the interaction model I wanted: channels, private repo rooms, threads, typing indicators, uploads, downloads, pinned messages, and direct messages for owner/admin workflows.

So the product decision became simple: stop pretending every transport matters equally and make the Discord experience solid.

That also means the old channel prefix changed. It is no longer codex-myrepo. It is:

code-myrepo

That name fits the project better now. A channel maps to code. The selected backend can be Codex, Claude, Gemini, or whatever gets added later.

It Is Not Just Prompt Relay Anymore

The bridge now has a real command surface. You can still send prompts, but the useful part is that you can operate sessions without being at the machine.

Some examples:

!c start
!c resume fix the failing tests
!c status
!c ps
!c stop
!c interrupt
!c kill
!c logs
!c download path/to/file
!c git status
!c gh pr status

There are shortcuts for active-run interaction:

!s tighten the scope
!a yes, proceed
!y
!n
!w
!retry

Plain chat can also become useful in the right state. If exactly one session is running, a plain message can steer that active session instead of being queued as a new prompt. If an agent is waiting for input, a plain reply can go straight to stdin.

That makes the mobile workflow feel much less like operating a bot and much more like supervising a long-running coding process.

Sessions, Threads, Queues, and Conflict Handling

Each repo channel has a default session. Discord threads also get isolated session scopes, so I can split work without stomping on the main channel state.

There is queueing per channel, run control, stale-session handling, and explicit conflict choices:

!continue
!new
!compact

The compact flow is one of the more useful quality-of-life changes. When a session is stale or I want a fresh run without throwing away all context, the bridge can summarize prior context and start a new session from that summary.

That is the kind of feature that only shows up after actually using this thing for messy, interrupted work.

Security Became a First-Class Feature

Running local coding agents from chat is powerful, which is another way of saying it can be dangerous if treated casually.

The current bridge is much stricter than the early version:

There are also safer file-transfer rules now. Uploads are bounded by per-file size, total batch size, and file count. Saves use repo-local temporary files and symlink-aware finalization so an upload cannot casually overwrite something outside the repo.

That sounds boring until you remember this is a chat interface into a development machine. Boring is good here.

Better Feedback During Long Runs

Long agent runs are where bridges like this either feel magical or feel broken.

PyCodeBridge now tries much harder to tell me what is happening:

The point is not to make the chat noisy. The point is to avoid the worst state: staring at Discord wondering whether anything is alive.

Docker, Health Checks, and Operations

The project also grew the less glamorous pieces that make it easier to run:

The bridge can still run directly with Python, but the Docker path is much cleaner for a persistent bot.

What I Actually Use It For

I do not think of PyCodeBridge as “coding on a phone.” That phrase sounds like punishment.

I think of it as remote supervision for local agentic coding.

The useful moments are things like:

It is still a little ridiculous. That is part of the charm. But it is no longer just a weekend toy.

The Current Shape

The short version:

That is a lot more than “send a prompt to Codex from Discord.”

It is now a small, opinionated control plane for letting agentic coding tools work on my machine while I steer them from wherever I happen to be.

Still doom-vibe-code friendly. Just a lot less reckless.

Project:

https://github.com/aleksandarristic/pycodebridge

↑ Archive