{"$schema":"https://ejfox.com/schema/page-twin@1.json","kind":"changelog","url":"https://ejfox.com/changelog","json_url":"https://ejfox.com/changelog.json","generator":"ejfox.com/json-twin@1","data":{"meta":{"endpoint":"/api/changelog","timestamp":"2026-10-12T07:25:11.540Z","generatedAt":"2026-06-18T17:29:31.479Z","count":50,"filters":{"limit":50}},"commits":[{"hash":"11976dc","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:54.000Z","message":"feat(reach): query umami postgres directly instead of the stale HTTP API","type":"feat"},{"hash":"48c2d88","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:34.000Z","message":"chore: gitignore gear sync backups","type":"chore"},{"hash":"74d6513","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:25:31.000Z","message":"data(gear): add two currently-worn items (83 total)","type":"data"},{"hash":"988bddb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:24:36.000Z","message":"fix(projects): drop duplicate title headings from body","type":"fix"},{"hash":"5aae0cd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:16:09.000Z","message":"data(gear): sync filled weights — inventory now 100% weighed","type":"data"},{"hash":"fa65228","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:45:01.000Z","message":"feat(gear): sync 81-item inventory + Status field, schema-driven linter","type":"feat"},{"hash":"04e1da2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:43:02.000Z","message":"feat(stats): fold knowledge (wiki), reach (umami), photography into horizons","type":"feat"},{"hash":"b1dcfa9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:24:37.000Z","message":"fix(health): ambient dB is a level, not a sum — use mean of readings","type":"fix"},{"hash":"7f6ecfd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:16:24.000Z","message":"feat(stats): fold three portrait facets into horizons","type":"feat"},{"hash":"18a0633","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:19:11.000Z","message":"feat(stats): compose /api/stats as time horizons (now/today/week/year/ever)","type":"feat"},{"hash":"034b47f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:01:05.000Z","message":"fix(health): repair stats aggregation + surface sleep","type":"fix"},{"hash":"f17dedd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:02:29.000Z","message":"copy: de-robotize taglines + clean og descriptions","type":"copy"},{"hash":"84c9ab8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:20:22.000Z","message":"feat: mirror blog posts into AT-Proto / standard.site (#27)","type":"feat"},{"hash":"2617347","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T23:14:59.000Z","message":"perf(reveal): don't hide above-the-fold content (fixes LCP)","type":"perf"},{"hash":"d3614de","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:45:43.000Z","message":"feat: projects page image-first masonry overhaul (#22)","type":"feat"},{"hash":"e47ba11","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:34:03.000Z","message":"feat: hand-drawn marginalia kit (#23)","type":"feat"},{"hash":"d7ddb43","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:26:44.000Z","message":"docs: add Vault Alarm font preview screenshot","type":"docs"},{"hash":"e8f5659","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:25:52.000Z","message":"feat: use Vault Alarm as display font for headings","type":"feat"},{"hash":"b3b0a79","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:07:27.000Z","message":"feat(home): add today-post + weekly creative pulse footer","type":"feat"},{"hash":"b0e7d34","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:22:08.000Z","message":"chore: Vue SFC cleanup + high-leverage page refactors (#21)","type":"chore"},{"hash":"b3ce296","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-28T12:57:28.000Z","message":"fix(gear): kill mouse-tilt jitter and page-transition conflict","type":"fix"},{"hash":"76f14e0","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-25T02:47:59.000Z","message":"fix(og): resolve drafts in vault subdirs and week-notes/","type":"fix"},{"hash":"fcb9c4e","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:29:38.000Z","message":"refactor(layout): align with project style — Tailwind on elements, CSS only for grid areas","type":"refactor"},{"hash":"52d13d2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:27:44.000Z","message":"refactor(layout): CSS Grid layout + lift blog bar to layout-level Teleport slot","type":"refactor"},{"hash":"8f1b321","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:08:58.000Z","message":"fix(layout): metadata bar uses sticky, not fixed — kills mobile nav overlap","type":"fix"},{"hash":"18ff7d1","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:56:23.000Z","message":"fix(github): flip CommitHeatmap to weeks-across-years-down","type":"fix"},{"hash":"f3d4bde","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:46:51.000Z","message":"fix(feeds, build): RSS audit + unbreak production build","type":"fix"},{"hash":"cfc9938","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:36:16.000Z","message":"chore: yarn lint:fix sweep (prettier + isNaN/parseInt fixes)","type":"chore"},{"hash":"9ab7554","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:35:58.000Z","message":"feat(github): rebuild repo pages w/ dense layout, network graphs, commit type breakdown","type":"feat"},{"hash":"353a7c7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:42:11.000Z","message":"fix(og): fall back to Dispatch's vault path for unsynced drafts","type":"fix"},{"hash":"6f77a52","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:35:57.000Z","message":"feat(og): pull images from frontmatter + raise cap to 6","type":"feat"},{"hash":"3e2f84b","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:13:29.000Z","message":"fix(og): split :batchN suffix off the slug before path lookups","type":"fix"},{"hash":"26d25a4","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T01:02:29.000Z","message":"feat: mermaid rendering + smarter Obsidian wikilink routing","type":"feat"},{"hash":"f868c5a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T02:23:35.000Z","message":"fix: overhaul project pages, remove LQIP backgrounds, fix hydration errors","type":"fix"},{"hash":"449494a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T00:55:16.000Z","message":"fix: pass correct prop name to BlogPostContent on project pages","type":"fix"},{"hash":"52e9212","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:18:40.000Z","message":"docs: update CLAUDE.md with deploy pipeline, security, and VPS build bug","type":"docs"},{"hash":"92448e8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:03:52.000Z","message":"fix: use appleboy/scp-action with workspace-relative path","type":"fix"},{"hash":"e905a39","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:58:36.000Z","message":"fix: use scp directly for build upload instead of scp-action","type":"fix"},{"hash":"2956fe7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:55:36.000Z","message":"security: strip PII leaks, harden API routes, build on GH runner","type":"security"},{"hash":"5d90781","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T00:28:35.000Z","message":"fix: restore compat mode, add server build safety check to deploy","type":"fix"},{"hash":"40abf06","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T23:58:20.000Z","message":"fix: disable nuxt4 compat mode to restore node-server build","type":"fix"},{"hash":"d18c411","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:51:02.000Z","message":"ci: switch deploy workflow from docker to pm2","type":"ci"},{"hash":"31ba4c9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:39:54.000Z","message":"feat: 3D gear gallery, blog↔gear linking, and knife essay","type":"feat"},{"hash":"71bddae","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-08T22:36:58.000Z","message":"feat(gear): audit weights + add 8 new outdoor items","type":"feat"},{"hash":"ae9b0bd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T17:22:00.000Z","message":"docs(claude): replace docker references with pm2 deploy flow","type":"docs"},{"hash":"e03572f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:48:56.000Z","message":"fix(deploy): mount runtime-cache volume for monkeytype persistence","type":"fix"},{"hash":"b9da623","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:47:51.000Z","message":"feat(monkeytype): persist last-good cache to disk so cold restarts don't drop to null","type":"feat"},{"hash":"19a8489","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:39:15.000Z","message":"fix(monkeytype): treat 479 (ApeKey rate limit) as a transient miss + 5min TTL","type":"fix"},{"hash":"541571a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:20:36.000Z","message":"fix(api): null-cache, auth, and silent-fail audit","type":"fix"},{"hash":"b53dccb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-03T22:38:29.000Z","message":"refactor: one slug pattern — delete duplicated gear CSV parsing","type":"refactor"}],"grouped":{"byDate":{"2026-06-18":[{"hash":"11976dc","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:54.000Z","message":"feat(reach): query umami postgres directly instead of the stale HTTP API","type":"feat"},{"hash":"48c2d88","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:34.000Z","message":"chore: gitignore gear sync backups","type":"chore"},{"hash":"74d6513","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:25:31.000Z","message":"data(gear): add two currently-worn items (83 total)","type":"data"},{"hash":"988bddb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:24:36.000Z","message":"fix(projects): drop duplicate title headings from body","type":"fix"},{"hash":"5aae0cd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:16:09.000Z","message":"data(gear): sync filled weights — inventory now 100% weighed","type":"data"},{"hash":"fa65228","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:45:01.000Z","message":"feat(gear): sync 81-item inventory + Status field, schema-driven linter","type":"feat"},{"hash":"04e1da2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:43:02.000Z","message":"feat(stats): fold knowledge (wiki), reach (umami), photography into horizons","type":"feat"},{"hash":"b1dcfa9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:24:37.000Z","message":"fix(health): ambient dB is a level, not a sum — use mean of readings","type":"fix"},{"hash":"7f6ecfd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:16:24.000Z","message":"feat(stats): fold three portrait facets into horizons","type":"feat"},{"hash":"18a0633","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:19:11.000Z","message":"feat(stats): compose /api/stats as time horizons (now/today/week/year/ever)","type":"feat"},{"hash":"034b47f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:01:05.000Z","message":"fix(health): repair stats aggregation + surface sleep","type":"fix"},{"hash":"f17dedd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:02:29.000Z","message":"copy: de-robotize taglines + clean og descriptions","type":"copy"},{"hash":"84c9ab8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:20:22.000Z","message":"feat: mirror blog posts into AT-Proto / standard.site (#27)","type":"feat"}],"2026-06-17":[{"hash":"2617347","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T23:14:59.000Z","message":"perf(reveal): don't hide above-the-fold content (fixes LCP)","type":"perf"},{"hash":"d3614de","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:45:43.000Z","message":"feat: projects page image-first masonry overhaul (#22)","type":"feat"},{"hash":"e47ba11","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:34:03.000Z","message":"feat: hand-drawn marginalia kit (#23)","type":"feat"},{"hash":"b3b0a79","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:07:27.000Z","message":"feat(home): add today-post + weekly creative pulse footer","type":"feat"},{"hash":"b0e7d34","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:22:08.000Z","message":"chore: Vue SFC cleanup + high-leverage page refactors (#21)","type":"chore"}],"2026-04-08":[{"hash":"d7ddb43","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:26:44.000Z","message":"docs: add Vault Alarm font preview screenshot","type":"docs"},{"hash":"e8f5659","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:25:52.000Z","message":"feat: use Vault Alarm as display font for headings","type":"feat"}],"2026-05-28":[{"hash":"b3ce296","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-28T12:57:28.000Z","message":"fix(gear): kill mouse-tilt jitter and page-transition conflict","type":"fix"}],"2026-05-25":[{"hash":"76f14e0","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-25T02:47:59.000Z","message":"fix(og): resolve drafts in vault subdirs and week-notes/","type":"fix"}],"2026-05-20":[{"hash":"fcb9c4e","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:29:38.000Z","message":"refactor(layout): align with project style — Tailwind on elements, CSS only for grid areas","type":"refactor"},{"hash":"52d13d2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:27:44.000Z","message":"refactor(layout): CSS Grid layout + lift blog bar to layout-level Teleport slot","type":"refactor"},{"hash":"8f1b321","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:08:58.000Z","message":"fix(layout): metadata bar uses sticky, not fixed — kills mobile nav overlap","type":"fix"},{"hash":"18ff7d1","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:56:23.000Z","message":"fix(github): flip CommitHeatmap to weeks-across-years-down","type":"fix"},{"hash":"f3d4bde","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:46:51.000Z","message":"fix(feeds, build): RSS audit + unbreak production build","type":"fix"},{"hash":"cfc9938","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:36:16.000Z","message":"chore: yarn lint:fix sweep (prettier + isNaN/parseInt fixes)","type":"chore"},{"hash":"9ab7554","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:35:58.000Z","message":"feat(github): rebuild repo pages w/ dense layout, network graphs, commit type breakdown","type":"feat"}],"2026-05-19":[{"hash":"353a7c7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:42:11.000Z","message":"fix(og): fall back to Dispatch's vault path for unsynced drafts","type":"fix"},{"hash":"6f77a52","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:35:57.000Z","message":"feat(og): pull images from frontmatter + raise cap to 6","type":"feat"},{"hash":"3e2f84b","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:13:29.000Z","message":"fix(og): split :batchN suffix off the slug before path lookups","type":"fix"},{"hash":"26d25a4","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T01:02:29.000Z","message":"feat: mermaid rendering + smarter Obsidian wikilink routing","type":"feat"}],"2026-05-17":[{"hash":"f868c5a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T02:23:35.000Z","message":"fix: overhaul project pages, remove LQIP backgrounds, fix hydration errors","type":"fix"},{"hash":"449494a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T00:55:16.000Z","message":"fix: pass correct prop name to BlogPostContent on project pages","type":"fix"}],"2026-05-14":[{"hash":"52e9212","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:18:40.000Z","message":"docs: update CLAUDE.md with deploy pipeline, security, and VPS build bug","type":"docs"},{"hash":"92448e8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:03:52.000Z","message":"fix: use appleboy/scp-action with workspace-relative path","type":"fix"},{"hash":"e905a39","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:58:36.000Z","message":"fix: use scp directly for build upload instead of scp-action","type":"fix"},{"hash":"2956fe7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:55:36.000Z","message":"security: strip PII leaks, harden API routes, build on GH runner","type":"security"},{"hash":"5d90781","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T00:28:35.000Z","message":"fix: restore compat mode, add server build safety check to deploy","type":"fix"}],"2026-05-13":[{"hash":"40abf06","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T23:58:20.000Z","message":"fix: disable nuxt4 compat mode to restore node-server build","type":"fix"},{"hash":"d18c411","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:51:02.000Z","message":"ci: switch deploy workflow from docker to pm2","type":"ci"},{"hash":"31ba4c9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:39:54.000Z","message":"feat: 3D gear gallery, blog↔gear linking, and knife essay","type":"feat"}],"2026-05-08":[{"hash":"71bddae","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-08T22:36:58.000Z","message":"feat(gear): audit weights + add 8 new outdoor items","type":"feat"}],"2026-05-06":[{"hash":"ae9b0bd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T17:22:00.000Z","message":"docs(claude): replace docker references with pm2 deploy flow","type":"docs"},{"hash":"e03572f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:48:56.000Z","message":"fix(deploy): mount runtime-cache volume for monkeytype persistence","type":"fix"},{"hash":"b9da623","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:47:51.000Z","message":"feat(monkeytype): persist last-good cache to disk so cold restarts don't drop to null","type":"feat"},{"hash":"19a8489","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:39:15.000Z","message":"fix(monkeytype): treat 479 (ApeKey rate limit) as a transient miss + 5min TTL","type":"fix"},{"hash":"541571a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:20:36.000Z","message":"fix(api): null-cache, auth, and silent-fail audit","type":"fix"}],"2026-05-03":[{"hash":"b53dccb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-03T22:38:29.000Z","message":"refactor: one slug pattern — delete duplicated gear CSV parsing","type":"refactor"}]},"byType":{"feat":[{"hash":"11976dc","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:54.000Z","message":"feat(reach): query umami postgres directly instead of the stale HTTP API","type":"feat"},{"hash":"fa65228","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:45:01.000Z","message":"feat(gear): sync 81-item inventory + Status field, schema-driven linter","type":"feat"},{"hash":"04e1da2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:43:02.000Z","message":"feat(stats): fold knowledge (wiki), reach (umami), photography into horizons","type":"feat"},{"hash":"7f6ecfd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:16:24.000Z","message":"feat(stats): fold three portrait facets into horizons","type":"feat"},{"hash":"18a0633","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:19:11.000Z","message":"feat(stats): compose /api/stats as time horizons (now/today/week/year/ever)","type":"feat"},{"hash":"84c9ab8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:20:22.000Z","message":"feat: mirror blog posts into AT-Proto / standard.site (#27)","type":"feat"},{"hash":"d3614de","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:45:43.000Z","message":"feat: projects page image-first masonry overhaul (#22)","type":"feat"},{"hash":"e47ba11","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:34:03.000Z","message":"feat: hand-drawn marginalia kit (#23)","type":"feat"},{"hash":"e8f5659","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:25:52.000Z","message":"feat: use Vault Alarm as display font for headings","type":"feat"},{"hash":"b3b0a79","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:07:27.000Z","message":"feat(home): add today-post + weekly creative pulse footer","type":"feat"},{"hash":"9ab7554","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:35:58.000Z","message":"feat(github): rebuild repo pages w/ dense layout, network graphs, commit type breakdown","type":"feat"},{"hash":"6f77a52","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:35:57.000Z","message":"feat(og): pull images from frontmatter + raise cap to 6","type":"feat"},{"hash":"26d25a4","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T01:02:29.000Z","message":"feat: mermaid rendering + smarter Obsidian wikilink routing","type":"feat"},{"hash":"31ba4c9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:39:54.000Z","message":"feat: 3D gear gallery, blog↔gear linking, and knife essay","type":"feat"},{"hash":"71bddae","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-08T22:36:58.000Z","message":"feat(gear): audit weights + add 8 new outdoor items","type":"feat"},{"hash":"b9da623","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:47:51.000Z","message":"feat(monkeytype): persist last-good cache to disk so cold restarts don't drop to null","type":"feat"}],"chore":[{"hash":"48c2d88","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:28:34.000Z","message":"chore: gitignore gear sync backups","type":"chore"},{"hash":"b0e7d34","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T22:22:08.000Z","message":"chore: Vue SFC cleanup + high-leverage page refactors (#21)","type":"chore"},{"hash":"cfc9938","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:36:16.000Z","message":"chore: yarn lint:fix sweep (prettier + isNaN/parseInt fixes)","type":"chore"}],"data":[{"hash":"74d6513","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:25:31.000Z","message":"data(gear): add two currently-worn items (83 total)","type":"data"},{"hash":"5aae0cd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:16:09.000Z","message":"data(gear): sync filled weights — inventory now 100% weighed","type":"data"}],"fix":[{"hash":"988bddb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T17:24:36.000Z","message":"fix(projects): drop duplicate title headings from body","type":"fix"},{"hash":"b1dcfa9","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T16:24:37.000Z","message":"fix(health): ambient dB is a level, not a sum — use mean of readings","type":"fix"},{"hash":"034b47f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T15:01:05.000Z","message":"fix(health): repair stats aggregation + surface sleep","type":"fix"},{"hash":"b3ce296","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-28T12:57:28.000Z","message":"fix(gear): kill mouse-tilt jitter and page-transition conflict","type":"fix"},{"hash":"76f14e0","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-25T02:47:59.000Z","message":"fix(og): resolve drafts in vault subdirs and week-notes/","type":"fix"},{"hash":"8f1b321","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:08:58.000Z","message":"fix(layout): metadata bar uses sticky, not fixed — kills mobile nav overlap","type":"fix"},{"hash":"18ff7d1","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:56:23.000Z","message":"fix(github): flip CommitHeatmap to weeks-across-years-down","type":"fix"},{"hash":"f3d4bde","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T15:46:51.000Z","message":"fix(feeds, build): RSS audit + unbreak production build","type":"fix"},{"hash":"353a7c7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:42:11.000Z","message":"fix(og): fall back to Dispatch's vault path for unsynced drafts","type":"fix"},{"hash":"3e2f84b","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-19T16:13:29.000Z","message":"fix(og): split :batchN suffix off the slug before path lookups","type":"fix"},{"hash":"f868c5a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T02:23:35.000Z","message":"fix: overhaul project pages, remove LQIP backgrounds, fix hydration errors","type":"fix"},{"hash":"449494a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-17T00:55:16.000Z","message":"fix: pass correct prop name to BlogPostContent on project pages","type":"fix"},{"hash":"92448e8","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:03:52.000Z","message":"fix: use appleboy/scp-action with workspace-relative path","type":"fix"},{"hash":"e905a39","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:58:36.000Z","message":"fix: use scp directly for build upload instead of scp-action","type":"fix"},{"hash":"5d90781","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T00:28:35.000Z","message":"fix: restore compat mode, add server build safety check to deploy","type":"fix"},{"hash":"40abf06","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T23:58:20.000Z","message":"fix: disable nuxt4 compat mode to restore node-server build","type":"fix"},{"hash":"e03572f","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:48:56.000Z","message":"fix(deploy): mount runtime-cache volume for monkeytype persistence","type":"fix"},{"hash":"19a8489","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:39:15.000Z","message":"fix(monkeytype): treat 479 (ApeKey rate limit) as a transient miss + 5min TTL","type":"fix"},{"hash":"541571a","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T16:20:36.000Z","message":"fix(api): null-cache, auth, and silent-fail audit","type":"fix"}],"copy":[{"hash":"f17dedd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-18T13:02:29.000Z","message":"copy: de-robotize taglines + clean og descriptions","type":"copy"}],"perf":[{"hash":"2617347","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-06-17T23:14:59.000Z","message":"perf(reveal): don't hide above-the-fold content (fixes LCP)","type":"perf"}],"docs":[{"hash":"d7ddb43","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-04-08T16:26:44.000Z","message":"docs: add Vault Alarm font preview screenshot","type":"docs"},{"hash":"52e9212","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T17:18:40.000Z","message":"docs: update CLAUDE.md with deploy pipeline, security, and VPS build bug","type":"docs"},{"hash":"ae9b0bd","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-06T17:22:00.000Z","message":"docs(claude): replace docker references with pm2 deploy flow","type":"docs"}],"refactor":[{"hash":"fcb9c4e","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:29:38.000Z","message":"refactor(layout): align with project style — Tailwind on elements, CSS only for grid areas","type":"refactor"},{"hash":"52d13d2","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-20T17:27:44.000Z","message":"refactor(layout): CSS Grid layout + lift blog bar to layout-level Teleport slot","type":"refactor"},{"hash":"b53dccb","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-03T22:38:29.000Z","message":"refactor: one slug pattern — delete duplicated gear CSV parsing","type":"refactor"}],"security":[{"hash":"2956fe7","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-14T16:55:36.000Z","message":"security: strip PII leaks, harden API routes, build on GH runner","type":"security"}],"ci":[{"hash":"d18c411","author":"EJ Fox","email":"ejfox@ejfox.com","date":"2026-05-13T22:51:02.000Z","message":"ci: switch deploy workflow from docker to pm2","type":"ci"}]}},"stats":{"totalCommits":50,"dateRange":{"earliest":"2026-05-03T22:38:29.000Z","latest":"2026-06-18T17:28:54.000Z"},"byType":{"feat":16,"chore":3,"data":2,"fix":19,"copy":1,"perf":1,"docs":3,"refactor":3,"security":1,"ci":1}}},"_links":{"self":"https://ejfox.com/changelog.json","html":"https://ejfox.com/changelog"}}