Skip to content

Commit de0629f

Browse files
committed
add onboard/offboard member scripts with LLM bio generation
1 parent 4f62f4b commit de0629f

8 files changed

Lines changed: 1066 additions & 48 deletions

File tree

AGENTS.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# CONTEXTUAL DYNAMICS LAB WEBSITE
2+
3+
**Generated:** 2026-01-08
4+
**Commit:** 4f62f4b
5+
**Branch:** main
6+
7+
## OVERVIEW
8+
9+
Static website for Contextual Dynamics Lab (Dartmouth). Content pages auto-generated from Excel spreadsheets via Python build system. GitHub Pages hosting.
10+
11+
## STRUCTURE
12+
13+
```
14+
contextlab.github.io/
15+
├── *.html # 7 pages (index, research, people, publications, software, news, contact)
16+
├── css/style.css # Single stylesheet, 1897 lines, CSS variables
17+
├── js/main.js # All interactive components (359 lines)
18+
├── data/*.xlsx # Content source: publications, people, software, news
19+
├── templates/*.html # HTML templates with <!-- MARKER --> injection points
20+
├── scripts/ # Python build system (see scripts/AGENTS.md)
21+
├── images/ # Assets: people/, publications/, software/, research/, news/
22+
├── documents/ # CV files (JRM_CV.tex → .pdf, .html)
23+
└── tests/ # pytest suite for build system
24+
```
25+
26+
## WHERE TO LOOK
27+
28+
| Task | Location | Notes |
29+
|------|----------|-------|
30+
| Add publication | `data/publications.xlsx` | Auto-builds via GitHub Actions |
31+
| Add team member | `scripts/onboard_member.py` | Processes photo, generates bio, updates CV |
32+
| Offboard member | `scripts/offboard_member.py` | Moves to alumni, updates CV |
33+
| Add software | `data/software.xlsx` | |
34+
| Add news | `data/news.xlsx` | Thumbnail in `images/news/` |
35+
| Update CV | `documents/JRM_CV.tex` | Auto-compiles to PDF+HTML |
36+
| Fix styling | `css/style.css` | See CSS variables at top |
37+
| Fix JS behavior | `js/main.js` | 9 init functions |
38+
| Modify page structure | `templates/*.html` | NOT root *.html (auto-generated) |
39+
| Build system | `scripts/` | See scripts/AGENTS.md |
40+
41+
## CONVENTIONS
42+
43+
### Color Theme (CSS Variables)
44+
```css
45+
--primary-green: rgb(0, 112, 60);
46+
--bg-green: rgba(0, 112, 60, 0.2);
47+
--dark-text: rgba(0, 0, 0, 0.7);
48+
```
49+
50+
### Typography
51+
- All headings: lowercase (`text-transform: lowercase`)
52+
- Font: Nunito Sans (300 weight body, 300-700 headings)
53+
- Base: 14px, 1.7 line-height
54+
55+
### Images
56+
- Publication thumbnails: 500x500px with hand-drawn green border
57+
- People photos: Use `scripts/add_borders.py --face` for consistent styling
58+
- Border templates in `images/templates/WebsiteDoodles_Posters_v1.svg`
59+
60+
### Template System
61+
- Templates use `<!-- MARKER_NAME -->` for content injection
62+
- Markers replaced by build scripts with generated HTML
63+
- DO NOT edit root `publications.html`, `people.html`, `software.html`, `news.html` directly
64+
65+
## ANTI-PATTERNS
66+
67+
- **NEVER edit auto-generated HTML** (publications, people, software, news) - changes will be overwritten
68+
- **NEVER use `!important`** in CSS without explicit justification
69+
- **NEVER add inline styles** to templates - use CSS classes
70+
- **NEVER commit without running tests** - `python -m pytest tests/ -v`
71+
72+
## COMMANDS
73+
74+
```bash
75+
# Local development server
76+
python3 -m http.server 8000
77+
78+
# Validate spreadsheet data
79+
cd scripts && python validate_data.py
80+
81+
# Build all content pages
82+
cd scripts && python build.py
83+
84+
# Build CV only
85+
cd scripts && python build_cv.py
86+
87+
# Run full test suite
88+
python -m pytest tests/ -v
89+
90+
# Pre-push validation
91+
cd scripts && python pre_push_check.py
92+
93+
# Add borders to images
94+
python scripts/add_borders.py image.png images/publications/
95+
python scripts/add_borders.py photo.jpg images/people/ --face
96+
97+
# Onboard a new lab member
98+
cd scripts && python onboard_member.py "First Last"
99+
cd scripts && python onboard_member.py "First Last" --rank "grad student"
100+
cd scripts && python onboard_member.py "First Last" --photo headshot --bio "Bio text..."
101+
cd scripts && python onboard_member.py "First Last" --skip-llm
102+
103+
# Offboard a lab member (move to alumni)
104+
cd scripts && python offboard_member.py "member name"
105+
cd scripts && python offboard_member.py "name" --end-year 2025
106+
cd scripts && python offboard_member.py --list-no-photo
107+
```
108+
109+
## GITHUB ACTIONS
110+
111+
| Workflow | Trigger | Action |
112+
|----------|---------|--------|
113+
| `build-content.yml` | Push to data/, templates/, scripts/ | Validate + build + commit HTML |
114+
| `build-cv.yml` | Push to documents/JRM_CV.tex | Compile LaTeX to PDF+HTML |
115+
116+
## JS COMPONENTS
117+
118+
| Function | Purpose |
119+
|----------|---------|
120+
| `initDropdowns()` | Footer nav dropdown menus |
121+
| `initStickyNav()` | Show/hide footer nav on scroll |
122+
| `initSlideshow()` | Image carousel with autoplay |
123+
| `initModal()` | Modal open/close (join-us form) |
124+
| `initSmoothScroll()` | Anchor link scrolling |
125+
| `initInfoPanel()` | Homepage "i" button toggle |
126+
| `initContactForms()` | Formspree AJAX submission |
127+
| `initMobileMenu()` | Hamburger menu toggle |
128+
| `initCustomValidation()` | Green-themed validation tooltips |
129+
130+
## NOTES
131+
132+
- Forms use Formspree backend - endpoint in form `action` attribute
133+
- Homepage brain animation: static PNG, CSS transforms on toggle
134+
- Footer nav always visible (no scroll threshold on homepage)
135+
- Bluesky feed integration on news page (see `news.html`)
136+
- CV uses Dartmouth Ruzicka fonts (`data/DartmouthRuzicka-*.ttf`)

README.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,39 @@ scripts/ # Build scripts
185185
- `image` - Thumbnail filename (optional, place image in `images/publications/`)
186186
4. Save and push to GitHub (or run build locally)
187187

188-
#### Adding a New Team Member
188+
#### Adding a New Team Member (Automated)
189+
190+
Use the onboarding script for the easiest experience:
191+
192+
```bash
193+
cd scripts
194+
195+
# Basic onboarding (will auto-generate bio)
196+
python onboard_member.py "First Last"
197+
198+
# With role and bio
199+
python onboard_member.py "First Last" --rank "grad student" --bio "Bio text here..."
200+
201+
# With photo (searches Downloads, Desktop, images/people/)
202+
python onboard_member.py "First Last" --photo headshot_filename
203+
204+
# With website
205+
python onboard_member.py "First Last" --website "https://example.com"
206+
207+
# Skip LLM bio processing (use simple default)
208+
python onboard_member.py "First Last" --skip-llm
209+
```
210+
211+
The script will:
212+
- Process the photo with a hand-drawn border (using face detection)
213+
- Generate or edit the bio using a local LLM (gpt-oss-20b)
214+
- Add the member to `people.xlsx`
215+
- Add the member to `JRM_CV.tex`
216+
- Rebuild `people.html`
217+
218+
**Idempotent**: Running twice with the same name updates the existing entry.
219+
220+
#### Adding a New Team Member (Manual)
189221

190222
1. Open `data/people.xlsx` in Excel/Google Sheets
191223
2. Go to the `members` sheet
@@ -197,7 +229,34 @@ scripts/ # Build scripts
197229
- `image` - Photo filename (place photo in `images/people/`)
198230
4. Save and push to GitHub
199231

200-
#### Adding Alumni
232+
#### Offboarding a Team Member (Moving to Alumni)
233+
234+
Use the offboarding script to move members from active to alumni:
235+
236+
```bash
237+
cd scripts
238+
239+
# Offboard a member (will prompt for confirmation)
240+
python offboard_member.py "member name"
241+
242+
# Specify end year
243+
python offboard_member.py "member name" --end-year 2025
244+
245+
# Skip confirmation prompt
246+
python offboard_member.py "member name" -y
247+
248+
# List undergrads without photos
249+
python offboard_member.py --list-no-photo
250+
```
251+
252+
The script will:
253+
- Move the member from `members` sheet to `alumni_undergrads` in `people.xlsx`
254+
- Update `JRM_CV.tex` to add the end date
255+
- Prompt to rebuild `people.html`
256+
257+
**Idempotent**: Running twice with the same name detects the member is already offboarded.
258+
259+
#### Adding Alumni (Manual)
201260

