Let the extension update itself, and host the dashboard

Chrome has no update channel for an unpacked extension, so every pull left one
manual step: click reload on its card. The dashboard now publishes the version
its own checkout ships at /api/autobuyer/status, and the extension reloads
itself when it is behind — chrome.runtime.reload() re-reads the folder from
disk, which the update check has already pulled into. It only ever runs code
that is on disk, so a reload that changes nothing is reported and waited out
rather than repeated; a dashboard that is behind is ignored.

Also adds the deploy stack for running the dashboard on the droplet, next to
the autotrader one: it joins that nginx's network and renders a server block
into its conf.d rather than standing up a second ingress. AUTOFIRMER_DB moves
the SQLite file onto a volume, since the working directory in a container is
replaced on every deploy.

And waitFor gained `hidden`: an absent gate matched on DOM presence only, so a
modal that closes by going display:none could never satisfy it. The extension
grew a visibility probe for this — locate cannot answer it, because absent and
hidden are both errors there and a wait gate has to tell them apart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-08-31 12:30:59 -05:00
co-authored by Claude Opus 5
parent 1f4459985a
commit d1e8668440
18 changed files with 637 additions and 28 deletions
+30
View File
@@ -0,0 +1,30 @@
# The dashboard, alongside the autotrader stack rather than instead of it: the
# droplet already runs one nginx on 80/443, and this joins that network so the
# same ingress can proxy to it. Nothing here publishes a host port.
name: autofirmer
services:
autofirmer:
build:
context: ..
dockerfile: Dockerfile
image: autofirmer:local
container_name: autofirmer
restart: unless-stopped
environment:
AUTOFIRMER_DB: /data/autotrader.sqlite
volumes:
- autofirmer-data:/data
expose:
- "3000"
networks: [web]
networks:
# Created by the autotrader stack. `external` so this compose file never tries
# to own it — bringing this stack down must not take the ingress with it.
web:
name: ${SHARED_NETWORK:-autotrader-vps_web}
external: true
volumes:
autofirmer-data: