215 lines
9.3 KiB
Markdown
215 lines
9.3 KiB
Markdown
<div align="center">
|
||
|
||
# helder.
|
||
|
||
**A dark desktop workbench for developers who build with Claude Code.**
|
||
|
||
See what the agent changes, while it changes it — then hand it back exactly the line you mean.
|
||
|
||
[](#download)
|
||
[](https://electronjs.org)
|
||
[](https://react.dev)
|
||
[](https://typescriptlang.org)
|
||
[](#development)
|
||
[](#fully-vibe-coded)
|
||
|
||
<img src="docs/design/screenshots/Screenshot%202026-09-03%20at%2009.34.16.png" alt="The Helder workspace: source control, explorer, editor and the Claude Code agent in four columns" width="100%">
|
||
|
||
</div>
|
||
|
||
---
|
||
|
||
## Who this is for
|
||
|
||
You run Claude Code. The agent writes, edits and refactors while you watch the terminal scroll past. Two questions come back every few minutes: *what did it just change*, and *how do I point it at this exact line*.
|
||
|
||
Helder answers both in one window. The agent runs in the right column. The code it touches sits in the middle. The git working state sits on the left. Nothing is more than one keystroke away, and no window switch is necessary.
|
||
|
||
Helder is a review and hand-off surface, not a replacement for your editor. Keep PhpStorm or VS Code for the long build sessions. Open Helder for the sessions where the agent does the work.
|
||
|
||
---
|
||
|
||
## Download
|
||
|
||
Version **0.1.0**. Both builds are unsigned, so each platform asks once for permission.
|
||
|
||
| Platform | File | After the download |
|
||
|---|---|---|
|
||
| macOS · Apple Silicon | [`Helder-0.1.0-arm64.dmg`](releases/Helder-0.1.0-arm64.dmg) | Drag to `Applications`, then run `xattr -dr com.apple.quarantine /Applications/Helder.app` |
|
||
| Windows · x64 | [`helder-win-v0.1.0.zip`](releases/helder-win-v0.1.0.zip) | Unzip and run `Helder.exe`. SmartScreen shows "unrecognised app" — choose *More info · Run anyway* |
|
||
|
||
The `claude` CLI must be on your `PATH`. The agent pane starts it for you.
|
||
|
||
---
|
||
|
||
## What it does
|
||
|
||
Four resizable columns, between a thin title bar and a status bar.
|
||
|
||
| Column | What it holds |
|
||
|---|---|
|
||
| **A · Source Control** | Commit box, staged list, changes list, per-file `+/−` counts |
|
||
| **B · Explorer** | File tree with type icons and inline change badges |
|
||
| **C · Editor** | Tabs, syntax highlighting, and four views of every changed file |
|
||
| **D · Agent + Shell** | A live Claude Code terminal over a normal shell |
|
||
|
||
Every boundary is a splitter. Positions survive a restart, together with your open tabs and view modes.
|
||
|
||
### Hand off a reference, not a description
|
||
|
||
This is the feature the app exists for. Select code in the editor, press `⌘→`, and the reference lands in the agent's input **without a submit**:
|
||
|
||
```
|
||
src/Http/Controller/UserController.php:42
|
||
```
|
||
|
||
Stack five of them, add your sentence, then press Enter once. Under the hood Helder writes a bracketed paste into the agent's PTY, so the `claude` CLI treats it as pasted text, exactly like a real terminal paste.
|
||
|
||
Right-click gives you the same reference on the clipboard. The Explorer offers it at file level.
|
||
|
||
### Four views of one change
|
||
|
||
Every changed file derives four views from one original-and-updated pair. `⌘M` cycles them.
|
||
|
||
**Actual** · **Original** · **Diff** · **Split**
|
||
|
||
Added is teal, removed is amber-deep. There is no green and no red anywhere: the diff reads on shape and on a 2px rule, not on alarm.
|
||
|
||
<img src="docs/design/screenshots/Screenshot%202026-09-03%20at%2009.34.30.png" alt="Split view: original on the left, updated on the right, with the changed line marked" width="100%">
|
||
|
||
### Git, in the columns you already read
|
||
|
||
The Source Control column is a working git client for the review loop:
|
||
|
||
- Stage and unstage a single file, or the whole list.
|
||
- Write a commit message and commit with `⌘↵`.
|
||
- Discard a file back to `HEAD`, behind a confirmation.
|
||
- Push the current branch with `⌘P`.
|
||
- Watch `+/−` counts update as the agent writes.
|
||
|
||
Pull, fetch and branch switching stay out of scope. Helder reviews what the agent did; it does not manage your remotes.
|
||
|
||
### One search for everything
|
||
|
||
`⌘F` opens a single overlay that searches file **contents** and file **names** at the same time. Content matches come from ripgrep on the left, fuzzy name matches on the right. There is deliberately no second "go to file" command to remember.
|
||
|
||
<img src="docs/design/screenshots/Screenshot%202026-09-03%20at%2009.34.21.png" alt="The search overlay and the keyboard shortcut reference" width="100%">
|
||
|
||
### The project note
|
||
|
||
`⌘N` opens a note that belongs to the project. Collect the things you want to tell the agent while you read. `⌘P` passes the whole note into the agent's input in one go.
|
||
|
||
---
|
||
|
||
## Keyboard
|
||
|
||
Press `?` in the title bar for the full list.
|
||
|
||
| Key | Action |
|
||
|---|---|
|
||
| `⌘F` | Search contents and names |
|
||
| `⌘→` | Pass the selection to the agent |
|
||
| `⌘N` · `⌘P` | Open the project note · pass the whole note |
|
||
| `⌘M` | Cycle Actual · Original · Diff · Split |
|
||
| `⌘C` · `⌘↵` | Focus the commit message · commit the staged files |
|
||
| `⌘P` | Push the current branch |
|
||
| `⌘S` | Save this file |
|
||
| `⌘G` · `⌘L` · `⌘.` | Source Control on or off · fluid columns · hidden files |
|
||
| `⌘O` · `⇧⌘O` | Open a project folder · open a recent project |
|
||
| `⌘←→` · `↑↓` · `↵` | Move between columns · move the row cursor · open the row |
|
||
|
||
---
|
||
|
||
## Fully vibe coded
|
||
|
||
Helder is **100% vibe coded**. Every line comes out of Claude Code sessions: the design board, the Electron main process, the React renderer, the 155 tests, the packaging scripts and this README. A human set the direction, judged the result and said yes or no. A human did not type the source.
|
||
|
||
That is also why the app exists. The workflow needed a tool, so the workflow built one.
|
||
|
||
Read it with that in mind. The code is reviewed and it is tested, but it carries the shape of the sessions that made it.
|
||
|
||
---
|
||
|
||
## Configuration
|
||
|
||
Settings are per project, in a `.helder/` folder in the project root.
|
||
|
||
| File | Role |
|
||
|---|---|
|
||
| `config.json` | Your overrides only. Sparse |
|
||
| `config.default.json` | Every default, rewritten on each launch as live documentation |
|
||
| `theme.css` | A theme over the built-in dark one. The code font and size live here |
|
||
|
||
An effective value comes from `config.json` when it is present, otherwise from `config.default.json`, merged key by key. A watcher reloads both while the app runs.
|
||
|
||
There is no light mode and no theme toggle. That is a decision, not a gap.
|
||
|
||
---
|
||
|
||
## Development
|
||
|
||
Node 18 or later, and `git` on your `PATH`.
|
||
|
||
```bash
|
||
npm install # rebuilds node-pty for Electron (postinstall)
|
||
npm run dev # launch with hot reload
|
||
```
|
||
|
||
Helder opens one project per window, by default the working directory. Click the project name in the title bar to open another, or start with `HELDER_PROJECT=/path/to/repo npm run dev`.
|
||
|
||
| Command | What it does |
|
||
|---|---|
|
||
| `npm run dev` | Launch in Electron with HMR |
|
||
| `npm run build` | Production build into `out/` |
|
||
| `npm test` | The vitest suite |
|
||
| `npm run lint` | ESLint |
|
||
| `npm run typecheck` | `tsc --noEmit`, renderer and main |
|
||
| `npm run rebuild` | Rebuild `node-pty` when a terminal says "PTY unavailable" |
|
||
|
||
Keep typecheck, lint, test and build green together. The build uses esbuild and does not type-check, so run `typecheck` on its own.
|
||
|
||
### Package a release
|
||
|
||
```bash
|
||
./sync_helder.sh # macOS: build, install into ~/Applications, copy the DMG
|
||
npm run build && npx electron-builder --win -c.npmRebuild=false # Windows, cross-built from macOS
|
||
```
|
||
|
||
The Windows build needs `node_modules/@vscode/ripgrep-win32-x64`, which npm refuses to install on macOS. Extract it by hand once; `npm ci` removes it again.
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
| Layer | Choice |
|
||
|---|---|
|
||
| Shell | Electron 31, main + renderer + preload bridge (`contextIsolation: true`) |
|
||
| Renderer | React 18, TypeScript, Vite through `electron-vite` |
|
||
| Highlighting | Prism 1.29 |
|
||
| Filesystem | `fs` + `chokidar` v3, in the main process |
|
||
| Git | `simple-git`, in the main process |
|
||
| Terminals | `node-pty` + `xterm.js` |
|
||
| Search | ripgrep for content, a fuzzy matcher for names |
|
||
| Type | IBM Plex Mono for code and labels, IBM Plex Sans for the interface. Both bundled |
|
||
|
||
**The one rule:** the renderer never touches the filesystem, git or a PTY. Everything crosses the preload bridge over IPC. Break that and the app stops being safe to run against a real repository.
|
||
|
||
```
|
||
src/
|
||
main/ window, IPC, services (fs · git · pty · search · config · logger)
|
||
preload/ the contextIsolation bridge — the only renderer↔OS surface
|
||
renderer/ React UI: App, editor, terminals, overlays, project store, helpers
|
||
test/ vitest — diff, fuzzy, highlight, config, fs, git, grouping, UI
|
||
docs/design/ the design board, tokens and screens at real pixel size
|
||
DESIGN.md functional spec: every panel, state and interaction
|
||
CLAUDE.md architecture notes and the traps, for the next agent session
|
||
```
|
||
|
||
`docs/design/README.md` is the visual source of truth. `DESIGN.md` is the behavioural one.
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
TBD.
|