pgx
PGX — Lightweight Postgres for AI agents. Written in Rust. Thousands of isolated databases in one runtime. 🐘
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Bangkok civic intelligence hub — live PM2.5, satellite, alerts. Independent of any vendor platform.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Bangkok civic intelligence / smart-city OS — independent of vendors. Live air, water, traffic, satellite, civic reports, and a bilingual morning brief on one screen. This is not an official product of BMA, DEPA, or any government. It is independent civic software by Non Arkaraprasertkul. Fork it. Run it on one Mac. เมืองที่เข้าใจเรา และเราเข้าใจเมือง — the city that understands us, and we understand the city.檢視完整 README ↗
Bangkok civic intelligence / smart-city OS — independent of vendors. Live air, water, traffic, satellite, civic reports, and a bilingual morning brief on one screen.
This is not an official product of BMA, DEPA, or any government. It is independent civic software by Non Arkaraprasertkul. Fork it. Run it on one Mac.
เมืองที่เข้าใจเรา และเราเข้าใจเมือง — the city that understands us, and we understand the city.
City Hub is a replicable civic intelligence and planning tool. Bangkok is the full-tier city (tier: 'full' in src/config/cities.ts). Other cities in that same registry — Chiang Mai, Phuket, Singapore, Kuching, Kranj, Ljubljana, and more — run on global open sources (tier: 'lite'). Adding a city is one config object; pointing the map at a typed name uses OpenStreetMap Nominatim for a session-only view.
It exists so a resident, journalist, or city operator can open one tab and see what the sensors say next to what the press says, with every figure cited. It is not a brochure dashboard. Layers that are pending, historical, mocked, or key-gated say so in src/config/bangkok-layers.ts.
Since v7 the top bar carries three actions — Compare, Look, Research —
and everything else lives under More. The line under the title is the finding
for the current city; clicking it opens the argument. More → Plan models the
city as eight systems with capacity and demand, says what to do about the ones
going negative, and lists the assumptions that would change the ranking. Every
coefficient on that panel is marked MEASURED, DERIVED or ASSUMED.
Reading the code cold? Start at SYSTEM.md — how the layers fit, what the data contracts are, and why the OSM traffic goes through a proxy.
The product name in the UI is Dr Non's City Hub. package.json version is 0.9.4. GitHub description: Bangkok civic intelligence hub — live PM2.5, satellite, alerts. Independent of any vendor platform.
Drawn from the layer catalog and data modules — not from marketing copy:
| Domain | Sources in this repo |
|---|---|
| Air | GISTDA PM2.5, Air4Thai (PCD), Open-Meteo AQI, WAQI, OpenAQ |
| Water / flood | GISTDA live + historical flood polygons, Thaiwater quality and levels |
| Fire | NASA FIRMS (needs Worker FIRMS_MAP_KEY or VITE_FIRMS_MAP_KEY); GISTDA hotspots are a historical 2023 snapshot, not live |
| Traffic | Longdo / iTIC live tiles + incidents (default-on); TomTom flow/incidents if VITE_TOMTOM_KEY is set |
| Civic | Traffy Fondue citizen reports (points + heatmap) |
| Weather | TMD 7-day official forecast (Thai + English); Open-Meteo |
| Satellite | NASA GIBS (true color, night lights, LST, NDVI, aerosol, …), ESRI World Imagery, EOX Sentinel-2 cloudless; AlphaEarth / Sentinel-5P / GHSL need Earth Engine Worker secrets |
| 3D twin | OSM footprints baked to GeoJSON (public/geo/bkk-buildings.geojson, ODbL); heights from OSM, not invented |
| Narrative | GDELT headlines + sentiment; Reality Check verdict (CALM / UNDERSTATED / CONFIRMED / OVERSTATED) vs sensors |
| Brief | Governor-style panel; optional Gemini narration via the Worker; optional local Ollama ASK chat |
Transit rail geometry is a hand-curated BTS/MRT/ARL GeoJSON. The gtfs-transit-live layer is documented in the catalog as a mock GTFS-RT simulation — not a live operator feed.
Five tenets this public README is written to:
wrangler dev. ASK chat defaults to Ollama on your machine (http://localhost:11434) — nothing leaves it unless you turn on the cloud toggle. You do not need a vendor platform, a cluster, or a city IT department to try this.src/config/cities.ts is the replicability layer. scripts/bake-city-buildings.py ports the 3D path (Bangkok, then Kranj, then Ljubljana). MIT, as stated in this file and STORY.md.nameLocal (กรุงเทพฯ, เชียงใหม่, ภูเก็ต, ยะลา), IBM Plex Sans Thai, TMD descriptions in Thai and English, iTIC incident labels in Thai, UI aphorism ทุกอย่างเกิดขึ้นเพราะมีเหตุ. English for the rest of the operator chrome.BangkokIntelligence are cited. Empty, stale, pending, and mocked layers are labeled. The dashboard would rather show a gap than invent a number.STORY.md, not an official endorsement.scripts/bake-city-buildings.py: no invented metrics). Twin KPIs that are curated say so and name a source. Forecast backends tell the truth: the Worker’s /forecast model field reports Gemini, TimeFM, or Holt-Winters — whichever actually answered..env.example to .env.local. Worker secrets go through wrangler secret put. Never commit .env.local. This README does not include tokens, service-account JSON, or demo passwords.worker/src/index.ts origin-locks CORS to this project’s Pages hosts, *.nonarkara.org, and localhost. Do not strip that allowlist and republish it as an open CORS relay.flowchart TB
subgraph mac [One Mac]
Dev["npm run dev — Vite + React 19"]
Ollama["Optional: Ollama ASK chat\nlocalhost:11434"]
WDev["Optional: wrangler dev :8787"]
end
subgraph spa [Browser SPA]
UI["Panels, bilingual brief, layer rail"]
Map["MapLibre GL\noptional Mapbox vector tiles\nelse NASA / ESRI / Sentinel rasters"]
end
subgraph edge [Cloudflare]
Pages["Pages — static dist/"]
Worker["Worker cityhub-proxy\nCORS + key injection\n/forecast /narrate /ee/mapid"]
end
subgraph open [Public APIs — cited, replaceable]
Direct["CORS-friendly: Open-Meteo, USGS, NASA GIBS, OSM"]
Proxied["Often proxied: FIRMS, Traffy, GDELT,\nAir4Thai, TMD, data.go.th, WAQI, OpenAQ"]
end
Dev --> spa
Pages --> spa
UI --> Map
UI --> Direct
UI --> Ollama
UI --> Worker
UI --> WDev
Worker --> Proxied
WDev --> Proxied
Stack (from package.json and source, not the old UNL notes):
maplibre-gl. A Mapbox public pk.* token unlocks dark-vector and satellite-streets basemaps; without it the map still has NASA GIBS / ESRI / Sentinel-2 rasters)worker/ for CORS-blocked APIs and optional Gemini / TimeFM / Earth Enginesrc/config/cities.tsThe Vite alias @shared → ../_shared is used by src/data/gistda.ts for GISTDA helpers. That sibling folder is not in this repository. A clone of only city-hub will not resolve those imports until _shared/lib/gistda.js exists next to the checkout (or you change the alias). Other layers do not go through that file.
Requires Node.js and npm (lockfile is npm).
git clone https://github.com/Nonarkara/city-hub.git
cd city-hub
npm install
cp .env.example .env.local
npm run dev
Vite serves the SPA (typically http://localhost:5173). Bangkok super-mode is the default city in CITIES.
.env.example is the env contract. Names only:
| Variable | Role |
|---|---|
VITE_MAPBOX_ACCESS_TOKEN | Optional. Public pk.* token; URL-restrict it to your Pages hosts. Unlocks Mapbox vector / satellite-streets. |
VITE_PROXY_URL | Cloudflare Worker origin. Many fetchers use it when set; some (OpenWeatherMap, OpenAQ, narrate) fall back to http://127.0.0.1:8787. |
VITE_WAQI_TOKEN | Optional WAQI token |
VITE_LONGDO_KEY | Optional Longdo key |
VITE_TOMTOM_KEY | Optional TomTom (free-tier note in .env.example: 2,500 req/day) |
VITE_OPENWEATHERMAP_KEY | Optional OpenWeatherMap One Call 3.0 |
VITE_OPENAQ_KEY | Optional OpenAQ v3 |
VITE_FIRMS_MAP_KEY | Optional; direct FIRMS in dev. Production should use the Worker secret instead |
VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY | Optional cache |
VITE_OLLAMA_URL / VITE_OLLAMA_MODEL | Optional ASK chat. Code default model is phi4-mini (src/lib/ollama.ts); .env.example still shows qwen2.5-coder:1.5b as an override example |
VITE_GEMINI_MODEL | Optional cloud ASK via Firebase AI Logic; Firebase web config is in src/lib/firebase.ts (client identifiers, restricted by hostname in the Firebase console) |
Mapbox is not required to see a map. FIRMS, some keyed air/traffic APIs, Gemini narration, TimeFM, and AlphaEarth are silent or empty until the matching env/Worker secret exists — that is intentional.
From worker/README.md and worker/wrangler.toml (name = "cityhub-proxy"):
cd worker
npm install
npx wrangler dev # http://localhost:8787
Point the app at it:
# in .env.local
VITE_PROXY_URL=http://127.0.0.1:8787
Production secrets (names only — set with npx wrangler secret put SECRET_NAME inside worker/):
GEMINI_API_KEY, WAQI_TOKEN, OPENAQ_KEY, OWM_KEY, FIRMS_MAP_KEY, GCP_SERVICE_ACCOUNT_JSON, optional HF_API_TOKEN, TIMEFM_ENDPOINT_URL.
POST /forecast tries Gemini, then TimeFM, then in-Worker Holt-Winters. /narrate is Gemini. /ee/mapid is Earth Engine. Setup steps for TimeFM and AlphaEarth are in worker/README.md.
Documented deployed Worker hostname in context.md: cityhub-proxy.drnon.workers.dev (older unl-city-proxy.drnon.workers.dev is retired).
From .env.example and src/lib/ollama.ts:
# install https://ollama.com then e.g.
ollama pull phi4-mini && ollama serve
For the deployed site to call your Mac:
OLLAMA_ORIGINS="https://city-hub.pages.dev,https://hub.nonarkara.org" ollama serve
From scripts/bake-city-buildings.py and context.md (heights from OSM only):
python3 scripts/bake-city-buildings.py \
--city ljubljana \
--bbox 14.48,46.03,14.54,46.08 \
--output public/geo/ljubljana-buildings.geojson
Then set threeD: true and buildings3dUrl on that city in src/config/cities.ts.
From the previous README and context.md (Vite inlines VITE_* at build time):
npm run build
npx wrangler pages deploy dist --project-name city-hub --branch main \
--commit-hash=$(git rev-parse --short HEAD) \
--commit-message="$(git log -1 --pretty=%s)"
functions/ is bundled with the Pages deploy automatically — the Nominatim and
Overpass proxies ship with the static app, no separate deploy step.
Cloudflare Pages Git integration: framework preset Vite, build command npm run build, output dist. Set VITE_MAPBOX_ACCESS_TOKEN and VITE_PROXY_URL (and any other VITE_* you need) in Pages build environment variables for Production and Preview.
cd worker && npx wrangler deploy
Documented public host — also the GitHub repository homepage:
index.html and the About modal also name https://hub.nonarkara.org. Treat both as this project’s public fronts. This README does not claim uptime; if the SPA error boundary or the origin is down, run locally with the steps above.
| Doc | What it is |
|---|---|
| SYSTEM.md | How the system fits together — read this before changing a fetcher or a contract |
| docs/MSH.md | The layout law — when you find SH, massacre. Read before designing, building, or reviewing any interface |
| STORY.md | Why the UNL tiles were dropped; vendor independence |
| CONTRIBUTING.md | How to run a fork and what pull requests we want |
| SECURITY.md | How to report a vulnerability |
| LICENSE | MIT — GitHub-detectable |
| docs/DESIGN-AUDIT-LYNCH.md | The five Lynch lenses, and why OSM features are candidate evidence rather than a mental map |
| docs/IOC-2.0-RESEARCH.md | Research and design for Image of the City 2.0 — binding the eight city systems to Lynch's elements, with page references to the 1960 source |
| docs/hero-banner.png | Public README hero (this banner) |
| docs/UNL-DEPENDENCY-INVENTORY.md |
Released under the MIT License. Copyright © 2026 Non Arkaraprasertkul.
Use it, fork it, ship your own city’s version. Keep the copyright notice. This repository is independent civic software — not a vendor platform and not an official BMA, DEPA, or government product.
An in-app About panel currently prints a stricter “all rights reserved / written
licence” paragraph. The public repository license is MIT (LICENSE on
main). Do not take the About modal as overriding that file.
OpenStreetMap building extracts are ODbL. Upstream open-data providers keep their own terms.
See CONTRIBUTING.md and SECURITY.md.
Built by Non Arkaraprasertkul. ทุกอย่างเกิดขึ้นเพราะมีเหตุ.
| What UNL did vs what replaced it (historical; some env names in it are obsolete) |
| docs/IMPLEMENTATION-2026-05-26.md | Air4Thai, TMD seismic, Thaiwater, TomTom, Airbnb, correlation engine |
| docs/SESSION-2026-05-27-CIVIC-INTELLIGENCE.md | Insight stacks, city onboarding, per-city open data |
| worker/README.md | Proxy, forecast, narrate, Earth Engine |
| context.md | Internal engineering notes — some UNL-era; prefer package.json + source when they disagree |