diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..ccc9fa1 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,83 @@ +# Roadmap — commitmentissues.dev + +Living document. Completed work at the top, upcoming at the bottom. Add new entries as changes ship. + +--- + +## Shipped + +### Launch foundation +- Initial Next.js app setup — certificate generation, SEO metadata, JSON-LD, sitemap +- A4 certificate design with cause of death, last words, repo age, derived stats +- Rubber stamp branding ("REST IN PRODUCTION") +- Satori-based server-side certificate rendering +- Leaderboard / graveyard carousel (Famous Casualties) +- Submit form with example repo chips +- FAQ, Terms, Privacy consolidated into single About page +- Footer with GitHub source link and "keep the server alive" coffee CTA + +### Social & exports +- Multi-format exports (feed, square, story 9:16) without zip +- Mobile native share sheet (Web Share API) +- Platform-aware share flow (X, Instagram, desktop fallback menu) + +### Live data (Upstash / Redis) +- Real buried counter with historical baseline (800+) +- Recently Buried section — live feed of analyzed repos +- Animated count tick-up on load +- Migrated from `@vercel/kv` to `@upstash/redis` + +### UX polish +- Full UI/UX audit — back buttons, consistent gray design system, CSS cleanup +- Brutalist outlined control style across key surfaces +- Hover states and micro-interactions across all clickable elements +- Mobile certificate scaling — viewport-based, no sideways scroll +- Marquee scroll speed and reverse-direction Recently Buried row +- Random dead repo button (replaces example chips) +- Hover effects on all certificate action buttons +- Fixed Buy Me a Coffee button (top-right, all pages) + +### Routing & SEO +- Legacy route redirects (`/pricing`, `/faq`, `/privacy`) → `/about` +- `/terms` removed from sitemap and merged into `/about` +- OG image aligned with live hero (light theme, correct fonts) +- Custom roast line for commitmentissues repo itself + +### Data integrity +- Audited all 28 Famous Casualties graveyard entries against live GitHub API +- Fixed `angularjs/angular.js` → `angular/angular.js` (org transferred, old path 404) +- Fixed `facebook/flux` → `facebookarchive/flux` (archived org move) +- Fixed `joyent/node` → `nodejs/node-v0.x-archive` (org transferred) +- Fixed `yahoo/mojito` → `YahooArchive/mojito` (org transferred) +- Fixed `mikeal/request` → `request/request` (repo transferred) +- Removed `nicowillis/ratchet` — repo deleted with no replacement +- Removed `microsoft/winjs` — repo deleted with no replacement +- Removed `adobe/phonegap` — repo deleted with no replacement +- Synced `scoring.ts` known-cause keys to match updated repo paths + +### Open-source prep +- GitHub issue templates +- Repository conventions doc (`docs/repository-conventions.md`) +- `docs/releases/` changelog structure (v1.0.0) +- README refresh with screenshots, stack, and onboarding sections + +--- + +## Up next + +### Infrastructure +- [ ] Upgrade Next.js 14.x → 16.x (deferred CVEs — target: within one month of launch) + +### Features +- [ ] *(add items here)* + +### Fixes / polish +- [ ] *(add items here)* + +--- + +## How to use this file + +When a change ships, move it from **Up next** to the relevant **Shipped** section. +For brand-new ideas, add them under **Up next** with a `[ ]` checkbox. +Keep entries short — one line per change, same tone as the commit messages above. diff --git a/next.config.mjs b/next.config.mjs index 157281b..08c806e 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,5 +1,13 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + async redirects() { + return [ + { source: '/pricing', destination: '/', permanent: true }, + { source: '/faq', destination: '/', permanent: true }, + { source: '/privacy', destination: '/about', permanent: true }, + { source: '/terms', destination: '/about', permanent: true }, + ] + }, async headers() { return [ { diff --git a/src/components/Leaderboard.tsx b/src/components/Leaderboard.tsx index 40163be..b33c946 100644 --- a/src/components/Leaderboard.tsx +++ b/src/components/Leaderboard.tsx @@ -5,33 +5,33 @@ import { LeaderboardEntry } from '@/lib/types' const HALL_OF_SHAME: LeaderboardEntry[] = [ { fullName: 'atom/atom', cause: 'GitHub built VS Code and forgot this existed', score: 10, deathDate: 'Dec 2022', lastWords: 'At least I had good themes.' }, - { fullName: 'angularjs/angular.js', cause: 'Angular 2 murdered its own parent in cold blood', score: 9, deathDate: 'Jan 2022', lastWords: 'They named the replacement Angular too. Nobody was fooled.' }, + { fullName: 'angular/angular.js', cause: 'Angular 2 murdered its own parent in cold blood', score: 9, deathDate: 'Jan 2022', lastWords: 'They named the replacement Angular too. Nobody was fooled.' }, { fullName: 'adobe/brackets', cause: 'Adobe discovered VS Code already existed', score: 10, deathDate: 'Sep 2021', lastWords: 'I was actually pretty good. Nobody will know.' }, { fullName: 'apache/cordova', cause: 'React Native showed up and everyone switched mid-project', score: 8, deathDate: 'Aug 2020', lastWords: 'Hybrid apps were a mistake. I was a mistake.' }, { fullName: 'gulpjs/gulp', cause: 'Webpack arrived. Then Vite. Poor Gulp.', score: 8, deathDate: 'Dec 2019', lastWords: 'I streamed data beautifully. Nobody cared.' }, { fullName: 'meteor/meteor', cause: 'Promised full-stack bliss. Delivered full-stack confusion.', score: 7, deathDate: 'Jun 2018', lastWords: 'I promised real-time. I delivered real pain.' }, { fullName: 'ariya/phantomjs', cause: 'Chrome went headless. This went nowhere.', score: 9, deathDate: 'Mar 2018', lastWords: 'I had a headless future. Then so did Chrome.' }, { fullName: 'bower/bower', cause: 'npm install happened and nobody looked back', score: 9, deathDate: 'Jan 2017', lastWords: 'bower_components. That\'s my legacy.' }, - { fullName: 'facebook/flux', cause: 'Redux arrived uninvited and never left', score: 9, deathDate: 'Oct 2016', lastWords: 'I was just unidirectional data flow. Redux was also just unidirectional data flow.' }, + { fullName: 'facebookarchive/flux', cause: 'Redux arrived uninvited and never left', score: 9, deathDate: 'Oct 2016', lastWords: 'I was just unidirectional data flow. Redux was also just unidirectional data flow.' }, { fullName: 'gruntjs/grunt', cause: 'Gulped by Gulp, then Webpacked into the grave', score: 8, deathDate: 'Feb 2016', lastWords: 'Gruntfile.js was 300 lines. That was the problem.' }, { fullName: 'mootools/mootools-core', cause: 'jQuery killed it softly. Then jQuery died too.', score: 7, deathDate: 'Jan 2016', lastWords: 'I prototyped everything. Even things that shouldn\'t be prototyped.' }, { fullName: 'ftlabs/fastclick', cause: 'The 300ms delay got fixed. So did this.', score: 8, deathDate: 'Nov 2015', lastWords: 'My entire purpose was 300ms. Mobile browsers fixed it. Nobody told me.' }, - { fullName: 'microsoft/winjs', cause: 'Windows Phone died and took everything with it', score: 10, deathDate: 'Sep 2015', lastWords: 'Windows Phone had 3% market share. I had 3% of that.' }, + { fullName: 'jashkenas/coffeescript', cause: 'ES6 stole all its ideas and left', score: 7, deathDate: 'Sep 2015', lastWords: 'I made JavaScript beautiful. JavaScript made me irrelevant.' }, { fullName: 'knockout/knockout', cause: 'Vue arrived and everyone forgot their vows', score: 8, deathDate: 'Oct 2015', lastWords: 'ko.observable. ko.computed. ko.gone.' }, - { fullName: 'nicowillis/ratchet', cause: 'Bootstrap Mobile never shipped. Neither did this.', score: 7, deathDate: 'Aug 2015', lastWords: 'I was mobile-first before mobile-first was cool. Then I wasn\'t.' }, - { fullName: 'adobe/phonegap', cause: 'Cordova forked it. React Native buried them both.', score: 8, deathDate: 'Oct 2020', lastWords: 'I was Cordova before Cordova. Nobody remembers.' }, + + { fullName: 'postcss/autoprefixer', cause: 'Browsers finally agreed on things. Took them long enough.', score: 7, deathDate: 'Jan 2023', lastWords: 'I added -webkit- to everything. Even things that didn\'t need it.' }, - { fullName: 'joyent/node', cause: 'io.js forked it, then everyone made up and pretended nothing happened', score: 7, deathDate: 'May 2015', lastWords: 'The fork was mostly about a callback style disagreement. We don\'t talk about it.' }, + { fullName: 'nodejs/node-v0.x-archive', cause: 'io.js forked it, then everyone made up and pretended nothing happened', score: 7, deathDate: 'May 2015', lastWords: 'The fork was mostly about a callback style disagreement. We don\'t talk about it.' }, { fullName: 'twbs/ratchet', cause: 'Nobody actually built apps with Bootstrap anyway', score: 6, deathDate: 'Mar 2016', lastWords: 'I had 11,000 stars. Zero shipped apps.' }, { fullName: 'mattdesl/budo', cause: 'Webpack devServer ate the entire category', score: 6, deathDate: 'Feb 2018', lastWords: 'browserify was already losing. I never stood a chance.' }, { fullName: 'strongloop/loopback', cause: 'Express stayed simple. This did not.', score: 7, deathDate: 'Jun 2019', lastWords: 'I had a visual API composer. I thought that was good.' }, - { fullName: 'yahoo/mojito', cause: 'Yahoo slowly forgot it existed, then forgot everything else', score: 9, deathDate: 'Dec 2014', lastWords: 'I was isomorphic JavaScript in 2012. Too early. Also Yahoo.' }, + { fullName: 'YahooArchive/mojito', cause: 'Yahoo slowly forgot it existed, then forgot everything else', score: 9, deathDate: 'Dec 2014', lastWords: 'I was isomorphic JavaScript in 2012. Too early. Also Yahoo.' }, { fullName: 'dojo/dojo', cause: 'jQuery won the 2008 framework wars. Dojo was not informed.', score: 8, deathDate: 'Dec 2021', lastWords: 'I had AMD modules before AMD was a thing. Nobody used them.' }, { fullName: 'Polymer/polymer', cause: 'Web Components were supposed to be the future. They were not.', score: 8, deathDate: 'Apr 2021', lastWords: 'HTML Imports. I thought that was a good idea. It was not.' }, { fullName: 'tencent/wepy', cause: 'WeChat\'s own framework killed its own ecosystem', score: 7, deathDate: 'Nov 2019', lastWords: 'Even Tencent forgot about me.' }, { fullName: 'marionettejs/backbone.marionette', cause: 'Backbone died. So did everything built on Backbone.', score: 8, deathDate: 'Mar 2020', lastWords: 'I was Backbone but organized. Backbone wasn\'t organized. Or alive.' }, - { fullName: 'mikeal/request', cause: 'fetch() shipped natively and deprecated an entire generation', score: 9, deathDate: 'Feb 2020', lastWords: 'I was downloaded 30 million times a week. Then fetch happened.' }, + { fullName: 'request/request', cause: 'fetch() shipped natively and deprecated an entire generation', score: 9, deathDate: 'Feb 2020', lastWords: 'I was downloaded 30 million times a week. Then fetch happened.' }, { fullName: 'nicolo-ribaudo/jest-light-runner', cause: 'Vitest arrived and made everyone feel bad about Jest', score: 6, deathDate: 'Jan 2023', lastWords: 'I was faster Jest. Vitest was even faster. Also had a UI.' }, ] diff --git a/src/lib/scoring.ts b/src/lib/scoring.ts index 8cd6ff6..48a2a3b 100644 --- a/src/lib/scoring.ts +++ b/src/lib/scoring.ts @@ -8,8 +8,8 @@ const KNOWN_REPO_CAUSES: Record = { 'bower/bower': 'npm install happened and nobody looked back', 'atom/atom': 'GitHub shipped VS Code, then sunset Atom in public', 'adobe/brackets': 'Adobe handed it to the community after VS Code won the editor war', - 'angularjs/angular.js': 'AngularJS hit official end-of-life when modern Angular replaced it', - 'mikeal/request': 'The maintainers deprecated it as native fetch and modern clients took over', + 'angular/angular.js': 'AngularJS hit official end-of-life when modern Angular replaced it', + 'request/request': 'The maintainers deprecated it as native fetch and modern clients took over', 'ariya/phantomjs': 'Chrome went headless and erased the reason this existed', }