|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## What this is |
| 6 | + |
| 7 | +Hypr is a desktop REST API client (like Postman/Insomnia) built with **Wails v2** (Go backend + React/TypeScript frontend). The Go HTTP client does the actual network calls; the React app is the UI. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +| Command | What it does | |
| 12 | +|---------|-------------| |
| 13 | +| `wails dev` | Live dev mode — Vite HMR for the frontend + Go backend. Also serves a browser dev server at `http://localhost:34115` where Go methods are callable from devtools. | |
| 14 | +| `wails build` | Production build — embeds `frontend/dist` and outputs a native executable named `hypr` (per `wails.json`). | |
| 15 | +| `go mod tidy` | Sync Go dependencies. | |
| 16 | +| `wails doctor` | Check the Wails toolchain / native prerequisites. Run this before `wails dev` on a fresh machine. | |
| 17 | +| `npm run build` (in `frontend/`) | `tsc && vite build`. Wails runs this automatically during `wails build`; run it manually to typecheck. | |
| 18 | + |
| 19 | +Go has unit tests — run them with `go test ./...` (curl parser and HTTP helpers; see `parse_curl_test.go`, `app_test.go`). The frontend has **no test runner**; its only check is `tsc` via the build. There is **no lint/format/CI** config. |
| 20 | + |
| 21 | +**Go changes are not hot-reloaded** — `wails dev` only HMRs the frontend. Restart `wails dev` after editing Go. |
| 22 | + |
| 23 | +## Architecture |
| 24 | + |
| 25 | +The frontend↔backend boundary is the only non-obvious part. Wails binds the Go `App` struct (`main.go`, `Bind: []interface{}{app}`) and code-generates TypeScript wrappers into `frontend/wailsjs/`. The React app imports those wrappers (`../wailsjs/go/main/App`) and calls Go methods as promises. |
| 26 | + |
| 27 | +**Three bound Go methods** (all on `App`, all callable from React): |
| 28 | +- `MakeRequest(url, method, body, headers)` — builds and sends the HTTP request via the shared `http.Client` (50s timeout, created in `startup`), returns a `RequestResult`. JSON response bodies are pretty-indented server-side. |
| 29 | +- `RunCurl(curl)` — parses a curl string into a `Request`, then calls `MakeRequest`. |
| 30 | +- `Export(req, reqHeaders, reqBodies, result)` — opens a native save dialog and writes the request/response as JSON. |
| 31 | + |
| 32 | +`RequestResult` (`app.go`) is the single response shape returned to the UI: `Body`, `HeadersStr` (newline-joined response headers), `Error`, plus echoed-back request fields. Errors are returned **inside** `RequestResult.Error`, not as a thrown/rejected promise — the UI checks `result.Error`. |
| 33 | + |
| 34 | +**Curl parsing** (`parse_curl.go`): a hand-written state machine over `go-shellwords` tokens. Supports `-X/--request`, `-H/--header`, `-d/--data[-ascii|-raw]`, `-A/--user-agent`, `-u/--user` (→ Basic auth), `-I/--head`, `-b/--cookie`. Does **not** handle `--data-binary`, `--data-urlencode`, or multipart. Input must start with `curl `. |
| 35 | + |
| 36 | +**Frontend state** (`frontend/src/App.tsx`): the UI is multi-tab ("Request 1", "Request 2", …). State is held as **parallel arrays indexed by tab** — `reqBodies[]`, `reqHeaders[][]`, `responses[]` — all kept in sync in `addNewTab`/`closeTab`. When editing tab logic, update all three arrays together or they desync. Headers in the UI are `{Key, Value}` objects (`src/lib/header.ts`); they're converted to a plain `Record<string, string>` before being passed to Go (which expects `main.Headers`). |
| 37 | + |
| 38 | +**UI stack**: the frontend uses **Tailwind CSS + shadcn/ui** (Radix primitives in `frontend/src/components/ui/`, `cn` helper in `src/lib/utils.ts`, design tokens as CSS variables in `src/index.css`, theme in `tailwind.config.js`). Icons are `lucide-react`. JSON responses are highlighted by the in-house `src/components/json-view.tsx` (no `react-json-pretty`). The `@/*` import alias maps to `src/`. |
| 39 | + |
| 40 | +## Gotchas |
| 41 | + |
| 42 | +- **Go module is named `changeme`** (`go.mod` placeholder, never renamed). Build works because Wails manages it; rename before publishing/importing. |
| 43 | +- **`frontend/hypr/` is a stale leftover** — a complete nested Wails scaffold (its own `go.mod`, `main.go`, `build/`, `frontend/`). It is **not** part of the real app (the real entry point is the root `main.go`). Don't edit files there expecting them to take effect. |
| 44 | +- **`frontend/wailsjs/` is generated** — `App.d.ts`/`App.js`/`models.ts` are regenerated by Wails from the Go structs. Don't hand-edit; change the Go types and rebuild. |
0 commit comments