update readme.md
Some checks failed
CI / check (push) Has been cancelled

This commit is contained in:
2026-09-04 09:58:12 +02:00
parent bccc97c11c
commit 3746374d94

232
README.md
View File

@@ -1,109 +1,211 @@
# Helder
<div align="center">
**A dark, AI-first desktop code workbench for reviewing code written by an AI agent.**
# helder.
Helder is an Electron app that puts code review, git, and a live Claude Code agent side by side in one dense, IDE-style window. It opens one project per window, is dark-only by design (no light mode, no theme toggle), and is built around a single idea: make it effortless to point an AI agent at exactly the code you're looking at.
**A dark desktop workbench for developers who build with Claude Code.**
> **Status: working build.** The Electron app is scaffolded and everything above is implemented against the real filesystem, git, terminals, ripgrep search, and the `.helder/` config system. The editor is writable (save · autosave · discard). See [Getting started](#getting-started).
See what the agent changes, while it changes it — then hand it back exactly the line you mean.
[![Platform](https://img.shields.io/badge/platform-macOS%20·%20Windows-E8913A?style=flat-square)](#download)
[![Electron](https://img.shields.io/badge/Electron-31-18202B?style=flat-square)](https://electronjs.org)
[![React](https://img.shields.io/badge/React-18-18202B?style=flat-square)](https://react.dev)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.5-18202B?style=flat-square)](https://typescriptlang.org)
[![Tests](https://img.shields.io/badge/tests-155%20passing-8FBFB4?style=flat-square)](#development)
[![Vibe coded](https://img.shields.io/badge/vibe%20coded-100%25-E8913A?style=flat-square)](#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
A four-column workbench, left to right, between a thin title bar and status bar:
Four resizable columns, between a thin title bar and a status bar.
1. **Source Control** — git working state: commit box, staged list, changes list, per-file `+/` counts. Stage, unstage, commit, and discard. (Push, pull, fetch, and branch switching are out of scope this version.)
2. **Explorer** — a VS Code-style file tree with colored file-type icons and inline change badges.
3. **Editor** — tabs plus syntax-highlighted code, with four diff view modes for changed files: **Original · Updated · Diff · Split** (Split goes full-screen, side by side).
4. **Right column** — a live **Claude Code agent** terminal stacked over a normal shell terminal.
| 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 pane boundary is a draggable splitter; positions persist across launches.
Every boundary is a splitter. Positions survive a restart, together with your open tabs and view modes.
### The defining feature: Copy reference / Pass on to Agent
### Hand off a reference, not a description
Right-click in the editor to copy a project-relative `path:line` reference (e.g. `src/Http/Controller/UserController.php:42`), or **Pass on to Agent** — which inserts the reference into the agent's input *without submitting*, so you can stack several references before sending. Under the hood this uses bracketed paste into the agent's PTY, exactly how a real terminal paste behaves.
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` / `Ctrl+F` opens a single modal that searches **both file contents and file names** at once — content matches on the left (ripgrep), fuzzy file-name matches on the right. There is intentionally no separate "go to file" command.
`⌘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.
---
## Tech stack
## Keyboard
| Layer | Choice |
|-------|--------|
| Shell | Electron (latest stable), main + renderer + preload bridge (`contextIsolation: true`) |
| Renderer | React 18 + TypeScript + Vite (`electron-vite`) |
| Highlighting | Prism 1.29 (swappable to Shiki / CodeMirror 6) |
| Filesystem | `fs` + `chokidar`, via the main process |
| Git | `git` / `simple-git`, via the main process |
| Terminals | `node-pty` + `xterm.js` |
| Search | `ripgrep` (content) + a fuzzy matcher (file names) |
| Mono font | JetBrains Mono, bundled locally |
Press `?` in the title bar for the full list.
**Architecture rule:** the renderer never touches the filesystem, git, or PTYs directly. All of it goes through the main process over IPC / the preload bridge.
| 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 |
---
## Getting started
## Fully vibe coded
Requires Node 18+ and a recent `git` on your `PATH`.
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.
```bash
npm install # also rebuilds node-pty for Electron (postinstall)
npm run dev # launch the app with hot reload
```
That is also why the app exists. The workflow needed a tool, so the workflow built one.
Helder opens **one project per window** — by default the current working directory. Open a different folder by clicking the project name in the title bar, or launch with `HELDER_PROJECT=/path/to/repo npm run dev`. The agent pane auto-runs the `claude` CLI, so it must be on your `PATH`.
### Scripts
| Command | What it does |
|---------|--------------|
| `npm run dev` | Launch in Electron with HMR |
| `npm run build` | Production build into `out/` |
| `npm start` | Run the built app |
| `npm test` | Run the vitest suite |
| `npm run lint` | ESLint |
| `npm run typecheck` | `tsc --noEmit` (renderer + main/preload) |
| `npm run pack` | Unpacked app into `dist/` (electron-builder) |
| `npm run dist` | Distributable (`.dmg` / `.zip` / etc.) |
| `npm run rebuild` | Re-rebuild `node-pty` for Electron if a terminal shows "PTY unavailable" |
To preview the original design prototype, open `design_handoff_helder_workbench/design/Helder - AI Code Workbench.html` in a browser — a clickable React-via-Babel mock with sample data.
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 project-scoped, in a `.helder/` folder in the opened project's root:
Settings are per project, in a `.helder/` folder in the project root.
- **`.helder/config.json`** — your overrides only (sparse).
- **`.helder/config.default.json`** — the full default set, regenerated on every launch as live documentation of every setting.
- **`.helder/theme.css`** — a custom theme layered over the built-in dark theme; the code font and size live here.
| 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 setting is the value from `config.json` if present, otherwise from `config.default.json`, merged key by key.
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.
---
## Repository layout
## 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/ Electron main process: window + IPC + services
(fs-service, git-service, pty-service, search-service, config, project)
preload/ contextIsolation bridge — the only renderer↔OS surface (window.helder)
renderer/ React UI: App, editor (4 diff modes + writable buffer), terminals (xterm),
overlays (search/menu/toasts), project store, diff/highlight/fuzzy helpers
test/ vitest suite — diff, fuzzy, highlight, config, fs, git
electron.vite.config.ts electron-builder.yml eslint.config.js vitest.config.ts
DESIGN.md Functional/UX spec — every panel, state, interaction
CLAUDE.md Guidance + current architecture for Claude Code
design_handoff_helder_workbench/ Original design handoff + clickable prototype
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
```
`DESIGN.md` and `design_handoff_helder_workbench/README.md` remain the design source of truth; the prototype is a visual reference, not shipped.
`docs/design/README.md` is the visual source of truth. `DESIGN.md` is the behavioural one.
---