Un petit observatoire nature de notre maison près du pont couvert de Saint-Placide-de-Charlevoix, sur la rivière du Bras Nord-Ouest — qui agrège des capteurs autour de la propriété et publie chaque nuit une édition figée décrivant la veille.
En ligne : https://valdesloups.com
C'est un almanach avec une direction éditoriale axée sur la lisibilité, la clarté et la simplicité, et non un tableau de bord : chaque jour, on choisit une chose à signaler, on la met en page avec retenue, et on laisse la densité vivre derrière un lien discret.
Projet personnel, open source (MIT).
Le repo GitHub est l'état persistant — pas de base de données. Chaque nuit,
un workflow GitHub Actions exécute le script de génération, écrit le JSON du
jour dans data/, commit et push. Netlify détecte le push et rebuild le site
statique. Toute la chaîne est versionnée et inspectable dans git log.
GitHub Actions cron (5 5 * * * UTC, ≈ 01:05 EDT)
↓ npm run daily (tsx src/cli.ts)
↓ écrit data/{weather,birds,sky,editions}/YYYY-MM-DD.json
↓ + data/inat-photos.json (cache iNat)
↓ git commit + git push
GitHub push main → Netlify rebuild auto (Astro static)
↓ npm run site:build → publish site/dist
Netlify CDN sert valdesloups.com (HTTPS Let's Encrypt)
- Runtime du cron : Node 24 + TypeScript (via
tsx). - Site : Astro
output: 'static', lecture directe des JSON sousdata/au moment du build. - Synthèse : API Anthropic (Claude). La voix est dans
prompts/editorial-voice.md, modifiable à chaud. - Hosting : Netlify (site statique).
- DNS : Namecheap (apex
valdesloups.com, www en redirect vers apex).
src/
├── cli.ts # entrypoint : node --import tsx src/cli.ts [--date YYYY-MM-DD]
├── daily.ts # orchestrateur 5 étapes
├── almanac.ts # astronomy-engine + NOAA + IMO + Open-Meteo
├── synthesize.ts # appel Claude, charge editorial-voice.md
├── sources/
│ ├── tempest.ts # météo (agrégat journalier, horaire, norm historique)
│ ├── birdweather.ts # détections d'oiseaux (GraphQL)
│ └── inat.ts # photos d'espèces (cache TTL)
└── util/{date,json}.ts
scripts/
└── backfill-tempest.ts # one-shot remontée historique Tempest
site/
├── astro.config.mjs
└── src/
├── lib/data.ts # lit les JSON, queries typées au build
├── layouts/Base.astro
├── components/TopBar.astro
├── pages/{index,a-propos,credits,donnees}.astro
├── pages/archives/index.astro # page unique listant tous les billets
└── styles/globals.css
data/ # le repo EST l'état
├── weather/YYYY-MM-DD.json # Tempest, backfill depuis 2021-09-01
├── birds/YYYY-MM-DD.json # BirdWeather
├── sky/YYYY-MM-DD.json # éphémérides (astro + atmo)
├── editions/YYYY-MM-DD.json # billet éditorial de Claude
├── inat-photos.json # cache iNaturalist
├── quotes.json # 13 citations statiques (Thoreau, Muir, etc.)
└── breeding.json # 246 espèces Atlas QC
prompts/editorial-voice.md # voix de Claude (asset runtime)
.github/workflows/daily.yml # cron quotidien
netlify.toml # build statique
- Tempest station
41129— météo, foudre, rayonnement solaire ; historique continu depuis septembre 2021 (~4,7 ans, repère et non normale climatique). - BirdWeather station
6670— détections d'oiseaux + soundscapes FLAC publics ; API GraphQL accessible sans jeton. - iNaturalist API v2 — photos d'espèces (cc-by / cc-by-nc / pd) avec nom français, cache TTL.
- astronomy-engine (lib npm, local) — éphémérides, phase lunaire, planètes.
- NOAA SWPC — aurores (Kp).
- IMO — pluies d'étoiles (calendrier statique).
- Open-Meteo — couverture nuageuse uniquement (pas de clé).
- Verbatim de la source ou rien. Aucune mesure ou espèce inventée.
- Citations : uniquement depuis
data/quotes.json, jamais reconstituées de mémoire. - Sous le seuil de confiance : marquer « à confirmer », jamais affirmer.
- Ciel : calculé, jamais deviné.
Le workflow GitHub Actions s'évalue en UTC fixe. 5 5 * * * UTC
correspond à :
- 00 h 05 EST (hiver, UTC−5)
- 01 h 05 EDT (été, UTC−4)
— toujours post-minuit local. À chaque tick, src/daily.ts recalcule la
date locale America/Toronto et choisit entryDate = veille et
skyDate = ce soir. La même config marche toute l'année.
La feuille de route — en cours, à venir, reporté, terminé — est publiée
directement sur le site : https://valdesloups.com/feuille-de-route/.
Les données vivent dans data/roadmap.json ; la page
les lit au build.
MIT — voir LICENSE.
A small nature observatory based at our home near the covered bridge of Saint-Placide-de-Charlevoix, on the Bras Nord-Ouest river — aggregating sensors around the property and publishing every night a frozen daily edition describing the day before.
Live at: https://valdesloups.com
This is an almanac with an editorial direction grounded in readability, clarity and restraint — not a dashboard. Each day, one thing is chosen to highlight, laid out with restraint, and density is left to live behind discreet links.
Personal project, open source (MIT).
The GitHub repo is the persistent state — no database. Every night, a
GitHub Actions workflow runs the generation script, writes the day's JSON
to data/, commits and pushes. Netlify detects the push and rebuilds the
static site. The whole chain is versioned and inspectable through git log.
GitHub Actions cron (5 5 * * * UTC, ≈ 01:05 EDT)
↓ npm run daily (tsx src/cli.ts)
↓ writes data/{weather,birds,sky,editions}/YYYY-MM-DD.json
↓ + data/inat-photos.json (iNat cache)
↓ git commit + git push
GitHub push main → Netlify auto-rebuild (Astro static)
↓ npm run site:build → publish site/dist
Netlify CDN serves valdesloups.com (HTTPS Let's Encrypt)
- Cron runtime: Node 24 + TypeScript (via
tsx). - Site: Astro
output: 'static', reads JSON files underdata/directly at build time. - Synthesis: Anthropic (Claude) API. The voice lives in
prompts/editorial-voice.md, hot-editable. - Hosting: Netlify (static site).
- DNS: Namecheap (apex
valdesloups.com, www redirects to apex).
src/
├── cli.ts # entrypoint: node --import tsx src/cli.ts [--date YYYY-MM-DD]
├── daily.ts # 5-step orchestrator
├── almanac.ts # astronomy-engine + NOAA + IMO + Open-Meteo
├── synthesize.ts # Claude call, loads editorial-voice.md
├── sources/
│ ├── tempest.ts # weather (daily aggregate, hourly, historical norm)
│ ├── birdweather.ts # bird detections (GraphQL)
│ └── inat.ts # species photos (TTL cache)
└── util/{date,json}.ts
scripts/
└── backfill-tempest.ts # one-shot Tempest historical backfill
site/
├── astro.config.mjs
└── src/
├── lib/data.ts # reads JSON, typed queries at build
├── layouts/Base.astro
├── components/TopBar.astro
├── pages/{index,a-propos,credits,donnees}.astro
├── pages/archives/index.astro # single page listing all posts
└── styles/globals.css
data/ # the repo IS the state
├── weather/YYYY-MM-DD.json # Tempest, backfilled since 2021-09-01
├── birds/YYYY-MM-DD.json # BirdWeather
├── sky/YYYY-MM-DD.json # ephemerides (astro + atmo)
├── editions/YYYY-MM-DD.json # Claude's editorial post
├── inat-photos.json # iNaturalist cache
├── quotes.json # 13 static quotations (Thoreau, Muir, etc.)
└── breeding.json # 246 species QC Atlas
prompts/editorial-voice.md # Claude's voice (runtime asset)
.github/workflows/daily.yml # daily cron
netlify.toml # static build
- Tempest station
41129— weather, lightning, solar radiation; continuous record since September 2021 (~4.7 years, used as a local reference and not a climate normal). - BirdWeather station
6670— bird detections + public FLAC soundscapes; GraphQL API, no token required. - iNaturalist API v2 — species photos (cc-by / cc-by-nc / pd) with French names, TTL cache.
- astronomy-engine (npm lib, local) — ephemerides, lunar phase, planets.
- NOAA SWPC — auroras (Kp).
- IMO — meteor showers (static calendar).
- Open-Meteo — cloud cover only (no key).
- Verbatim from the source, or nothing. No measurement or species made up.
- Quotations: only from
data/quotes.json, never reconstructed from memory. - Below the confidence threshold: mark as "à confirmer", never assert.
- Sky: computed, never guessed.
The GitHub Actions workflow runs in fixed UTC. 5 5 * * * UTC means:
- 00:05 EST (winter, UTC−5)
- 01:05 EDT (summer, UTC−4)
— always past local midnight. On each tick, src/daily.ts recomputes the
local date in America/Toronto and picks entryDate = previous day and
skyDate = tonight. Same config works year-round.
The roadmap — in progress, coming up, deferred, done — is published
directly on the site at https://valdesloups.com/feuille-de-route/.
Data lives in data/roadmap.json; the page reads
it at build time.
MIT — see LICENSE.