202261
1. Open `data/people.xlsx`
203262
2. Go to the appropriate sheet:

data/people.xlsx

-5.84 KB
Binary file not shown.

documents/JRM_CV.tex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -739,23 +739,23 @@ \subsection*{Mentorship (selected)}
739739
\item Ellie Mattox (2025 -- )
740740
\item Emmy Thornton (2025 -- )
741741
\item Evan McDermid (2025 -- )
742-
\item Jackson C. Sandrich (2025 -- )
742+
\item Jackson C. Sandrich (2025 -- 2026)
743743
\item Will Lehman (2025 -- )
744-
\item Luca Gandrud (2025 -- )
744+
\item Luca Gandrud (2025 -- 2026)
745745
\item Sam Haskel* (2025 -- )
746746
\item Kevin Chang (2025 -- )
747747
\item Andrew Richardson (2025 -- )
748748
\item Ben Hanson (2025 -- )
749-
\item Annabelle Morrow (2025 -- )
750-
\item Owen Phillips (2025 -- )
749+
\item Annabelle Morrow (2025 -- 2026)
750+
\item Owen Phillips (2025 -- 2026)
751751
\item Rodrigo Vega Ayllon (2025)
752752
\item Joy Maina (2025 -- )
753753
\item Alexandra Wingo (2025 -- )
754754
\item Angelyn Liu (2025 -- )
755755
\item Miel Wewerka (2024)
756756
\item Manraaj Singh (2024)
757757
\item Can Kam (2024)
758-
\item Chelsea Joe (2024 -- )
758+
\item Chelsea Joe (2024 -- 2026)
759759
\item Jacob Bacus (2024 -- )
760760
\item Rohan Goyal (2024)
761761
\item Harrison Stropkay* (2024 -- 2025)

people.html

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,6 @@ <h3>sarah parigela | undergrad</h3>
115115
</div>
116116

117117
<div class="people-grid">
118-
<div class="person-card">
119-
<img src="images/people/placeholder.png" alt="chelsea joe">
120-
<h3>chelsea joe | undergrad</h3>
121-
<p>Chelsea is a Computer Science and Neuroscience double major. She is interested in artificial intelligence, machine learning, and building computational models.</p>
122-
</div>
123118
<div class="person-card">
124119
<img src="images/people/jacob_bacus.png" alt="jacob bacus">
125120
<h3>jacob bacus | undergrad</h3>
@@ -130,14 +125,14 @@ <h3>jacob bacus | undergrad</h3>
130125
<h3>aidan miller | undergrad</h3>
131126
<p>Aidan is a pre-med student at Dartmouth College, majoring in Biology, minor in Spanish, and graduating in 2028. He joined the Contextual Dynamics Lab in fall 2025, where his interests center on advanced learning and memory techniques, including the method of loci and PAO systems.</p>
132127
</div>
133-
</div>
134-
135-
<div class="people-grid">
136128
<div class="person-card">
137129
<img src="images/people/alexandra_wingo.png" alt="alexandra wingo">
138130
<h3>alexandra wingo | undergrad</h3>
139131
<p>Alexandra is interested in education technology and brings to the lab her extensive computer science experience. She is especially interested in helping students with learning differences, and in developing brain-based learning tools.</p>
140132
</div>
133+
</div>
134+
135+
<div class="people-grid">
141136
<div class="person-card">
142137
<img src="images/people/alishba_tahir.png" alt="alishba tahir">
143138
<h3>alishba tahir | undergrad</h3>
@@ -148,27 +143,19 @@ <h3>alishba tahir | undergrad</h3>
148143
<h3>andrew richardson | undergrad</h3>
149144
<p>Andrew Richardson is a Mathematics and Economics double major from Minneapolis, MN. Outside of academics, he enjoys playing tennis and soccer.</p>
150145
</div>
151-
</div>
152-
153-
<div class="people-grid">
154146
<div class="person-card">
155147
<img src="images/people/placeholder.png" alt="angelyn liu">
156148
<h3>angelyn liu | undergrad</h3>
157149
<p>Angelyn is a member of the class of 2028 from the Bay Area, CA, planning on majoring in cognitive science. In her free time, she enjoys singing, reading, puzzle games, and creative writing.</p>
158150
</div>
159-
<div class="person-card">
160-
<img src="images/people/placeholder.png" alt="annabelle morrow">
161-
<h3>annabelle morrow | undergrad</h3>
162-
<p>Annabelle Morrow is a member of the class of 2028 from Hong Kong. She is planning to major in economics and minor in human-centered design. Outside of class, she enjoys running and spending time outdoors.</p>
163-
</div>
151+
</div>
152+
153+
<div class="people-grid">
164154
<div class="person-card">
165155
<img src="images/people/placeholder.png" alt="azaire andre">
166156
<h3>azaire andre | undergrad</h3>
167157
<p>Azaire is a Mathematics and Anthropology double major. She is particularly interested in understanding complex systems like brain networks and financial markets.</p>
168158
</div>
169-
</div>
170-
171-
<div class="people-grid">
172159
<div class="person-card">
173160
<img src="images/people/ben_hanson.png" alt="ben hanson">
174161
<h3>ben hanson | undergrad</h3>
@@ -179,42 +166,27 @@ <h3>ben hanson | undergrad</h3>
179166
<h3>ellie mattox | undergrad</h3>
180167
<p>Ellie is a member of the class of 2027 from Austin, TX and is majoring in neuroscience with a minor in human-centered design. Outside of the lab she enjoys playing volleyball on Dartmouth's Varsity team, spending time outside, and hanging out with friends.</p>
181168
</div>
182-
<div class="person-card">
183-
<img src="images/people/placeholder.png" alt="evan mcdermid">
184-
<h3>evan mcdermid | undergrad</h3>
185-
<p>Evan is a Mathematics major and Computer Science minor. He is interested in algorithmic trading, algorithmic problem solving, and building models of financial market dynamics.</p>
186-
</div>
187169
</div>
188170

