Tip
Add new schedules at https://github.com/emmby/LairPages/upload/main/schedules/inbox
Public static asset hosting and automated ingestion pipeline for the Lair schedule application.
This repository hosts the static JSON schedules and the global manifest under the schedules/ directory, served via GitHub Pages at:
https://emmby.github.io/LairPages/schedules/
We have implemented an automated end-to-end ingestion pipeline to allow non-technical staff (such as camp managers) to upload new schedules.
[Camp Staff]
│ (Drops PDF in Google Drive Folder)
▼
[Google Drive Inbox]
│ (Daily Google Apps Script Watcher runs)
▼
[GitHub Inbox] (schedules/inbox/filename.pdf)
│ (GitHub Action triggers)
▼
[Isolated Branch Ingestion & Tests]
├── Runs Gemini-based Parser (moves PDF to camp folder & generates JSON)
├── Runs Vitest validation suite
▼
[PR Creation & Deployment]
├── Succeeded: Creates PR, auto-merges, deletes branch -> Deploys to Pages
└── Failed: Creates open [FAILED] PR for manual review and debugging
- Go to Google Apps Script.
- Create a new project named Lair Schedule Ingest Watcher.
- Copy the script from tool/google-apps-script.js and paste it into the editor (replacing all default code).
- Click the gear icon (Project Settings) on the left sidebar.
- Under Script Properties, add the following settings:
GITHUB_PAT: A GitHub Personal Access Token (classic) withreposcope to authorize commits.INBOX_FOLDER_ID: The Folder ID of your Google Drive schedule upload folder.PROCESSED_FOLDER_ID(Optional): The Folder ID where processed PDFs will be moved (if omitted, it creates aProcessedsubfolder automatically inside your Inbox folder).
- Click the clock icon (Triggers) on the left sidebar.
- Click + Add Trigger:
- Choose function to run:
checkAndUploadSchedules - Select event source:
Time-driven - Select type of trigger:
Day timer(recommend daily run, e.g., 6:00 AM - 7:00 AM) - Save and authorize permissions.
- Choose function to run:
Ensure the following Repository Secrets are added in your GitHub repository settings under Settings -> Secrets and variables -> Actions:
GEMINI_API_KEY: Your Gemini API key from Google AI Studio.LAIR_REPO_PAT: A GitHub Personal Access Token with write access toemmby/LairPagesand read access toemmby/Lair(so the validation check can load maps).
If you are a developer with local repository access, you can run the parsing pipeline manually.
- Copy the
.envconfiguration withGEMINI_API_KEY. - Run
npm installto install dependencies.
# General usage
npx tsx src/index.ts schedules/2026/oski/week_03.pdf
# Force visual OCR run without Step 0 cache
npx tsx src/index.ts schedules/2026/oski/week_03.pdf --no-cacheFor more details on manual conversion parameters, see the Tool README.
We enforce strict schema and cross-camp location link checks on all JSON files before merging:
# Run the local Vitest suite
npm testThe test suite validates:
- All JSON files follow the required schema boundaries and offset timestamps.
- Every
maplocation://markdown link maps to a valid location ID defined in the siblingLair/assets/maps/locations_{camp}.jsonfiles.