113 lines
5.6 KiB
Markdown
113 lines
5.6 KiB
Markdown
# Helder
|
||
|
||
**A dark, AI-first desktop code workbench for reviewing code written by an AI agent.**
|
||
|
||
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.
|
||
|
||
> **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).
|
||
|
||
---
|
||
|
||
## What it does
|
||
|
||
A four-column workbench, left to right, between a thin title bar and 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.
|
||
|
||
Every pane boundary is a draggable splitter; positions persist across launches.
|
||
|
||
### The defining feature: Copy reference / Pass on to Agent
|
||
|
||
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.
|
||
|
||
### 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.
|
||
|
||
---
|
||
|
||
## Tech stack
|
||
|
||
| 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 |
|
||
|
||
**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.
|
||
|
||
---
|
||
|
||
## Getting started
|
||
|
||
Requires Node 18+ and a recent `git` on your `PATH`.
|
||
|
||
```bash
|
||
npm install # also rebuilds node-pty for Electron (postinstall)
|
||
npm run dev # launch the app with hot reload
|
||
```
|
||
|
||
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.
|
||
|
||
---
|
||
|
||
## Configuration
|
||
|
||
Settings are project-scoped, in a `.helder/` folder in the opened project's 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.
|
||
|
||
An effective setting is the value from `config.json` if present, otherwise from `config.default.json`, merged key by key.
|
||
|
||
---
|
||
|
||
## Repository layout
|
||
|
||
```
|
||
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
|
||
```
|
||
|
||
`DESIGN.md` and `design_handoff_helder_workbench/README.md` remain the design source of truth; the prototype is a visual reference, not shipped.
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
TBD.
|