189171
<div class="people-grid">
190172
<div class="person-card">
191-
<img src="images/people/placeholder.png" alt="jackson c. sandrich">
192-
<h3>jackson c. sandrich | undergrad</h3>
193-
<p>Jax is a Mathematics and Economics double major. He is interested in using EEG to understand how people learn new concepts and skills.</p>
173+
<img src="images/people/placeholder.png" alt="evan mcdermid">
174+
<h3>evan mcdermid | undergrad</h3>
175+
<p>Evan is a Mathematics major and Computer Science minor. He is interested in algorithmic trading, algorithmic problem solving, and building models of financial market dynamics.</p>
194176
</div>
195177
<div class="person-card">
196178
<img src="images/people/placeholder.png" alt="kevin chang">
197179
<h3>kevin chang | undergrad</h3>
198180
<p>From Taipei and Boston, Kevin is a ‘29 studying Applied Math and CS. He is passionate about quantitative finance, machine learning, and health analytics. His long term goal is to develop data-driven solutions to optimize inefficiencies in the US healthcare system.</p>
199181
</div>
200-
<div class="person-card">
201-
<img src="images/people/placeholder.png" alt="luca gandrud">
202-
<h3>luca gandrud | undergrad</h3>
203-
<p>Luca is a Neuroscience major who is passionate about how we can use technology and neuroscience to enhance learning in everyday life. He is also interested in wearable brain recording devices.</p>
204-
</div>
205-
</div>
206-
207-
<div class="people-grid">
208-
<div class="person-card">
209-
<img src="images/people/placeholder.png" alt="owen phillips">
210-
<h3>owen phillips | undergrad</h3>
211-
<p>Owen is a ‘28 from Costa Mesa, California. He plans to major in Math and minor in Engineering and Computer Science. In his free time, he enjoys philatelics, post-hardcore music, fashion/art history, and logic puzzles.</p>
212-
</div>
213182
<div class="person-card">
214183
<img src="images/people/placeholder.png" alt="sam haskel">
215184
<h3>sam haskel | undergrad</h3>
216185
<p>Sam is a Quantitative Social Science and Economics double major. He is interested in how social peer influences shape beliefs and affect how people make decisions.</p>
217186
</div>
187+
</div>
188+
189+
<div class="people-grid">
218190
<div class="person-card">
219191
<img src="images/people/will_lehman.png" alt="will lehman">
220192
<h3>will lehman | undergrad</h3>
@@ -382,7 +354,12 @@ <h3>Undergraduate Researchers</h3>
382354
Sheherzad Mohydin (2016)<br>
383355
Peter Tran (2016)<br>
384356
Gal Perlman (2016)<br>
385-
Jessica Tin (2016)
357+
Jessica Tin (2016)<br>
358+
Chelsea Joe (2026)<br>
359+
Annabelle Morrow (2026)<br>
360+
Jackson C. Sandrich (2026)<br>
361+
Luca Gandrud (2026)<br>
362+
Owen Phillips (2026)
386363
</p>
387364
</div>
388365
</div>

0 commit comments

Comments
 (0)