Files
helder/OVERNIGHT.md
2026-06-16 06:18:42 +02:00

76 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Overnight work log
Autonomous session continuing the Helder build while you slept. Everything kept
compiling (`npm run build`), type-checking (`npm run typecheck`) and — new this
session — passing tests (`npm run test`). Git left uncommitted for you to review.
## Plan
1. Packaging (electron-builder)
2. Automated test suite (vitest)
3. Lint + format (eslint + prettier)
4. Robustness + feature polish
5. Developer README
## Progress
### 1. Packaging — done
- Added `electron-builder.yml` (appId `com.blijnder.helder`, mac dmg+zip / win nsis / linux AppImage, unsigned local build).
- Scripts: `npm run pack` (`--dir`), `npm run dist`, `npm run dist:mac`.
- Made the bundled ripgrep path asar-safe (redirect to `app.asar.unpacked`).
- `asarUnpack` for `node-pty` + `@vscode/ripgrep` so the native `.node` and `rg` binary load at runtime.
- Verified: `npm run pack` produced `dist/mac-arm64/Helder.app` (245 MB) with `pty.node` + `rg` correctly unpacked. Unsigned (ad-hoc), default icon. `dist/` gitignored.
### 2. Automated tests — done (vitest)
- Added vitest + `vitest.config.ts`; scripts `npm run test` / `test:watch`. **38 tests, all green.**
- `test/diff.test.ts` — LCS diff: no-change, single change, new/deleted file, side marks, split alignment, trailing-newline.
- `test/fuzzy.test.ts` — subsequence matcher (extracted to `src/renderer/src/fuzzy.ts`).
- `test/highlight.test.ts` — ext/lang/label/icon/escape + Prism php highlighting (confirms markup-templating load order).
- `test/config.test.ts``.helder` defaults regen, sparse deep-merge, theme.css not overwritten.
- `test/fs.test.ts` — tree dirs-first + ignore dirs, content index skips binaries/node_modules, read/write round-trip.
- `test/git.test.ts``classify` unit + real temp-repo integration (modified/untracked/staged, HEAD-vs-worktree text).
### 3. Lint + format — done
- ESLint flat config (`eslint.config.js`): typescript-eslint recommended + react-hooks, prettier-disables, sensible ignores. `npm run lint` = **0 errors** (8 intentional exhaustive-deps warnings).
- Fixed real `no-unused-expressions` violations (short-circuit/ternary-as-statement).
- `.prettierrc.json` added (style: no-semi, single-quote, width 140). Not auto-applied to avoid churn.
### 4. Robustness + feature polish — done
- **Fixed a real `discard` bug**: `git checkout` can't remove a new/untracked file. `discard` now reverts modified→HEAD, restores deleted, and removes new/untracked (staged or not). Covered by new git tests.
- **Close-tab guard**: confirms before closing a tab with unsaved edits (× / middle-click / ⌘W), and clears its buffer on close. Reads fresh state via refs so the ⌘W path is correct too.
- **ErrorBoundary** around the whole app — a render fault shows a dark, recoverable panel (with the message + Reload) instead of a blank window.
- **`editor.tabSize` wired** into the editable buffer (textarea + highlighted pre) and the status bar — config now visibly does something.
- **Layout persistence**: the three column widths + the terminal split fraction persist across launches via localStorage (`persist.ts`), making the README's "positions persist across launches" claim true.
### 5. Developer docs + icon — done
- `README.md` updated from "greenfield" to the real working build: getting-started, scripts table, repository layout.
- App icon generated from Helder's spark mark → `build/icon.png` (1024²); electron-builder embeds `icon.icns` in the packaged app (verified).
### 6. Renderer component tests + CI — done
- Added jsdom + `@testing-library/react`; the terminals (xterm) are mocked so tests stay deterministic.
- `test/app.test.tsx` — workbench renders, open changed file → diff tab, edit → dirty tab, content search returns hits.
- `test/app-interactions.test.tsx`**Pass-on-to-Agent** emits exactly `"<note> <path:line>"` via the `agentPaste` event; **stage → commit** toasts.
- `test/editor-modes.test.tsx` — Updated mode is editable / Original is read-only; Split opens the two-pane overlay and Esc collapses it.
- **49 tests total, all green.**
- `.github/workflows/ci.yml` — runs typecheck · lint · test · build on push/PR.
### 7. Finish to the DESIGN.md spec — done
Audited `DESIGN.md` section by section and closed every remaining behavioral gap:
- **Session restore** (`session.restoreOnLaunch`, §9) — open tabs, active tab, and per-tab view modes are restored per project (persisted in localStorage, keyed by root); splitter layout already persisted.
- **Close-dirty tab** (§5) — now a real **Save / Don't Save / Cancel** native dialog (was discard-or-cancel). `⌘S` save unchanged.
- **Unsaved indicator** (§5) — a **dot in place of the close control** (× returns on hover), matching the spec exactly (was a dot after the name).
- **New config keys, all wired**: `git.confirmStage` / `git.confirmUnstage` (default off, prompt when on), `git.defaultDiffMode` (drives the starting mode), `files.exclude` + `files.followGitignore`, `session.restoreOnLaunch`.
- **Unified file source**: `rg --files` is now the single source for the **Explorer tree + content index + search**, so **gitignore and `files.exclude` are honored consistently everywhere** (fs-walk fallback when ripgrep is absent). Dotfiles (`.env`, `.gitignore`) included via `--hidden`.
- **⌘P** aliases the unified search — no separate Go-to-File overlay, per the resolved decision (CLAUDE.md/README).
- Tests now **51** (added `buildTreeFromPaths`, gitignore-in-repo, updated dirty-tab class).
### 8. Live-run bugfix (found by running `npm run dev`)
- **Symptom:** the real Electron window showed mock "console" data and both terminals said "not available in browser preview" — i.e. `window.helder` was undefined in the actual app, so the renderer fell back to mock mode.
- **Cause:** electron-vite built the preload as `out/preload/index.mjs`, but `main/index.ts` loaded `../preload/index.js` (wrong extension) → Electron silently loaded no preload → no bridge.
- **Fix:** build the preload as **CommonJS `index.cjs`** (loads synchronously before the page, so `contextBridge` is exposed by the time React mounts) and point `main` at `../preload/index.cjs`. Verified the built `index.cjs` exposes `helder` and main references it. **Re-run `npm run dev` to confirm the live window now loads the real project + terminals.**
## Final state (all green)
- `npm run typecheck` ✓ · `npm run lint` ✓ (0 errors, 8 intentional warnings) · `npm test` ✓ (51) · `npm run build` ✓ · `npm run pack` ✓ (`Helder.app` with icon + unpacked native binaries)
- **DESIGN.md is now fully implemented** (the only intentional exception is the separate Go-to-File overlay, replaced by ⌘P→unified-search per the resolved decision).
- Everything left **uncommitted** for your review (laptop is read-only on git).
- The only thing not exercisable in this headless session remains the live Electron GUI — `npm run dev` to see it.