[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81541":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":16,"stars30d":13,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":15,"starSnapshotCount":15,"syncStatus":14,"lastSyncTime":26,"discoverSource":27},81541,"satlas","PremaanshVyas\u002Fsatlas","PremaanshVyas","Real-time space situational awareness, with an AI agent at the front door.","https:\u002F\u002Fsatlas.app",null,"TypeScript",30,4,2,0,1,3,2.1,"MIT License",false,"main",[],"2026-06-12 02:04:16","\u003Cdiv align=\"center\">\n  \u003Cimg src=\"apps\u002Fweb\u002Fpublic\u002Ffavicon.svg\" alt=\"Satlas\" width=\"96\" height=\"96\" \u002F>\n  \u003Ch1>Satlas\u003C\u002Fh1>\n  \u003Cp>\u003Cem>Real-time space situational awareness, with an AI agent at the front door.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\nA live, open platform that lets anyone explore what's happening in Earth orbit — every tracked satellite, rocket body, and piece of debris, visualised in 3D and queryable in plain English.\n\n**Live demo:** [satlas.app](https:\u002F\u002Fsatlas.app) · [![Sponsor](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fsponsors\u002FPremaanshVyas?label=Sponsor&logo=github)](https:\u002F\u002Fgithub.com\u002Fsponsors\u002FPremaanshVyas) (also [getsatlas.vercel.app](https:\u002F\u002Fgetsatlas.vercel.app))  \nOpen the site — 30,000+ tracked objects orbit Earth in real time across their actual altitudes (LEO, MEO, GEO shells visually distinct), fetched from the US Space Force catalog and propagated in a web worker. A real-time cloud layer drapes the globe; a star field from NASA's Gaia DR2 catalog fills the background.  \nAsk: _\"When does the ISS pass over Melbourne tonight?\"_ — it does real orbital mechanics to answer.  \nAsk: _\"Show me where the ISS is right now\"_ — it answers **and** flies the 3D globe camera to the ISS, pulsing it three times.  \nAsk: _\"Show all Starlink satellites\"_ — it highlights every Starlink dot in violet while dimming everything else.  \nAsk: _\"How many GPS satellites are tracked?\"_ — reads the live count from the globe, no tool call needed.  \nAsk: _\"What satellites are overhead right now from Sydney?\"_ — it queries the catalog and tells you.  \nHover any dot for name + altitude. Click to select (multiple selections supported) — see the info card with live lat\u002Flon\u002Faltitude\u002Fvelocity, orbital parameters, and satellite metadata (owner, launch date, launch site). Hit \"Ask AI\" to query it.  \nCategory filter pills toggle entire groups on\u002Foff. Cloud layer and Debris toggles in the top-right. Enable the Borders toggle to switch to map mode — country fills, graticule, and country name labels appear; click any country to see which satellites are overhead right now.  \nOpen the Pass Prediction panel from any satellite info card — enter or geolocate your position; see every visible pass in the next 24 hours with times, max elevation, and approach direction.  \nThe agent remembers conversation context — follow-up questions work.  \n**API docs** at [satlas.app\u002Fdocs](https:\u002F\u002Fsatlas.app\u002Fdocs) — curl-ready examples for every endpoint.  \n**Status:** V1 live — custom domain (satlas.app), HTTPS on ALB, ECS Fargate + S3\u002FCloudFront\u002FRDS all deployed, pass prediction for any location, satellite metadata (owner\u002Flaunch date\u002Fsite) from Space-Track, public API docs.\n\n---\n\n## The pitch\n\nExisting space situational awareness (SSA) tools are either expensive enterprise systems sold to defence and large operators, or fragmented amateur sites that show one slice of the picture. Most students, amateur astronomers, journalists, and curious people don't have a unified, modern view of what's overhead.\n\nSatlas changes that. You open the site and see Earth, with every tracked object orbiting in real time. You ask: _\"What's that bright thing crossing Melbourne tonight?\"_ The AI agent reasons over orbital data, satellite imagery, and a knowledge base, and tells you — while highlighting the object on the globe.\n\nThat's the front door. Behind it sits a stack of services that any developer can also call directly:\n\n- **Orbital compute** — pass predictions, conjunction analysis, position propagation\n- **Vision pipeline** — Earth observation imagery (Sentinel-2) with computer vision overlays (fire scars, urban change)\n- **Knowledge RAG** — semantic search across mission docs, satellite catalogs, public space data\n\nEverything is open source. Public API. Free for non-commercial use.\n\n---\n\n## Why this exists\n\n**Most people don't realise how busy orbit is.** There are over 30,000 tracked objects and hundreds of thousands of pieces of untracked debris. Showing this is a public good.\n\n**Australia has growing space infrastructure but limited public-facing tools.** Tidbinbilla, the Australian Space Agency, university CubeSat programs — there's no single place a student in Melbourne can see what's overhead and when.\n\n**AI agents over real data is the interesting frontier.** Most \"AI\" products are chat wrappers around an LLM. This is a working example of an agent that orchestrates real scientific computation, image analysis, and knowledge retrieval to answer questions a single API call can't.\n\n---\n\n## Architecture\n\n```\n                    [ Frontend (React + Three.js) ]\n                                  |\n                         [ AI Agent (Claude API) ]\n                                  |\n        +-------------------------+-------------------------+\n        |                         |                         |\n[ Orbital compute ]      [ Vision pipeline ]      [ Knowledge RAG ]\n FastAPI + skyfield       PyTorch + Sentinel-2      pgvector + Postgres\n```\n\nThe AI agent doesn't generate orbital math. It calls tools that do. Every user query becomes one or more typed tool calls, and the agent composes the results.\n\n---\n\n## Tech stack\n\n| Layer | Tech | Status |\n|---|---|---|\n| Frontend | TypeScript, React, Three.js, Tailwind, Vite | Live at satlas.app |\n| Agent | Anthropic Claude API (Haiku + Sonnet) with tool use | Live |\n| Orbital compute | Python FastAPI + skyfield (ECS Fargate) + satellite.js (browser worker) | Live — backend API at api.satlas.app |\n| Satellite catalog | S3 + CloudFront (TLE + satcat from Space-Track, refreshed hourly by a single ECS worker; all reads served from CloudFront) | Live |\n| CI\u002FCD | GitHub Actions — lint + typecheck + vitest + pytest + Docker build + ECR push | Live |\n| Infra | Terraform: ECS Fargate, RDS PostgreSQL, S3+CloudFront, ALB, ACM, Route 53, ECR | Live |\n| Frontend hosting | Vercel — frontend + AI agent\u002Fpass\u002Fcatalog functions | Live |\n| Database | PostgreSQL 15 + pgvector + PostGIS (RDS) — schema migrated | Live |\n\n---\n\n## Data sources (all public)\n\n- **TLE catalogs** — Space-Track.org (free with registration) via ECS → S3 → CloudFront pipeline\n- **Satellite imagery** — Sentinel-2 via [Sentinel Hub](https:\u002F\u002Fwww.sentinel-hub.com\u002F) and Copernicus\n- **Space weather** — [NOAA SWPC](https:\u002F\u002Fwww.swpc.noaa.gov\u002F)\n- **Ground station coordinates** — public ephemerides\n- **Knowledge corpus** — NASA\u002FESA mission documentation, public CubeSat datasheets\n\n---\n\n## Roadmap\n\n### What's working now\n- [x] 3D Earth with real-time cloud layer (clouds.matteason.co.uk, updates ~3h, AdditiveBlending)\n- [x] NASA Gaia DR2 star field skybox — denser and higher quality than procedural stars\n- [x] 30,000+ tracked objects at actual orbital altitudes (LEO\u002FMEO\u002FGEO shells visually distinct)\n- [x] ISS rendered separately with yellow dot; catalog satellites colour-coded by type\n- [x] Dot sizing by type: GEO satellites 1.5× base size, debris 0.6× and dimmer\n- [x] Satellite trails — last 10 minutes of ECEF path on selected satellite, lime→transparent fade\n- [x] Multi-satellite selection tray — click multiple satellites; each gets its own orbit ring; tray chip ✕ removes; card ✕ closes info only\n- [x] Satellite info card — live lat\u002Flon\u002Faltitude\u002Fvelocity + orbital parameters + metadata (country, launch date, launch site, status) from Space-Track\n- [x] Text search — type to find any satellite by name or NORAD ID; keyboard-navigable results\n- [x] Hover tooltip — satellite name + altitude; hovered\u002Fselected satellites highlight lime green\n- [x] Category filter pills — Starlink \u002F GPS \u002F Iridium \u002F Debris \u002F Other with instant Uint8Array mask; debris off by default\n- [x] Cloud layer + Debris toggles — show\u002Fhide independently from the globe overlay\n- [x] Borders \u002F map mode — dark navy fill, country borders, lat\u002Flon graticule, country name labels; lazy GeoJSON fetch\n- [x] Country click → CountryPanel — shows all satellites overhead (>10° elevation) at that moment, tiered by elevation\n- [x] Search fly-to — selecting a satellite from search flies the camera directly to it\n- [x] AI agent answers questions with real orbital mechanics (skyfield pass prediction, satellite lookup)\n- [x] Agent-driven globe interaction — \"show me the ISS\" flies the camera and pulses it\n- [x] Agent-controlled category filter — \"show only Starlink\" applies filter + colours; pill state stays in sync\n- [x] AI category counts — \"how many GPS satellites?\" reads live counts from globe (no tool call)\n- [x] Multi-turn conversation history — follow-up questions work\n- [x] Find satellites overhead from any location (\"what's visible from Sydney right now?\")\n- [x] Look up any satellite by name or NORAD ID — live orbital snapshot + globe highlight\n- [x] Melbourne-accurate timestamps (computed server-side, never guessed by the AI)\n- [x] Mobile-friendly layout — 100dvh + safe-area insets so overlays clear browser chrome on iOS\u002FAndroid\n- [x] Pass prediction panel — geolocate or search any location; next 24h passes with time, duration, max elevation, direction, sky condition (Day\u002FTwilight\u002FNight), satellite illumination status, and visibility score (0–100%)\n- [x] Search dropdown always shows a catalog-name tip — some satellites appear under catalog IDs; try NORAD ID if a name search misses\n- [x] Developer notes panel — \"i\" button (bottom-right) opens a toggleable panel with notes from the developer; hides when chat is open\n- [x] Public API with docs at satlas.app\u002Fdocs — 6 endpoints, curl-ready examples\n- [x] Custom domain satlas.app with HTTPS (ACM cert, ALB HTTPS listener, HTTP→HTTPS redirect)\n\n### V1 (complete)\n- [x] Project scaffolding, monorepo, CI\u002FCD\n- [x] Live TLE catalog (30,000+ objects, InstancedMesh + web worker)\n- [x] Agent tools: predict_iss_passes, highlight_on_globe, find_satellites_overhead, get_satellite_info, set_category_filter\n- [x] Click satellite → details; multi-satellite selection tray; orbital arc + trail\n- [x] Hover tooltip; category filter pills; text search with fly-to camera\n- [x] Cloud layer, star field, dot sizing by type\n- [x] Borders \u002F map mode — country fills, borders, graticule, labels; click country → overhead satellites panel\n- [x] Mobile-responsive layout (100dvh + safe-area insets)\n- [x] AWS infra deployed (ECS Fargate, RDS, S3+CloudFront, ALB, ECR, Route 53, ACM)\n- [x] Pass predictor for any user location (exposed in UI)\n- [x] Public API with docs (satlas.app\u002Fdocs) — 6 endpoints\n- [x] Custom domain + HTTPS on ALB (satlas.app \u002F api.satlas.app)\n- [x] Satellite metadata from Space-Track (owner, launch date, launch site, decay status)\n- [x] Rate limiting + security hardening on all public API endpoints (60 req\u002Fmin\u002FIP, input validation, CSP\u002Fsecurity headers)\n- [x] Space-Track API-compliance hardening — single hourly catalog client, durable per-class rate clocks\n\n### V2 — next up\n- [ ] Conjunction analysis service\n- [ ] Alert subscriptions (email\u002FSMS for ISS pass, debris near asset, etc.)\n- [ ] Vision pipeline integration — Sentinel-2 imagery on demand\n- [ ] First CV use case: bushfire scar detection in Australian regions\n- [ ] Vector RAG over space documentation\n- [ ] Blog post explaining how it all works\n\n### V3 — stretch\n- [ ] Space weather overlay (geomagnetic storms, aurora prediction)\n- [ ] ML-based orbital prediction error correction\n- [ ] Mobile app\n\n---\n\n## Engineering Notes\n\nFull debugging history is in [`CHANGELOG.md`](CHANGELOG.md). A few highlights:\n\n**Vercel Edge Runtime vs Node.js** — Deployed the AI agent endpoint with `runtime: 'edge'` for lower latency. Every request returned 500. Root cause: the Anthropic SDK references `node:fs` and `node:path` internally, which don't exist in V8 edge isolates. Fix was removing the edge config and running as a standard Node.js function. Lesson: edge runtimes are not Node.js — check SDK compatibility before choosing a runtime.\n\n**The CelesTrak double-bug** — The satellite catalog went through three data source changes in two days. First, CelesTrak's `GROUP=active` endpoint blocks Railway's cloud IP range (403). Switched to space-track.org, which worked but its orbital parameter filters (`MEAN_MOTION > 11.25`) intermittently excluded the ISS at certain orbital epochs. Added a dedicated per-satellite CATNR fetch as a guarantee — but the CATNR JSON endpoint returns GP orbital elements, not TLE lines, causing a silent `KeyError` swallowed by a `except: pass`. Final fix: `FORMAT=TLE` for the CATNR endpoint, which returns parseable three-line plain text. Three separate bugs, same symptom (\"ISS not in catalog\").\n\n**TLE age and position accuracy** — The ISS was visually rendering at the wrong position because the prototype used a hardcoded March 2024 TLE baked into source code. The live catalog was fetched for the 1000-satellite field but never applied to the dedicated ISS mesh. Added `SatelliteMesh.updateTle()` to reinitialise the SGP4 propagator from the live catalog on startup. Position now matches major tracking sites within visual margin.\n\n**Globe not flying to satellite after agent response** — The camera highlight worked once, then stopped. Root cause: the second Claude call (answer-streaming turn) had `tools` included in the request. Haiku chose to call `highlight_on_globe` as a tool call in the streaming turn instead of generating text, but the streaming loop only captures `text_delta` events — tool calls are silently dropped. Fix: removed `tools` from the answer-streaming turn (forces text-only output), updated the system prompt to say call `highlight_on_globe` in the same turn as `get_satellite_info` (not after), and increased the first-turn `max_tokens` from 512 to 1024. Lesson: never include tools in a streaming turn unless you're prepared to handle tool_use stop reasons.\n\n**Chatbot reliability — Vercel 10s timeout + Railway cold starts** — The agent chat panel was intermittently returning \"No response\" even for simple questions. Two causes: (1) Vercel Hobby silently ignores `maxDuration: 60` — the hard cap is always 10s. Using Sonnet for the tool-detection turn consumed 3–5s, leaving no headroom for Railway. Fix: tool-detection turn uses `claude-haiku-4-5-20251001` (~1s), streaming answer keeps Sonnet for quality. (2) Railway free-tier sleeps after ~5 minutes; cold start takes 20–30s. Fix: the Globe component now pings `\u002Fhealth` on mount and every 4 minutes, keeping the backend warm for the duration of a user session.\n\n**Coordinate system bug — every satellite over the wrong continent** — The 3D globe was rendering all satellites roughly 90° off in longitude, making ISS over East Africa appear over South America. Root cause: `THREE.SphereGeometry` UV mapping places the prime meridian (lon=0°) at the +X axis in world space. Both the satellite propagation formula and the solar lighting formula independently placed it at +Z — an internally-consistent 90° shift that made satellites coherent with day\u002Fnight but wrong against geography. Fix was changing both formulas to `(r·cos(lat)·cos(lon), r·sin(lat), -r·cos(lat)·sin(lon))` and `(xECEF, zECEF, -yECEF)`. Lesson: write coordinate tests (lon=0° → +X, 90°E → −Z, north pole → +Y) before writing any rendering code, and verify against a known external tracker before shipping.\n\n**CelesTrak FORMAT=json — a mock-divergence bug that hid for three sessions** — The catalog was silently broken since Session 6. `FORMAT=json` returns GP orbital elements but never includes `TLE_LINE1`\u002F`TLE_LINE2`. Our parser accessed those keys → `KeyError` on every real call. Tests passed because fixtures had fabricated those keys. Production fell silently to the SpaceTrack fallback; when SpaceTrack had a transient failure both sources failed and the globe ran ISS-only with no error shown. Fix: switch to `FORMAT=TLE` (standard three-line text), add a `_parse_tle_text()` function, and update fixtures from the actual API response. Lesson: never fabricate fixture data with keys that differ from the real response schema.\n\n**Click-to-select false positives — fixed pixel threshold is wrong for 10k satellites** — A 20px hit zone sounds small, but with 10,000 satellites there is nearly always one within 20px of any click position. The correct approach: compute the actual pixel radius of the rendered dot using `dotRadiusPx = (SPHERE_RADIUS \u002F depth) * fovFactor`, then only accept a hit if `screenDist \u003C= dotRadiusPx + 1`. This matches the visual dot size exactly at any zoom level. Bonus: the prefill includes the NORAD ID so the backend does an exact catalog match instead of fuzzy name search.\n\n**NORAD ID leading-zero mismatch — wrong satellite returned for Cosmos 574** — TLE catalog pads NORAD IDs to 5 digits (`'06707'`); Space-Track satcat omits leading zeros (`'6707'`); the Haiku LLM normalises digit strings and strips the leading zero. Three compounding bugs: `satinfo.py` used string equality so `'6707' != '06707'` → miss, then fell through to name search where `'6707'` is a substring of `'STARLINK-36707'` → wrong satellite returned. Frontend satcat Map used raw Space-Track keys so `get('06707')` found nothing → all metadata dashes. Fix: integer comparison in `satinfo.py` (no leading-zero issue); pad keys to 5 chars in `parseSatcatJson`. Lesson: all NORAD ID comparisons must use integer equality.\n\n---\n\n## Local development\n\n### Prerequisites\n\n- Node.js 20+\n- npm 10+\n- Git\n- An Anthropic API key (free tier works) — get one at [console.anthropic.com](https:\u002F\u002Fconsole.anthropic.com)\n\n### Install\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FPremaanshVyas\u002Fsatlas.git\ncd satlas\nnpm install                  # root deps (Anthropic SDK, satellite.js)\ncd apps\u002Fweb && npm install   # frontend deps\n```\n\n### Run the frontend\n\n```bash\ncd apps\u002Fweb\nnpm run dev                  # Vite dev server → http:\u002F\u002Flocalhost:5173\n```\n\nThe globe loads immediately. Satellite data fetches from CloudFront in the browser — no backend needed to see the globe.\n\n### Run the AI chat locally\n\nThe AI chat endpoint is a Vercel serverless function at `api\u002Fchat.ts`. To run it locally:\n\n```bash\n# Install Vercel CLI (one-time)\nnpm install -g vercel\n\n# Add your Anthropic key at the repo root\necho 'ANTHROPIC_API_KEY=sk-ant-your-key-here' > .env\n\n# Run the Vercel dev server (from repo root)\nnpx vercel dev               # API available at http:\u002F\u002Flocalhost:3000\u002Fapi\u002Fchat\n```\n\nThen add `VITE_CHAT_URL=http:\u002F\u002Flocalhost:3000\u002Fapi\u002Fchat` to `apps\u002Fweb\u002F.env.local` to point the frontend at your local API.\n\n### Run tests\n\n```bash\ncd apps\u002Fweb\nnpx vitest run               # 169 frontend unit tests\nnpx tsc -b --noEmit          # TypeScript type check\nnpx eslint .                 # lint\n\ncd apps\u002Forbital\npytest                       # 113 Python unit tests\n```\n\n---\n\n## Contributing\n\nSolo project for now. Designed to be open. Once MVP is live, see `CONTRIBUTING.md` (to be written).\n\n---\n\n## Author\n\nBuilt by Premaansh (\"mickey\"), software engineering student at RMIT in Melbourne.\n\nIf you're hiring software engineering interns in Australia and what you've just read interests you — get in touch.\n\nLinkedIn: [LinkedIn](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fpremaansh-vyas-30b3b2221\u002F) \nEmail: premaanshvyas04@gmail.com\n\n---\n\n## License\n\nMIT\n","Satlas 是一个实时的空间态势感知平台，通过AI代理提供地球轨道上所有卫星、火箭残骸及碎片的3D可视化查询。项目采用TypeScript编写，具备强大的实时数据处理能力，能够从美国太空部队目录中获取并展示超过30,000个轨道物体的位置信息，并支持自然语言查询。用户可以轻松询问特定卫星的当前位置或预测其未来轨迹等。此外，Satlas还提供了丰富的交互功能如过滤器、详细信息卡片以及基于位置的过境预测，非常适合学生、业余天文学家、记者以及对太空感兴趣的公众使用，为他们提供了一个统一且现代的视角来了解头顶上的太空活动。","2026-06-11 04:05:26","CREATED_QUERY"]