Rename CritterScope → Drones (repo, subdomain, branding)

Worker + subdomain now drones.theradicalparty.com; in-app title/brand,
package names, docs updated. D1 database binding kept as-is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
King Omar 2026-07-25 17:56:53 +10:00
parent 48866acc97
commit 224792550f
12 changed files with 25 additions and 24 deletions

View file

@ -1,4 +1,4 @@
# 🛰️ CritterScope
# 🚁 Drones
Turn a drone survey into **georeferenced animal/object detections on a 3D map.**
@ -15,7 +15,7 @@ testable before any drone arrives. Real footage feeds the *same* dashboard via
- **Cloudflare Worker + Hono** (`src/index.js`)
- **MapLibre GL JS** — satellite imagery + Terrarium DEM for real 3D terrain (no API key)
- **D1** (optional) — stores real surveys/detections; schema in `schema.sql`
- Deploys to `critterscope.theradicalparty.com`
- Deploys to `drones.theradicalparty.com`
## Run locally
```bash
@ -41,7 +41,7 @@ Open `/` for the dashboard. Point it anywhere:
`type``deer | fox | rabbit | boar | kangaroo | person | vehicle | unknown`.
## Feeding real drone data
1. `wrangler d1 create critterscope`, paste the id into `wrangler.toml`, uncomment the binding.
1. `wrangler d1 create drones`, paste the id into `wrangler.toml`, uncomment the binding.
2. `npm run db:init`
3. `POST /api/ingest` with `{ survey, flight, detections }`.
4. View it at `/?survey=<id>`.

View file

@ -1,5 +1,5 @@
{
"name": "critterscope",
"name": "drones",
"version": "0.1.0",
"description": "Thermal/RGB drone survey → georeferenced animal detections on a 3D map",
"private": true,

View file

@ -1,7 +1,7 @@
# CritterScope drone ingest pipeline
# Drones drone ingest pipeline
Turns drone footage + telemetry into georeferenced detections and pushes them to
a CritterScope instance.
a Drones instance.
```
video / RTMP frames + telemetry (DJI .SRT)
@ -24,7 +24,7 @@ would send — proves the whole chain:
cd pipeline
node src/run.js --synthetic --dry-run
```
Push it into a running local CritterScope (with local D1, see root README):
Push it into a running local Drones (with local D1, see root README):
```bash
node src/run.js --synthetic --name "test-survey" --base-url http://localhost:8787
# → View it: http://localhost:8787/?survey=sv-test-survey-...
@ -37,7 +37,7 @@ node src/run.js \
--detector onnx --model yolo-thermal.onnx \
--width 1920 --height 1080 \
--drone "DJI Mavic 2 Enterprise Advanced" \
--base-url https://critterscope.theradicalparty.com
--base-url https://drones.theradicalparty.com
```
## Live RTMP (DJI Fly app livestream)

View file

@ -1,10 +1,10 @@
{
"name": "critterscope-pipeline",
"name": "drones-pipeline",
"version": "0.1.0",
"description": "Drone footage + telemetry → georeferenced detections → CritterScope",
"description": "Drone footage + telemetry → georeferenced detections → Drones",
"private": true,
"type": "module",
"bin": { "critterscope-ingest": "src/run.js" },
"bin": { "drones-ingest": "src/run.js" },
"scripts": {
"demo": "node src/run.js --synthetic --dry-run",
"demo:ingest": "node src/run.js --synthetic --base-url http://localhost:8787"

View file

@ -8,7 +8,7 @@
// - stub: deterministic synthetic detections so the whole pipeline runs and
// can be validated end-to-end without a model or real footage.
//
// The class list is COCO-ish remapped to the CritterScope species vocabulary.
// The class list is COCO-ish remapped to the Drones species vocabulary.
// For thermal you'd train/fine-tune on thermal wildlife imagery; the interface
// is identical.

View file

@ -1,4 +1,4 @@
// POST an assembled survey to a CritterScope instance.
// POST an assembled survey to a Drones instance.
export async function postSurvey({ baseUrl, survey, flight, detections }) {
const res = await fetch(`${baseUrl.replace(/\/$/, "")}/api/ingest`, {

View file

@ -1,5 +1,5 @@
#!/usr/bin/env node
// CritterScope drone ingest pipeline.
// Drones drone ingest pipeline.
//
// video/RTMP frames + telemetry (DJI SRT) → detector → georeferencer
// → survey JSON → POST /api/ingest → view at /?survey=<id>
@ -10,7 +10,7 @@
//
// # real footage:
// node src/run.js --source flight.MP4 --srt flight.SRT --detector onnx \
// --model yolo-thermal.onnx --base-url https://critterscope.theradicalparty.com
// --model yolo-thermal.onnx --base-url https://drones.theradicalparty.com
//
// # live RTMP stream from the DJI Fly app:
// node src/run.js --source rtmp://localhost/live/stream --srt live.SRT --fps 1

View file

@ -1,4 +1,4 @@
-- CritterScope data model.
-- Drones data model.
-- A "survey" is one drone flight over an area; "detections" are georeferenced
-- animals/objects found in that survey. The demo runs off the live simulator,
-- but real drone footage lands here via POST /api/ingest.

View file

@ -69,7 +69,7 @@ app.post("/api/ingest", async (c) => {
return c.json({ ok: true, survey: id, detections: (body.detections || []).length });
});
app.get("/health", (c) => c.json({ ok: true, service: "critterscope" }));
app.get("/health", (c) => c.json({ ok: true, service: "drones" }));
async function loadSurvey(db, id) {
const survey = await db.prepare(`SELECT * FROM surveys WHERE id=?`).bind(id).first();

View file

@ -1,4 +1,4 @@
// The CritterScope dashboard, served as a single self-contained HTML document.
// The Drones dashboard, served as a single self-contained HTML document.
// MapLibre GL JS (free, no API key): satellite imagery + Terrarium DEM for real
// 3D terrain relief. Detections render as species markers draped on the terrain;
// a timeline scrubber replays the survey as the drone flew it.
@ -10,7 +10,7 @@ export function page(cfg) {
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>CritterScope drone wildlife survey</title>
<title>Drones drone wildlife survey</title>
<link href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel="stylesheet" />
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
<style>
@ -56,7 +56,7 @@ export function page(cfg) {
<div id="loading">Loading terrain &amp; survey</div>
<div id="hud" class="panel">
<h1>🛰 CritterScope <span id="mode" class="badge sim">SIM</span></h1>
<h1>🚁 Drones <span id="mode" class="badge sim">SIM</span></h1>
<div class="sub" id="surveyName"></div>
<div class="stats">
<div class="stat"><b id="sTotal">0</b><span>detections</span></div>
@ -230,6 +230,7 @@ playBtn.onclick=()=>{
// initialise clock once loaded
const _origRender=renderSurvey;
</script>
<script src="https://theradicalparty.com/footer.js" data-mode="pill" defer></script>
</body>
</html>`;
}

View file

@ -5,7 +5,7 @@
# The live deploy uses wrangler.toml (simulator; no D1) until a D1-capable
# Cloudflare token is available — then move this binding into wrangler.toml
# with the real database_id.
name = "critterscope"
name = "drones"
main = "src/index.js"
compatibility_date = "2024-11-01"
compatibility_flags = ["nodejs_compat"]

View file

@ -1,12 +1,12 @@
name = "critterscope"
name = "drones"
main = "src/index.js"
compatibility_date = "2024-11-01"
compatibility_flags = ["nodejs_compat"]
routes = [{ pattern = "critterscope.theradicalparty.com", custom_domain = true }]
routes = [{ pattern = "drones.theradicalparty.com", custom_domain = true }]
[vars]
BASE_URL = "https://critterscope.theradicalparty.com"
BASE_URL = "https://drones.theradicalparty.com"
# Default map center [lon, lat] and survey radius (metres). Override per-survey via ?lat=&lon=&r=
DEFAULT_LON = "150.3119"
DEFAULT_LAT = "-33.7300"