Inspiration

I started building Hlid before the Codex desktop app was a thing. t3code had just shown up and was neat, but it didn't really work for my use case. Claude Remote Control permissions also kept breaking, which kind of defeats the purpose when the whole point is being able to walk away from the machine.

I needed something that ran on Windows, had native access to my projects in WSL, worked with my Obsidian vault, and could be accessed from pretty much anywhere.

I also wanted something that felt more in the seat than tools like OpenClaw or Hermes. I didn't want to throw work into a black box and hope for the best. I wanted to see what the agent was doing, approve things when needed, jump into a terminal, and pick the session back up from my phone.

Basically, I wanted something that fit how I work and let me play with whatever new tooling caught my attention without waiting for an official integration.

Claude, Codex, and ChatGPT have all evolved since then, but so has Hlid. I still use the ChatGPT app for Computer Use and other things, but Hlid has become my go-to for getting pretty much anything done on my machine.

What it does

Hlid brings Codex, Claude, and ACP harnesses into one workspace.

You can manage persistent conversations, reference notes and project files, use skills across providers, open terminals, answer agent questions, inspect tool calls, manage permissions at the individual tool level, and track usage without bouncing between a bunch of different apps.

It isn't trying to replace the harnesses. The goal is to give them a shared home while still keeping the things that make each provider useful.

Hlid runs on Windows, works directly with projects inside WSL, and connects to an Obsidian vault on the Windows side. The same sessions are available from desktop or mobile, so I can start something at my desk, check on it from my phone, and come back later without losing everything.

How we built it

Hlid was originally built specifically for Claude, mostly because those were the models I enjoyed using at the time. The first version was built around Anthropic's Agent SDK and slowly grew from there.

Once I started using Codex more, I integrated the Codex app server into Hlid. That has probably been the best architectural decision I made for the project.

Instead of treating Codex like a terminal process and trying to scrape whatever it prints, Hlid can work with the actual session, tool, approval, usage, and response events. It also means imported Codex sessions can behave like real sessions inside Raven, not some read-only transcript that happens to look like one.

That integration is also how the Computer Use workflow came together. An agent working inside WSL can call a Hlid command that creates a Windows-native Codex Computer Use session. The parent agent stays in its project, the child gets access to the actual Windows desktop, and Hlid keeps the whole thing connected.

There isn't really any secret sauce to the stack. It is a Bun server running a TanStack web app, with SQLite, WebSockets, provider SDKs, and a pile of Windows and WSL integration work holding everything together.

The meat and potatoes has always been the UX. I wanted tool calls to be visible without taking over the chat. Approvals needed to work on desktop and mobile. Sessions needed to feel alive while they were running. If I didn't actually want to use it every day, I knew nobody else would either.

Hlid existed before Build Week, so I used Codex and GPT-5.6 to meaningfully extend it during the event. That work included Windows Computer Use delegation, first-class Obsidian CLI tools, cross-provider session controls, provider-history recovery, managed CLIProxy routing, local productivity features, and a lot of long-session performance work.

Challenges we ran into

Cross-device sync was probably the most annoying challenge.

A response, plan, question, or approval would show up correctly on desktop, but not mobile. Or the mobile view would reconnect and have most of the session, but miss the one piece of state it actually needed. Getting the server to be the source of truth while keeping every connected client updated took a lot of work.

Performance was the other big one.

As model context windows got larger, I got lazy about splitting work into dedicated chats. You already know what happened next. Some of my sessions ended up with hundreds of tool calls, giant transcript payloads, and enough rendered content to make the whole app feel sluggish.

I had tool results, session events, responses, and metadata mounted out the wazoo. It worked fine with a normal chat, but boy did it fall apart once I started using Hlid the way I actually wanted to use it.

I ended up progressively loading more of the session, moving expensive work into the background, bounding how much tool history gets rendered, and no longer rendering full tool-call results until they are expanded.

Most of these problems came from using Hlid while building Hlid. Needless to say, there was plenty of dogfooding.

Accomplishments that we're proud of

Getting Computer Use working from a WSL chat is probably my favorite feature.

The agent can be working inside a Linux project, realize it needs something from a Windows application, and hand that task to a Windows-native Codex worker. That still feels really neat every time I use it.

Auto-sleep was another fun one. Hlid watches provider usage, and when a session runs out of room in its current usage window, it can pause the work and pick it back up once the window clears. I don't have to babysit it or keep retrying the prompt.

I have also been getting more into speaking instead of typing, so adding local Whisper voice input was a game changer. I can talk to a session from my computer or phone, and the audio stays on my machine. Local read-aloud makes it even nicer when I am away from the desk.

More than any single feature, I am proud that all these pieces feel like one workspace. The providers, terminals, projects, notes, permissions, usage, and sessions can stay separate under the hood without feeling scattered everywhere.

What we learned

I wish I had some giant revelation here, but honestly, the biggest thing I learned was how Codex likes to work on a long-running project.

As I repeated the same validation, versioning, and commit workflows, Codex started recognizing those patterns and turning them into reusable memory-backed procedures. It kept itself more consistent without me having to explain the entire process every time. I hadn't really seen a model do that so naturally before, and it is something I want to play with a lot more.

I also learned that a unified agent interface can't flatten every provider into the same thing. Claude, Codex, and ACP agents all have different session behavior, tools, permission models, and usage reporting. Hlid needs to give them a shared workspace while still being honest about what is actually happening underneath.

The other lesson was pretty simple: with cross-device software, the server has to own the state. Desktop and mobile should just be different views into the same live session. Once I really committed to that model, a lot of the weird synchronization problems became much easier to reason about.

What's next for Hlid

Honestly, whatever strikes my fancy.

I recently added managed CLIProxy support because I wanted to try Codex models through Claude Code. That rabbit hole turned into support for routing models across other harnesses while still tracking the actual model and provider inside Ledger. Pretty neat!

I am still hunting down performance wins, improving the mobile and desktop UX, and finding more places where the different providers can share useful workflows without pretending they are all identical.

I will most likely keep expanding the Obsidian CLI integration, although the current version already covers most of what I wanted from it. I also want to add more non-ACP harnesses as I find interesting ones to play with.

If there is a neat tool or a new way to work with agents, it is probably going to end up in Hlid. And that's about it, really.

Built With

Share this project:

Updates