From 43a222d0e212236a8612d7af932774b74359158b Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Thu, 28 May 2026 21:21:28 +0530 Subject: [PATCH 1/6] docs(v0.9.8): spec launch landing sections (examples + how-it-works + star CTA) --- ...2026-05-28-v0.9.8-launch-landing-design.md | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md diff --git a/docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md b/docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md new file mode 100644 index 0000000..3a31908 --- /dev/null +++ b/docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md @@ -0,0 +1,103 @@ +# v0.9.8 — Launch landing sections design spec + +**Status:** Designed. Implementation plan to follow under `docs/superpowers/plans/`. +**Date:** 2026-05-28. +**Author:** Claude (Opus 4.7) with Shaan. + +--- + +## 1. Goal + +Strengthen the landing page for launch by adding below-the-fold sections beneath the existing hero: a "see it in action" row of clickable example profiles (real, live reports — the honest proof), a "how it works / why trust it" methodology section, and a "Star on GitHub" call-to-action. The hero + search stay untouched. + +This is a discrete, shippable enhancement numbered **v0.9.8**. It is *not* v1.0.0 — the `1.0.0` version is reserved for the actual public launch (its exit criteria are about live traffic), so this ships as the last v0.9.x slice. + +## 2. Locked scope decisions (2026-05-28) + +| Decision | Choice | Why | +| --- | --- | --- | +| Shape | **Add below-the-fold sections; hero untouched** | The hero is already polished; lowest risk, strongest persuasion. | +| Proof | **Clickable example-profile cards → live `/u/` reports** | The only honest asset (no testimonials/usage-stats). Clicking shows a real analysis. | +| Star CTA | **Static "Star on GitHub" button** (no live count) | User wants to grow repo stars. Static avoids a GitHub-API fetch + the Cache-Components server-fetch/prerender wrinkle; a live count can be added later. | +| Avatars | **Plain `` via `github.com/.png`** | Avoids adding `github.com` to `next.config` image `remotePatterns`; small avatars don't need `next/image`. | +| Version | **v0.9.8** (not 1.0.0) | Keep 1.0.0 for launch; every version is a release. | + +## 3. Content + +### 3.1 Section A — "See it in action" +- Heading (e.g. "See it in action") + sub-line ("Real reports. Click any profile."). +- Responsive grid of example-profile cards. Each: avatar (`https://github.com/.png?size=80`), display name, `@`, and a "View report →" affordance. The whole card links to `/u/`. +- **Default profiles** (recognizable OSS devs; swap-friendly): `torvalds` (Linus Torvalds), `gaearon` (Dan Abramov), `sindresorhus` (Sindre Sorhus), `antfu` (Anthony Fu), `yyx990803` (Evan You), `tj` (TJ Holowaychuk). +- Grid: 1-col mobile → 2-col `sm` → 3-col `lg`. + +### 3.2 Section B — "How it works / why trust it" +- Heading + a compact feature grid of 4 points (reinforcing existing brand framing, no new claims): + 1. **Six deterministic signals** — repo quality, engineering maturity, OSS/collab, recruiter signal, consistency, learning trajectory. + 2. **A 100-point, explainable score** — every point is traceable; no black box. + 3. **AI writes the narrative, never the score** — the LLM only formats the story. + 4. **Roast or Mentor** — pick the tone; same honest analysis underneath. +- Grid: 1-col mobile → 2-col `sm`+. + +### 3.3 Section C — "Star on GitHub" CTA +- A short closing band: a line ("Like it? Star it on GitHub.") + a button with a `Star` (lucide) icon linking to `https://github.com/Shaan-alpha/Skill-Issue` (`target="_blank"`, `rel="noopener noreferrer"`). + +The existing global `SiteFooter` (v0.9.7) remains below all sections. + +## 4. Structure + style + +`frontend/src/app/page.tsx` currently renders only the hero inside a `flex flex-1 ... justify-center` container that fills the viewport. Change: the hero becomes an approximately-viewport-height block, followed by the new sections that scroll beneath it. Sections are extracted into focused client components so `page.tsx` stays readable: + +- `frontend/src/components/landing/example-profiles.tsx` +- `frontend/src/components/landing/how-it-works.tsx` +- `frontend/src/components/landing/star-cta.tsx` + +Style follows the existing design system (Tailwind v4 tokens: `text-foreground`/`text-muted-foreground`/`border-white/10`/`bg-card`, `max-w` containers, rounded glass cards) and the animation philosophy (Framer Motion `m.*` spring reveals on scroll via `whileInView`, subtle — **no neon, no gradient-soup**, per AGENTS design rules). **Responsive is non-negotiable**: verify every section at a ~375px mobile width. + +## 5. Surface area + +### 5.1 New files +| File | Responsibility | +| --- | --- | +| `frontend/src/components/landing/example-profiles.tsx` | "See it in action" grid of clickable example-profile cards. | +| `frontend/src/components/landing/how-it-works.tsx` | Methodology feature grid. | +| `frontend/src/components/landing/star-cta.tsx` | "Star on GitHub" closing CTA. | +| `frontend/src/components/landing/__tests__/example-profiles.test.tsx` | Smoke test: cards render with correct `/u/` links. | + +### 5.2 Modified files +| File | Change | +| --- | --- | +| `frontend/src/app/page.tsx` | Hero container → viewport-height block; render ``, ``, `` beneath it. | +| Version literals + CHANGELOG + PLAN + PROGRESS_LOG | Release ritual (0.9.7 → 0.9.8) + add the v0.9.8 row above v1.0.0. | + +### 5.3 Untouched (intentionally) +- Hero copy, `SearchBar`, the `100/6/0` stat strip — unchanged. +- `SiteHeader`, `SiteFooter` — unchanged. +- Backend — none. +- `next.config.ts` image config — avoided via plain `` avatars. + +## 6. Tests +Per the UI-coverage norm (visual verification is fine), keep it minimal: +- `example-profiles.test.tsx`: renders, asserts ≥1 card links to `/u/torvalds` (and that the rendered count matches the profile list length). +- Plus `next build` + a visual check of all three sections at desktop + mobile. + +## 7. Exit criteria +- [ ] Three sections render beneath the hero; hero/search/stats unchanged. +- [ ] Example cards link to live `/u/` reports; default six profiles (or the user's revision). +- [ ] Star CTA links to the repo in a new tab. +- [ ] Responsive verified at mobile; reveals are subtle/spring; no neon. +- [ ] `example-profiles.test.tsx` passes; frontend `lint`/`tsc`/`test:run`/`build` clean. +- [ ] Docs ritual + version bump to 0.9.8; PLAN v0.9.8 row added + ✅; tag `v0.9.8` + release. + +## 8. Out of scope +- Testimonials, usage statistics, FAQ, pricing, newsletter signup. +- A live GitHub star count (static button now; count is a later enhancement). +- Hero redesign or copy changes. +- Any backend or `next.config` change. + +## 9. Implementation ordering +1. `how-it-works.tsx` + `star-cta.tsx` (self-contained, no data). +2. `example-profiles.tsx` (+ its smoke test). +3. Wire all three into `page.tsx` (hero → viewport block + sections); verify build + mobile. +4. Docs ritual + version bump + ship. + +**Reversibility:** additive (new section components + a page-layout change); reverting restores the single-hero landing with no backend/data impact. From 5e232c50be2e1ab3e474784f95e93ef727388132 Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Fri, 29 May 2026 00:32:37 +0530 Subject: [PATCH 2/6] docs(v0.9.8): implementation plan for launch landing sections --- .../plans/2026-05-28-v0.9.8-launch-landing.md | 478 ++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md diff --git a/docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md b/docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md new file mode 100644 index 0000000..11dd133 --- /dev/null +++ b/docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md @@ -0,0 +1,478 @@ +# v0.9.8 — Launch landing sections Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add three below-the-fold landing sections (example profiles, how-it-works, star CTA) beneath the existing hero, for launch. + +**Architecture:** Three focused client section components rendered after the hero in `page.tsx`; the hero becomes a viewport-height block instead of filling all space. Framer Motion `whileInView` reveals; honest proof via clickable example-profile cards linking to live reports. No backend or config change. + +**Tech Stack:** Next.js 16 App Router, React 19, Tailwind v4, Framer Motion (`m` + existing `FramerProvider`), lucide-react, vitest + Testing Library. + +**Spec:** [`docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md`](../specs/2026-05-28-v0.9.8-launch-landing-design.md). + +--- + +## File structure + +| File | Responsibility | Action | +| --- | --- | --- | +| `frontend/src/components/landing/how-it-works.tsx` | Methodology feature grid (4 points) | Create | +| `frontend/src/components/landing/star-cta.tsx` | "Star on GitHub" closing CTA | Create | +| `frontend/src/components/landing/example-profiles.tsx` | Clickable example-profile cards → `/u/` | Create | +| `frontend/src/components/landing/__tests__/example-profiles.test.tsx` | Smoke test (cards render + links) | Create | +| `frontend/src/app/page.tsx` | Hero → viewport block + render the 3 sections | Modify | +| Version literals + CHANGELOG + PLAN + PROGRESS_LOG + `uv.lock` | Release ritual (0.9.7 → 0.9.8) | Modify | + +All frontend commands run from `frontend/`. The `glass` utility class is defined in `globals.css` (used by `loading.tsx`/`results-view.tsx`) — reuse it for cards. + +--- + +### Task 1: `how-it-works.tsx` + `star-cta.tsx` + +**Files:** +- Create: `frontend/src/components/landing/how-it-works.tsx`, `frontend/src/components/landing/star-cta.tsx` + +- [ ] **Step 1: Create `how-it-works.tsx`** + +```tsx +"use client"; + +import { m } from "framer-motion"; + +const ITEMS = [ + { + title: "Six deterministic signals", + body: "Repo quality, engineering maturity, OSS & collaboration, recruiter signal, consistency, and learning trajectory.", + }, + { + title: "A 100-point, explainable score", + body: "Every point traces back to evidence in your GitHub history. No black box, no vibes.", + }, + { + title: "AI writes the narrative, never the score", + body: "The model only formats the story. The numbers come from pure, deterministic code.", + }, + { + title: "Roast or Mentor", + body: "Pick the tone — brutally funny or genuinely constructive — over the same honest analysis.", + }, +]; + +export function HowItWorks() { + return ( +
+ + Engineering insight first. AI flavor second. + +
+ {ITEMS.map((it, i) => ( + +

{it.title}

+

{it.body}

+
+ ))} +
+
+ ); +} +``` + +- [ ] **Step 2: Create `star-cta.tsx`** + +```tsx +"use client"; + +import { m } from "framer-motion"; +import { Star } from "lucide-react"; + +export function StarCta() { + return ( +
+ +

+ Like it? Star it on GitHub. +

+

+ Skill Issue is built in the open. A star helps more developers find it. +

+ + +
+
+ ); +} +``` + +- [ ] **Step 3: Typecheck + lint** + +Run: `npx tsc --noEmit` → clean. +Run: `npm run lint` → clean. + +- [ ] **Step 4: Commit** + +```bash +git add frontend/src/components/landing/how-it-works.tsx frontend/src/components/landing/star-cta.tsx +git commit -m "feat(v0.9.8): how-it-works + star-on-github landing sections" +``` + +--- + +### Task 2: `example-profiles.tsx` + smoke test + +**Files:** +- Create: `frontend/src/components/landing/example-profiles.tsx` +- Test: `frontend/src/components/landing/__tests__/example-profiles.test.tsx` + +- [ ] **Step 1: Write the failing test** + +Create `frontend/src/components/landing/__tests__/example-profiles.test.tsx`: + +```tsx +import { render, screen } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; + +// Render framer-motion's `m.*` as plain divs — motion components don't render +// reliably under happy-dom without a LazyMotion provider (project lesson, +// PROGRESS_LOG 2026-05-28 v0.9.3). We only need the DOM structure here. +vi.mock("framer-motion", () => ({ + m: new Proxy( + {}, + { + get: + () => + ({ children, className }: { children?: React.ReactNode; className?: string }) => ( +
{children}
+ ), + }, + ), +})); + +import { ExampleProfiles } from "@/components/landing/example-profiles"; + +describe("ExampleProfiles", () => { + it("renders six example cards linking to live reports", () => { + render(); + expect(screen.getByRole("link", { name: /Linus Torvalds/i })).toHaveAttribute( + "href", + "/u/torvalds", + ); + expect(screen.getAllByRole("link")).toHaveLength(6); + }); +}); +``` + +- [ ] **Step 2: Run the test, confirm it fails** + +Run: `npm run test:run -- example-profiles` +Expected: FAIL — module `@/components/landing/example-profiles` not found. + +- [ ] **Step 3: Create `example-profiles.tsx`** + +```tsx +"use client"; + +import { m } from "framer-motion"; +import Link from "next/link"; +import { ArrowRight } from "lucide-react"; + +const PROFILES = [ + { username: "torvalds", name: "Linus Torvalds" }, + { username: "gaearon", name: "Dan Abramov" }, + { username: "sindresorhus", name: "Sindre Sorhus" }, + { username: "antfu", name: "Anthony Fu" }, + { username: "yyx990803", name: "Evan You" }, + { username: "tj", name: "TJ Holowaychuk" }, +]; + +export function ExampleProfiles() { + return ( +
+
+

+ See it in action +

+

Real reports — click any profile.

+
+
+ {PROFILES.map((p, i) => ( + + + {/* eslint-disable-next-line @next/next/no-img-element */} + +
+

{p.name}

+

@{p.username}

+
+ + View + + +
+ ))} +
+
+ ); +} +``` + +- [ ] **Step 4: Run the test, confirm it passes** + +Run: `npm run test:run -- example-profiles` +Expected: `1 passed` (the test file; 1 test). + +- [ ] **Step 5: Typecheck + lint** + +Run: `npx tsc --noEmit` → clean. +Run: `npm run lint` → clean (the inline `eslint-disable-next-line @next/next/no-img-element` suppresses the raw-img rule, which is intended here for small external avatars). + +- [ ] **Step 6: Commit** + +```bash +git add frontend/src/components/landing/example-profiles.tsx frontend/src/components/landing/__tests__/example-profiles.test.tsx +git commit -m "feat(v0.9.8): see-it-in-action example profiles + smoke test" +``` + +--- + +### Task 3: Wire the sections into `page.tsx` + +**Files:** +- Modify: `frontend/src/app/page.tsx` (full replace) + +- [ ] **Step 1: Replace `page.tsx`** + +Replace the ENTIRE contents of `frontend/src/app/page.tsx` with the following. The hero inner content is unchanged; the outer container changes from `flex flex-1` (fills viewport) to a `min-h-[calc(100vh-header)]` `
`, and the three new sections render after it. (The `v0.9.7` version-pill literal is bumped in Task 4 along with the other literals — leave it as-is here.) + +```tsx +"use client"; + +import { m } from "framer-motion"; +import { SearchBar } from "@/components/search-bar"; +import { ExampleProfiles } from "@/components/landing/example-profiles"; +import { HowItWorks } from "@/components/landing/how-it-works"; +import { StarCta } from "@/components/landing/star-cta"; + +export default function Home() { + return ( + <> +
+ {/* Ambient blobs — smaller and lighter on mobile to keep paint cheap */} +
+
+ +
+ + + Deterministic engineering reports · v0.9.7 + + +

+ Skill Issue +

+ +

+ Your GitHub profile is your real resume.{" "} + Skill Issue reads it honestly. +

+ + + + + + +
+ 100 + Deterministic +
+
+ 6 + Analyzers +
+
+ 0 + Hallucinations +
+
+
+
+ +
+
+ + + + + + ); +} +``` + +- [ ] **Step 2: Typecheck + lint + build** + +Run: `npx tsc --noEmit` → clean. +Run: `npm run lint` → clean. +Run: `npm run build` → succeeds; `/` still `○ (Static)`. + +- [ ] **Step 3: Visual check (manual)** + +`npm run dev`, open `/`: the hero still fills the first screen; scrolling reveals the three sections with subtle spring fade-ins; example cards show avatars and link to reports; the star button works. Check at ~375px mobile width (cards/feature-grid stack to 1 column, star button readable). (If the dev server can't run in this environment, note it — the build + smoke test cover structure; visual is the operator's confirm.) + +- [ ] **Step 4: Commit** + +```bash +git add frontend/src/app/page.tsx +git commit -m "feat(v0.9.8): render launch sections beneath the hero" +``` + +--- + +### Task 4: Docs ritual + version bump + ship + +**Files:** +- Modify: `backend/pyproject.toml:3`, `backend/app/settings.py:5`, `frontend/package.json:3`, `frontend/src/app/page.tsx` (version pill), `frontend/src/components/results-view.tsx:355`, `README.md` (status lead + running list + health curl), `CHANGELOG.md`, `PLAN.md` (map + section), `docs/PROGRESS_LOG.md`, `backend/uv.lock` + +- [ ] **Step 1: Bump version literals** + +`backend/pyproject.toml` line 3 `version = "0.9.7"` → `"0.9.8"`; `backend/app/settings.py` line 5 `VERSION = "0.9.7"` → `"0.9.8"`; `frontend/package.json` line 3 `"version": "0.9.7",` → `"0.9.8",`; `frontend/src/app/page.tsx` the pill text `Deterministic engineering reports · v0.9.7` → `v0.9.8`; `frontend/src/components/results-view.tsx` line 355 `... Protocol v0.9.7` → `v0.9.8`. + +- [ ] **Step 2: Update README** + +`README.md` line 46: change the lead to name **v0.9.8** (launch landing — example reports, how-it-works, star CTA), demote v0.9.7 to "before it," and change the trailing pointer from `**v1.0.0 — public launch** is next.` to `v0.9.8 adds launch landing sections (example reports, how-it-works, a GitHub-star CTA). **v1.0.0 — public launch** is next.` Bump the health-curl `"version":"0.9.7"` → `"0.9.8"`. + +- [ ] **Step 3: CHANGELOG** + +Insert below the preamble `---`, above `## [0.9.7]`: + +```markdown +## [0.9.8] — 2026-05-29 + +### Added +- **Launch landing sections.** Beneath the hero: a "see it in action" row of example profiles linking to live reports, a "how it works" methodology section, and a "Star on GitHub" call-to-action. + +--- +``` + +- [ ] **Step 4: PLAN.md** + +Add a map row directly above the `v1.0.0` row: +`| **v0.9.8** | Launch landing sections (examples + how-it-works + star CTA) | ✅ shipped |` + +Add a section directly above `## v1.0.0 — Public launch`: + +```markdown +## v0.9.8 — Launch landing sections (shipped 2026-05-29) + +**Goal:** Below-the-fold launch landing sections beneath the existing hero. + +**Delivered:** `ExampleProfiles` (clickable example-profile cards → live `/u/` reports — the honest proof), `HowItWorks` (deterministic-methodology feature grid), `StarCta` ("Star on GitHub" → repo). Hero/search/stats untouched; static-prerendered; responsive. No testimonials/usage-stats (none real). Shipped as v0.9.8, keeping 1.0.0 for the actual launch. + +**Design spec:** [`docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md`](./docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md). +**Sub-plan:** [`docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md`](./docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md). + +**Exit criteria:** +- [x] Three sections render beneath the hero; hero unchanged; `/` still static. +- [x] Example cards link to live reports; star CTA → repo (new tab). +- [x] Smoke test passes; frontend lint/tsc/test/build clean; mobile verified. +- [x] Docs ritual + version bump to 0.9.8; tag + release. +``` + +- [ ] **Step 5: Re-sync `uv.lock`** + +Run: `cd backend && uv lock` → only `skill-issue-backend 0.9.7 → 0.9.8` changes. + +- [ ] **Step 6: PROGRESS_LOG** + +Add a new top entry (file format): header `## 2026-05-29 — Claude (Opus 4.7) — v0.9.8 shipped (launch landing sections)`; Slice v0.9.8; Done (3 section components + page wiring + smoke test); Decisions (honest proof only — example reports, no testimonials; static star CTA, no live count, to dodge the Cache-Components server-fetch wrinkle; hero untouched; numbered v0.9.8 not 1.0.0); Verified (lint/tsc/test/build + mobile visual); Next (v1.0.0 — human-gated public launch). + +- [ ] **Step 7: Full verification** + +Run: `cd frontend && npm run lint && npx tsc --noEmit && npm run test:run && npm run build` +Expected: lint/tsc clean; vitest 57 + 1 = 58 passed; build succeeds, `/` static. + +Run: `cd backend && uv run pytest -q --no-header` +Expected: 290 passed (backend untouched; confirms version bump didn't break). + +- [ ] **Step 8: Commit** + +```bash +git add backend/pyproject.toml backend/app/settings.py frontend/package.json frontend/src/app/page.tsx frontend/src/components/results-view.tsx README.md CHANGELOG.md PLAN.md docs/PROGRESS_LOG.md backend/uv.lock +git commit -m "chore(v0.9.8): bump version + docs ritual (launch landing)" +``` + +- [ ] **Step 9: Push, PR, CI, merge, smoke (confirm before tag)** + +Push the branch, open a PR, wait for CI green, merge to `main`. Prod smoke: `curl …/health` → `version: 0.9.8`; load `/` on prod and scroll the new sections. Then **pause for user confirmation** before `git tag v0.9.8 && git push origin v0.9.8`. + +--- + +## Self-review notes + +- **Spec coverage:** §3.1 ExampleProfiles → Task 2; §3.2 HowItWorks + §3.3 StarCta → Task 1; §4 page structure → Task 3; §6 test → Task 2; §7 exit criteria → Task 4. All covered. +- **Placeholder scan:** none — full component, test, and page code included. +- **Type consistency:** component names `ExampleProfiles` / `HowItWorks` / `StarCta` (named exports) are imported identically in `page.tsx` (Task 3) and the test (Task 2). `PROFILES` list = 6 entries, matching the test's `toHaveLength(6)` and the `/u/torvalds` assertion. +- **Hero untouched:** Task 3 preserves the hero inner markup verbatim (only the container element + version literal-in-Task-4 change); search/stats unchanged. +- **Test count:** frontend 57 → 58 (+1). Backend unchanged at 290. +- **Framer-in-tests:** the test mocks `framer-motion` to plain divs (project lesson — `m.*` doesn't render reliably under happy-dom without LazyMotion), so the smoke test is deterministic. From aca6673c24a18489c309c9229c1eaa3220edf998 Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Fri, 29 May 2026 00:36:00 +0530 Subject: [PATCH 3/6] feat(v0.9.8): how-it-works + star-on-github landing sections --- .../src/components/landing/how-it-works.tsx | 53 +++++++++++++++++++ frontend/src/components/landing/star-cta.tsx | 34 ++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 frontend/src/components/landing/how-it-works.tsx create mode 100644 frontend/src/components/landing/star-cta.tsx diff --git a/frontend/src/components/landing/how-it-works.tsx b/frontend/src/components/landing/how-it-works.tsx new file mode 100644 index 0000000..362d918 --- /dev/null +++ b/frontend/src/components/landing/how-it-works.tsx @@ -0,0 +1,53 @@ +"use client"; + +import { m } from "framer-motion"; + +const ITEMS = [ + { + title: "Six deterministic signals", + body: "Repo quality, engineering maturity, OSS & collaboration, recruiter signal, consistency, and learning trajectory.", + }, + { + title: "A 100-point, explainable score", + body: "Every point traces back to evidence in your GitHub history. No black box, no vibes.", + }, + { + title: "AI writes the narrative, never the score", + body: "The model only formats the story. The numbers come from pure, deterministic code.", + }, + { + title: "Roast or Mentor", + body: "Pick the tone — brutally funny or genuinely constructive — over the same honest analysis.", + }, +]; + +export function HowItWorks() { + return ( +
+ + Engineering insight first. AI flavor second. + +
+ {ITEMS.map((it, i) => ( + +

{it.title}

+

{it.body}

+
+ ))} +
+
+ ); +} diff --git a/frontend/src/components/landing/star-cta.tsx b/frontend/src/components/landing/star-cta.tsx new file mode 100644 index 0000000..f4d8655 --- /dev/null +++ b/frontend/src/components/landing/star-cta.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { m } from "framer-motion"; +import { Star } from "lucide-react"; + +export function StarCta() { + return ( +
+ +

+ Like it? Star it on GitHub. +

+

+ Skill Issue is built in the open. A star helps more developers find it. +

+ + +
+
+ ); +} From c4290583ab837768116fd5310776fd4049ddb4d2 Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Fri, 29 May 2026 00:37:24 +0530 Subject: [PATCH 4/6] feat(v0.9.8): see-it-in-action example profiles + smoke test --- .../__tests__/example-profiles.test.tsx | 31 ++++++++++ .../components/landing/example-profiles.tsx | 61 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 frontend/src/components/landing/__tests__/example-profiles.test.tsx create mode 100644 frontend/src/components/landing/example-profiles.tsx diff --git a/frontend/src/components/landing/__tests__/example-profiles.test.tsx b/frontend/src/components/landing/__tests__/example-profiles.test.tsx new file mode 100644 index 0000000..2f48c93 --- /dev/null +++ b/frontend/src/components/landing/__tests__/example-profiles.test.tsx @@ -0,0 +1,31 @@ +import { render, screen } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; + +// Render framer-motion's `m.*` as plain divs — motion components don't render +// reliably under happy-dom without a LazyMotion provider (project lesson, +// PROGRESS_LOG 2026-05-28 v0.9.3). We only need the DOM structure here. +vi.mock("framer-motion", () => ({ + m: new Proxy( + {}, + { + get: + () => + ({ children, className }: { children?: React.ReactNode; className?: string }) => ( +
{children}
+ ), + }, + ), +})); + +import { ExampleProfiles } from "@/components/landing/example-profiles"; + +describe("ExampleProfiles", () => { + it("renders six example cards linking to live reports", () => { + render(); + expect(screen.getByRole("link", { name: /Linus Torvalds/i })).toHaveAttribute( + "href", + "/u/torvalds", + ); + expect(screen.getAllByRole("link")).toHaveLength(6); + }); +}); diff --git a/frontend/src/components/landing/example-profiles.tsx b/frontend/src/components/landing/example-profiles.tsx new file mode 100644 index 0000000..5b09656 --- /dev/null +++ b/frontend/src/components/landing/example-profiles.tsx @@ -0,0 +1,61 @@ +"use client"; + +import { m } from "framer-motion"; +import Link from "next/link"; +import { ArrowRight } from "lucide-react"; + +const PROFILES = [ + { username: "torvalds", name: "Linus Torvalds" }, + { username: "gaearon", name: "Dan Abramov" }, + { username: "sindresorhus", name: "Sindre Sorhus" }, + { username: "antfu", name: "Anthony Fu" }, + { username: "yyx990803", name: "Evan You" }, + { username: "tj", name: "TJ Holowaychuk" }, +]; + +export function ExampleProfiles() { + return ( +
+
+

+ See it in action +

+

Real reports — click any profile.

+
+
+ {PROFILES.map((p, i) => ( + + + {/* eslint-disable-next-line @next/next/no-img-element */} + +
+

{p.name}

+

@{p.username}

+
+ + View + + +
+ ))} +
+
+ ); +} From 98e8b9deefc2633dcd415bd0f372fd99b8262c0e Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Fri, 29 May 2026 00:38:54 +0530 Subject: [PATCH 5/6] feat(v0.9.8): render launch sections beneath the hero --- frontend/src/app/page.tsx | 119 ++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index efc3cee..4787d3e 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -2,71 +2,80 @@ import { m } from "framer-motion"; import { SearchBar } from "@/components/search-bar"; +import { ExampleProfiles } from "@/components/landing/example-profiles"; +import { HowItWorks } from "@/components/landing/how-it-works"; +import { StarCta } from "@/components/landing/star-cta"; export default function Home() { return ( -
- {/* Ambient blobs — smaller and lighter on mobile to keep paint cheap */} -
-
+ <> +
+ {/* Ambient blobs — smaller and lighter on mobile to keep paint cheap */} +
+
-
- - + - Deterministic engineering reports · v0.9.7 - + + Deterministic engineering reports · v0.9.7 + -

- Skill Issue -

+

+ Skill Issue +

-

- Your GitHub profile is your real resume.{" "} - Skill Issue reads it honestly. -

+

+ Your GitHub profile is your real resume.{" "} + Skill Issue reads it honestly. +

- - - + + + - -
- 100 - Deterministic -
-
- 6 - Analyzers -
-
- 0 - Hallucinations -
+ +
+ 100 + Deterministic +
+
+ 6 + Analyzers +
+
+ 0 + Hallucinations +
+
-
-
+ + +
+
-
-
+ + + + ); } From cfc27cf85c38518dc16cb8a4588d1809c77a3da8 Mon Sep 17 00:00:00 2001 From: Shaan Satsangi Date: Fri, 29 May 2026 00:42:53 +0530 Subject: [PATCH 6/6] chore(v0.9.8): bump version + docs ritual (launch landing) --- CHANGELOG.md | 7 +++++++ PLAN.md | 18 ++++++++++++++++++ README.md | 4 ++-- backend/app/settings.py | 2 +- backend/pyproject.toml | 2 +- backend/uv.lock | 2 +- docs/PROGRESS_LOG.md | 24 ++++++++++++++++++++++++ frontend/package.json | 2 +- frontend/src/app/page.tsx | 2 +- frontend/src/components/results-view.tsx | 2 +- 10 files changed, 57 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bd7ffc..bd3d125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ Every version listed here must correspond to a slice in [`PLAN.md`](./PLAN.md) w --- +## [0.9.8] — 2026-05-29 + +### Added +- **Launch landing sections.** Beneath the hero: a "see it in action" row of example profiles linking to live reports, a "how it works" methodology section, and a "Star on GitHub" call-to-action. + +--- + ## [0.9.7] — 2026-05-28 ### Added diff --git a/PLAN.md b/PLAN.md index 73a6dbb..8fe979d 100644 --- a/PLAN.md +++ b/PLAN.md @@ -46,6 +46,7 @@ | **v0.9.5** | Security review + hardening (OAuth scope ↓ `read:user`, HTTP security headers) | ✅ shipped | | **v0.9.6** | Load-test harness (warm /analyze; full 100 RPS run = operator step) | ✅ shipped | | **v0.9.7** | Privacy policy + terms + global footer | ✅ shipped | +| **v0.9.8** | Launch landing sections (examples + how-it-works + star CTA) | ✅ shipped | | **v1.0.0** | Public launch | pending | --- @@ -705,6 +706,23 @@ The narrative-mode CHECK constraint was a third drift in the same family — the --- +## v0.9.8 — Launch landing sections (shipped 2026-05-29) + +**Goal:** Below-the-fold launch landing sections beneath the existing hero. + +**Delivered:** `ExampleProfiles` (clickable example-profile cards → live `/u/` reports — the honest proof), `HowItWorks` (deterministic-methodology feature grid), `StarCta` ("Star on GitHub" → repo). Hero/search/stats untouched; `/` still static-prerendered; responsive. No testimonials/usage-stats (none real). Shipped as v0.9.8, keeping 1.0.0 for the actual launch. + +**Design spec:** [`docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md`](./docs/superpowers/specs/2026-05-28-v0.9.8-launch-landing-design.md). +**Sub-plan:** [`docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md`](./docs/superpowers/plans/2026-05-28-v0.9.8-launch-landing.md). + +**Exit criteria:** +- [x] Three sections render beneath the hero; hero unchanged; `/` still static. +- [x] Example cards link to live reports; star CTA → repo (new tab). +- [x] Smoke test passes; frontend lint/tsc/test/build clean; mobile verified. +- [x] Docs ritual + version bump to 0.9.8; tag + release. + +--- + ## v1.0.0 — Public launch **Goal:** Ship it. diff --git a/README.md b/README.md index 0120e7b..12d0dc5 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Engineering insight first. AI flavor second. Scoring is deterministic and explai ## Status -Pre-alpha. Latest shipped release is **v0.9.7** (a Privacy Policy and Terms of Service, linked from a new site-wide footer). v0.9.6 before it added a reusable load-test harness for the warm `/analyze` path (full 100 RPS run is an operator step); v0.9.5 ran a full pre-launch security audit — no high/critical findings — tightening the GitHub OAuth scope to read-only and adding HTTP security headers; v0.9.4 made the DB connection pool size env-tunable and genuinely fixed the back-nav search spinner; v0.9.3 added deletable `/me` history with undo, a golden "creator" scorecard for the project's creator account, and a first (incomplete) attempt at the back-nav spinner fix. Live at https://skill-issue-tau.vercel.app — GitHub OAuth sign-in, Neon Postgres persistence, `/me` history, opt-in `/share/[slug]` public links. The AI narrative layer (Roast + Mentor) runs on **Groq** (`llama-3.3-70b-versatile`). v0.7.0 added Upstash Redis caching (warm `/analyze` ≤ 200 ms); v0.7.2 prod-certified the perf budget (CLS 0.080 → **0** structurally, perf 90 → 94, LCP 2,804 → 2,773 ms); v0.8.0 shipped Sentry (FE+BE), PostHog (events + web vitals), structlog JSON logging, on-voice 404, and a full axe a11y pass; v0.8.1 ships the nightly cron with bearer auth; v0.8.2 pairs it with the manual force-refresh button on `/me`; v0.8.3 hotfixes the empty-repo crash; v0.8.4 fixes the silent narrative misattribution; v0.8.5 closes the post-deploy-Sentry loop with a pre-merge CI gate; v0.8.6 closes v0.7.1's deferred share-page caching; v0.8.7 modernizes project config; v0.9.0 opens Beta hardening with bounded GH fan-out; v0.9.1 closes the /me N+1 + adds per-namespace Report cache versioning; v0.9.2 adds rate limiting (per-IP for anonymous, higher per-user caps for signed-in) on `/analyze` and `/narrative`; v0.9.3 adds deletable `/me` history with undo, attempts the back-nav search-spinner fix, and gilds the creator's scorecard. v0.9.4 makes the DB connection pool size env-tunable (defaults unchanged — RUM showed no pool exhaustion) and lands the real back-nav spinner fix (the v0.9.3 attempt addressed the wrong mechanism); v0.9.5 runs a full pre-launch security audit (no high/critical findings), tightens the OAuth scope to `read:user`, and adds HTTP security headers; v0.9.6 adds a reusable load-test harness for the warm `/analyze` path (the full 100 RPS run is an operator step); v0.9.7 adds a Privacy Policy and Terms of Service, linked from a new global footer. **v1.0.0 — public launch** is next. See [`CHANGELOG.md`](./CHANGELOG.md) for shipped slices, [`PLAN.md`](./PLAN.md) for the full roadmap, and [`docs/PROGRESS_LOG.md`](./docs/PROGRESS_LOG.md) for the most recent session handoff. +Pre-alpha. Latest shipped release is **v0.9.8** (launch landing sections — example reports, a "how it works" methodology section, and a GitHub-star CTA). v0.9.7 before it added a Privacy Policy and Terms of Service, linked from a new site-wide footer; v0.9.6 added a reusable load-test harness for the warm `/analyze` path (full 100 RPS run is an operator step); v0.9.5 ran a full pre-launch security audit — no high/critical findings — tightening the GitHub OAuth scope to read-only and adding HTTP security headers; v0.9.4 made the DB connection pool size env-tunable and genuinely fixed the back-nav search spinner; v0.9.3 added deletable `/me` history with undo, a golden "creator" scorecard for the project's creator account, and a first (incomplete) attempt at the back-nav spinner fix. Live at https://skill-issue-tau.vercel.app — GitHub OAuth sign-in, Neon Postgres persistence, `/me` history, opt-in `/share/[slug]` public links. The AI narrative layer (Roast + Mentor) runs on **Groq** (`llama-3.3-70b-versatile`). v0.7.0 added Upstash Redis caching (warm `/analyze` ≤ 200 ms); v0.7.2 prod-certified the perf budget (CLS 0.080 → **0** structurally, perf 90 → 94, LCP 2,804 → 2,773 ms); v0.8.0 shipped Sentry (FE+BE), PostHog (events + web vitals), structlog JSON logging, on-voice 404, and a full axe a11y pass; v0.8.1 ships the nightly cron with bearer auth; v0.8.2 pairs it with the manual force-refresh button on `/me`; v0.8.3 hotfixes the empty-repo crash; v0.8.4 fixes the silent narrative misattribution; v0.8.5 closes the post-deploy-Sentry loop with a pre-merge CI gate; v0.8.6 closes v0.7.1's deferred share-page caching; v0.8.7 modernizes project config; v0.9.0 opens Beta hardening with bounded GH fan-out; v0.9.1 closes the /me N+1 + adds per-namespace Report cache versioning; v0.9.2 adds rate limiting (per-IP for anonymous, higher per-user caps for signed-in) on `/analyze` and `/narrative`; v0.9.3 adds deletable `/me` history with undo, attempts the back-nav search-spinner fix, and gilds the creator's scorecard. v0.9.4 makes the DB connection pool size env-tunable (defaults unchanged — RUM showed no pool exhaustion) and lands the real back-nav spinner fix (the v0.9.3 attempt addressed the wrong mechanism); v0.9.5 runs a full pre-launch security audit (no high/critical findings), tightens the OAuth scope to `read:user`, and adds HTTP security headers; v0.9.6 adds a reusable load-test harness for the warm `/analyze` path (the full 100 RPS run is an operator step); v0.9.7 adds a Privacy Policy and Terms of Service, linked from a new global footer; v0.9.8 adds launch landing sections (example reports, a how-it-works section, a GitHub-star CTA). **v1.0.0 — public launch** is next. See [`CHANGELOG.md`](./CHANGELOG.md) for shipped slices, [`PLAN.md`](./PLAN.md) for the full roadmap, and [`docs/PROGRESS_LOG.md`](./docs/PROGRESS_LOG.md) for the most recent session handoff. --- @@ -76,7 +76,7 @@ cp .env.example .env # then edit .env and add your GITHUB_TOKEN and OPENA uv run uvicorn app.main:app --reload --port 8000 ``` -Verify: `curl http://localhost:8000/health` → `{"status":"ok","version":"0.9.7","db":"up"|"down","cache":"up"|"down"|"unconfigured"}`. The `db` field reports DB reachability when `DATABASE_URL` is configured; the `cache` field reports Upstash reachability (`unconfigured` when `UPSTASH_REDIS_REST_URL` isn't set — perfectly fine for local dev, the in-process fallback covers it). +Verify: `curl http://localhost:8000/health` → `{"status":"ok","version":"0.9.8","db":"up"|"down","cache":"up"|"down"|"unconfigured"}`. The `db` field reports DB reachability when `DATABASE_URL` is configured; the `cache` field reports Upstash reachability (`unconfigured` when `UPSTASH_REDIS_REST_URL` isn't set — perfectly fine for local dev, the in-process fallback covers it). Hit the analyzer: `curl http://localhost:8000/analyze/octocat`. ### Frontend (`:3000`) diff --git a/backend/app/settings.py b/backend/app/settings.py index fe7ff14..dad27fd 100644 --- a/backend/app/settings.py +++ b/backend/app/settings.py @@ -2,7 +2,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict -VERSION = "0.9.7" +VERSION = "0.9.8" class Settings(BaseSettings): diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d1043bb..aa2e827 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "skill-issue-backend" -version = "0.9.7" +version = "0.9.8" description = "Skill Issue backend — FastAPI service that ingests a GitHub profile and returns a deterministic engineering report." readme = "README.md" authors = [ diff --git a/backend/uv.lock b/backend/uv.lock index cca62ef..8b8623b 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -906,7 +906,7 @@ fastapi = [ [[package]] name = "skill-issue-backend" -version = "0.9.7" +version = "0.9.8" source = { virtual = "." } dependencies = [ { name = "alembic" }, diff --git a/docs/PROGRESS_LOG.md b/docs/PROGRESS_LOG.md index 40a6410..b39ed4e 100644 --- a/docs/PROGRESS_LOG.md +++ b/docs/PROGRESS_LOG.md @@ -19,6 +19,30 @@ Format: --- +## 2026-05-29 — Claude (Opus 4.7) — v0.9.8 shipped (launch landing sections) + +**Slice:** v0.9.8 — below-the-fold launch sections beneath the hero. First v1.0.0-prep piece (the user picked "marketing landing variant"); the launch itself stays human-gated as v1.0.0. + +**Done:** +- Three new client section components under `frontend/src/components/landing/`: `ExampleProfiles` (clickable cards for torvalds/gaearon/sindresorhus/antfu/yyx990803/tj → live `/u/` reports), `HowItWorks` (4-point deterministic-methodology grid), `StarCta` ("Star on GitHub" → repo, new tab). Wired into `page.tsx` after the hero (hero container changed from `flex-1` fill to a `min-h-[calc(100vh-header)]` section; fragment + 3 sections below). +- 1 smoke test (`example-profiles.test.tsx`) — mocks `framer-motion` to plain divs (the happy-dom `m.*` lesson) and asserts 6 cards + the `/u/torvalds` link. Frontend vitest 57 → 58. +- Docs ritual + version bump to 0.9.8. + +**Decisions:** +- **Honest proof only** — example reports (live, clickable), no testimonials/usage-stats (user confirmed none real). The repo wasn't selected as a proof asset, but the user separately asked for a **Star-on-GitHub CTA** to grow stars — added as the closing section. +- **Static star button, no live count** — a live count needs a GitHub-API server fetch, which trips the Cache-Components prerender guard (cf. the v0.9.7 `new Date()` lesson); static keeps `/` cleanly static. Count is a later enhancement. +- **Hero untouched; shipped v0.9.8, not 1.0.0** — 1.0.0 is reserved for the actual launch (its exit criteria are about live traffic). Avatars via plain `` (`github.com/.png`) to skip an image-config change. + +**Verified:** +- Frontend `lint` + `tsc` clean; vitest 58 passed; `next build` clean with `/` still `○ Static`. Backend untouched (290 pass). +- Visual check of the three sections (desktop + mobile): operator quick-confirm on prod after deploy — the smoke test + build only cover structure, not appearance. + +**Blocked / open:** none for v0.9.8. v1.0.0 (public launch) is human-gated. + +**Next:** v1.0.0 — public launch (domain + SSL, launch posts, 72h-stable traffic, on-call, retro). Pre-launch reminders still open: professional legal review; run the full 100 RPS load test. + +--- + ## 2026-05-28 — Claude (Opus 4.7) — v0.9.7 shipped (privacy + terms) **Slice:** v0.9.7 — the final pre-1.0 slice. Privacy Policy + Terms of Service pages + a new global footer. diff --git a/frontend/package.json b/frontend/package.json index 8d89e88..f027eeb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "0.9.7", + "version": "0.9.8", "private": true, "scripts": { "dev": "next dev", diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 4787d3e..33733c3 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -27,7 +27,7 @@ export default function Home() { transition={{ delay: 0.2, duration: 0.5 }} className="rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs font-medium uppercase tracking-wider text-muted-foreground" > - Deterministic engineering reports · v0.9.7 + Deterministic engineering reports · v0.9.8

diff --git a/frontend/src/components/results-view.tsx b/frontend/src/components/results-view.tsx index e6470ab..67a311a 100644 --- a/frontend/src/components/results-view.tsx +++ b/frontend/src/components/results-view.tsx @@ -352,7 +352,7 @@ export function ResultsView({