# Setting up your own BidBrain

This is a copy of BidBrain, a daily car buying assistant that reads the new
stock on Motorway and Carwow, applies your buying rules, works out the most you
should pay for each car, and shows them on a private web page you open on any
device. It recommends only. You place every bid yourself.

It contains the code and the rulebook, but NONE of the original owner's data,
logins, margins or certificates. You set it up with your own accounts.

The fastest way to set this up is to open this folder in Claude Code (your own
Claude) and say: "Read CLAUDE.md and help me set up BidBrain for my business."
CLAUDE.md is the full architecture and decision log. Everything below is the
short version.

## 1. Get a released version, not the live branch

The `main` branch moves as the current owner keeps building on it day to day,
mid change and not always tested. `git tag -l` and the repo's Releases page
list the actual finished versions (v1, v2, v2.1 and onward); install from the
latest one of those, not from `main`, so you get a complete, working copy.

```
git clone git@github.com:CarDealer-OS/Bidbrain.git
cd Bidbrain
git checkout v2.7.12   # or whatever the latest tag is, see the Releases page
```

When a newer version comes out later, update the same way rather than pulling
`main`:

```
git fetch --tags
git checkout v2.2     # the new tag, once you are ready to move to it
```

Once the cockpit is running (step 8), this is also one click from the page
itself: Settings > Integrations has a "Software update" card showing whether
a newer release exists, with an "Update now" button that does the same
`git fetch`/`checkout` and restarts the server for you.

`dealer_config.py`, your local database and your saved logins all live outside
git and are untouched by switching versions (see step 5 and `.gitignore`).

## 2. What you need

- A Mac that stays on (this runs a small always on server). It also works on the
  Mac you sit at day to day.
- Python 3 (built in on macOS).
- Accounts you already have: Motorway dealer, Carwow dealer, Glass's, Cazana
  (now branded Percayso). No APIs are used, it reads the logged in screens.
- Auction4Cars and Dealer Auction are also supported now if you buy there too,
  same as Motorway and Carwow, just log in as normal (step 4). Neither needs a
  saved search URL the way Motorway and Carwow do (see step 5), the buying
  rules filter the full list instead, only slower. Skip either one entirely if
  you do not use it, nothing else depends on it.

## 3. Install

```
python3 -m pip install --user playwright
python3 -m playwright install chromium
```

That is the only dependency. Everything else is Python standard library.

## 4. Log into your accounts (your own, once)

```
python3 login.py motorway
python3 login.py carwow
python3 login.py glass
python3 login.py cazana
```

Each opens a browser window. Log in as normal, then say so and it saves the
session so the daily run does not need you again. For Glass's, tick "Don't ask
for 30 days".

If you also use Auction4Cars or Dealer Auction, log into those the same way,
adding `manual` on the end (`python3 login.py auction4cars manual`, `python3
login.py dealerauction manual`): these two, plus Glass's and Cazana, do not
auto detect a successful login the way Motorway and Carwow do, so `manual`
mode waits for you to say you are done instead of guessing. Dealer Auction
sometimes has an SMS 2FA step, just complete it in the window as normal.

Once the cockpit is running (step 8), any of these can also be redone later
straight from the page itself: Settings > Integrations has a "Log in to X"
button per site (opens the same window), and a saved session's own age is
shown right there too, so you can see at a glance if one has gone stale
without waiting for a run to fail first.

## 5. Point it at YOUR saved searches

Copy `dealer_config.example.py` to `dealer_config.py` (this file is
gitignored, it stays on your Mac and is never shared or committed, and stays
put across a `git checkout` to a newer version). Fill in:

- `MOTORWAY_STOCK_URL`: in the Motorway dealer site apply your own saved
  search, then copy the address bar URL and paste it in.
- `CARWOW_SAVED_FILTER_ID`: apply your own Carwow saved filter, copy the
  `saved_filter_id` from the address bar and put it in.
- `ACCOUNTS_EMAIL`: where the daily new purchase email should go, if you use
  that (see `purchases_run.py`).
- `DEALER_NAME`: only if another dealership on this same repo has agreed to
  let CompMatch (the suggested bid model) learn from your data too, and
  vice versa. Leave blank otherwise. See `shared_comps/README.md`.

## 6. Make the buying brain yours

