diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..609fd810 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,106 @@ +# RTL — notes for AI coding agents + +RTL (Ride The Lightning) is a device-agnostic web UI for Lightning node operations: +an Angular single-page frontend plus a Node/Express backend, both TypeScript. + +`CONTRIBUTING.md` is the process document — how to install, run the dev servers, package a +build, open a PR, add a library, and handle Dependabot. **Read it first.** This file covers +only the things that are easy to get wrong and aren't obvious from the tree. + +## Source vs. generated — read this before editing anything + +| Directory | What it is | Edit it? | +|-------------|-----------------------------------|----------| +| `src/` | Angular frontend source | yes | +| `server/` | Express backend source | yes | +| `frontend/` | Built AOT bundle, **committed** | never by hand | +| `backend/` | Compiled `server/` output, **committed** | never by hand | + +`frontend/` and `backend/` look like ignorable build artifacts, but they are tracked in git +and are expected to stay in sync with the sources. So a code change is a two-step edit: +change `src/`/`server/`, then rebuild and commit the regenerated output in the same PR. + +```bash +npm run buildbackend # tsc: server/ -> backend/ +npm run buildfrontend # ng build --configuration production: src/ -> frontend/ +``` + +`backend/` is a plain `tsc` transpile of `server/`, so it changes only when `server/` does — +a dependency bump alone won't move it. `frontend/` is a bundle, so it also carries the app +version and any bundled dependency. + +## The three-implementation pattern + +RTL supports three Lightning implementations, and the layout mirrors that everywhere: + +``` +src/app/{lnd,cln,eclair,shared}/ +server/controllers/{lnd,cln,eclair,shared}/ +server/routes/{lnd,cln,eclair,shared}/ +``` + +A feature or fix usually touches the matching folder in **each layer** for the +implementations it affects; genuinely cross-cutting logic belongs in `shared/`. When fixing a +bug in one implementation, check whether the same shape exists in the other two — they +frequently do, since the controllers were written in parallel. + +## Commands, and where they bite + +- **Install with `npm ci --legacy-peer-deps`**, not `npm install`. Plain `npm ci` fails on an + `ERESOLVE` conflict from `@fortawesome/angular-fontawesome`. +- **`npm run server` only works on Windows** — it sets `NODE_ENV` with `set X=Y&&` syntax. On + macOS/Linux use `npm run serverUbuntu`. +- **`npm run lint` and `npm run test` must both be green before a PR.** +- If lint reports hundreds of template "Parsing error" failures, look for a stale + **`coverage/`** directory (git-ignored Karma output). The template linter walks its HTML + report. Delete it and re-run. +- The repo README is at **`.github/README.md`** — there is none at the root. + +## Branches and releases + +- **PRs target the current `Release-x.y.z` branch, not `master`.** Because release branches + merge into `master` by *rebase*, a `Fixes #N` reference never auto-closes its issue (GitHub + only does that for the default branch) — close it manually after the merge. +- **Every PR adds its own release-note entry**, in the same PR as the change: + `release-notes/Release-notes-.md`, under `## Bug Fixes`, `## Enhancements`, + `## Code Health` or `## Developer Tooling`. Create the file if it doesn't exist yet. + Link the PR and any issue, and state the root cause briefly. Because the PR number isn't + known until the PR exists, commit the entry with `#TBD` and follow up with a + `Fill in PR number in release note (#N)` commit. + +### If a release ships while your PR is open + +The rebase-merge rewrites every commit of the release branch to a new hash, and the next +release branch is cut from `master` — so a branch based on the old release branch shares no +recent ancestor with the new one. Retargeting it makes the merge base collapse to before the +release cycle, and GitHub replays the entire cycle into your PR: hundreds of files, and a +`CONFLICTING` state. Replay just your own commits instead: + +```bash +git rebase --onto Release- Release- +``` + +Then confirm `git diff Release-..` is identical to +`git diff Release-..` before force-pushing. Retargeting *before* the release +branch is merged avoids the problem entirely. + +## Testing against real nodes + +`docker/` is a self-contained regtest fixture — bitcoind, three LND nodes, Core Lightning and +Eclair, wired to RTL — for end-to-end testing across all three implementations. See +`docker/README.md`, or the `rtl-docker-fixture` skill in `.claude/skills/`. It is dev-only; +every credential in it is throwaway. + +Backend code has no unit-test harness; `npm run test` runs the frontend Karma/Jasmine specs. +For backend changes, verify against the fixture and say so in the PR. + +## Conventions + +- **Be conservative about dependencies.** This is security-sensitive software. Prefer what's + already there, and raise an issue before adding anything. Never run `npm audit fix` — it + reaches for breaking major bumps. Dependabot PRs are batched, not merged individually; see + `CONTRIBUTING.md`. +- Match the surrounding code's style, naming and structure. Only fix style in code you're + already changing. +- `RTL-Config.json` is local runtime config and git-ignored; `Sample-RTL-Config.json` is the + template, and `RTL.conf` is an alternate config format.