Most of this is now editable straight from the cockpit, no code or Claude
needed: once it is running (step 8), open Settings (the wrench icon) for the
pricing formula (the flat spread and retail uplift) and each platform's own
hard gate (mileage, reserve, age, distance or allowed depots/counties, grade,
owners), edited on its own tab per platform since Motorway, Carwow, Auction4Cars
and Dealer Auction can each have different limits.

The rest still lives in `bidbrain/pricing.py`, covered by `test_pricing.py`:
the governing value threshold (10000), banned makes, banned models, banned
engines and value caps, all deliberately left code only rather than a setting,
since a malformed edit there could let something through it should not.

Change what you want, then run `python3 test_pricing.py` and keep the changes
only if the tests pass. Your own Claude can do this for you and add tests.

## 7. You do not use Clickdealer

Clickdealer is only used for the "in stock / fills a gap" flags. Nothing else
depends on it. You have two easy options:

- Simplest, and no code or Claude needed: leave DealerKit stock read switched
  off in Settings > Integrations (its own on/off toggle, alongside DealerKit
  purchases push, Glass's checks and anything else on that tab). The daily run
  already treats a failed or skipped stock read as non fatal, it carries on
  without the gap flags, no banner nags you about it once the toggle is off.
- Or point the stock read at your own DMS if it has an in stock list. The
  original owner's own DMS is DealerKit (`bidbrain/readers/dealerkit.py`), the
  one before that was Clickdealer (`bidbrain/readers/clickdealer.py`, still
  there, unused, if that happens to be yours instead); either way your own
  Claude can build a reader with the same shape for whatever you actually use.

(The monthly learning loop, `monthly_run.py`, still only reads Clickdealer sales
reports. If you do not use Clickdealer you can skip the monthly run, or have your
Claude adapt it to your own DMS's sales export.)

## 8. Run it

```
python3 daily_run.py          # read, price, build the page (run after 5pm)
python3 serve.py              # serve the page at http://localhost:8765/cockpit.html
```

Open http://localhost:8765/cockpit.html. Star the cars you want, hide any you do
not. The Run button opens a modal to refresh one platform or all of them; Glass's
checks, DealerKit and anything else you have switched on in Settings >
Integrations live under "Other checks" in that same modal.

Important: never run the read between 3:30pm and 5:00pm. Both platforms close the
day's sale at 3:30pm and only show the next day's stock after 5:00pm.

## 9. Private web address (optional)

To reach the page from your phone, use Tailscale Funnel (free, no domain). Set it
up on your Mac, sign in, then:

```
/Applications/Tailscale.app/Contents/MacOS/Tailscale funnel --bg 8765
```

That gives you your own unguessable https link. Do NOT reuse the original owner's
link or certificates, you generate your own.

## 10. Automate it (optional)

The original uses macOS launchd to keep the server up permanently, and to run
the daily job in TWO staggered slots rather than one, matching Motorway and
Carwow's own different stock times: Motorway alone shortly after 4:30pm
(`--platforms motorway`), then everything else (Carwow, Auction4Cars, Dealer
Auction, DealerWay) shortly after 5:00pm (`--platforms carwow,auction4cars,
dealerauction,dealerway`), so Motorway is not needlessly re read a second
time half an hour later. Your Claude can set up the same LaunchAgents for
you, timed to your own saved searches, pointed at your folder. See the
"launchd" notes in CLAUDE.md.

The three daily reads that need no login of their own (Didn't win sync,
Under offer check, CompMatch sync) install themselves in one line, in
Terminal, inside the BidBrain folder:

    python3 setup_schedule.py --install

Run it with no words to see every BidBrain job the Mac has. Pick your own
times with, say, `--install lost_bids=16:05 under_offer=16:30
compmatch=16:45`, and take one out with `--remove lost_bids`. Keep them
clear of your Purchases sync and daily run: the first two share the one
Motorway browser profile with those.

## A note on the rules and history in CLAUDE.md

CLAUDE.md is the original owner's full decision log, including his specific buying
rules and some of his operational detail. It is the best guide to how everything
works, but treat the specific rules, thresholds and any links as HIS, and change
them to yours as you go. CLAUDE.md itself lives on `main` and keeps growing with
every change, so the copy of it inside your chosen release tag is the one that
actually matches the code you are running; the one on `main` may describe things
not yet in any released version.
