feat(website): add comparison pages for other diff tools - #968
Conversation
Adds a /compare/ cluster answering the "hunk vs X" query directly: a hub plus head-to-head pages for delta, difftastic, diff-so-fancy, git diff, and Plannotator. Each page is one catalog entry rendered three ways, so the HTML page, the `.md` variant agents read, and the structured data can never disagree about a capability mark. The capability table is republished as `additionalProperty` on both products in the page's TechArticle, which lets an answer engine read the comparison without inferring it from a `<table>`, and each page also carries FAQPage and BreadcrumbList data. Marks come from each project's own documentation, with a note wherever a bare mark would mislead, and rows the other tool wins are in the tables. Tests enforce that: every page recommends the other tool for something, concedes at least one capability, explains every hedged mark, and cites its sources. Also extracts the head shared by the hand-built marketing pages into PageHead.astro rather than adding a third copy of it, and moves the JSON-LD serializer to a shared module now that two catalogs use it.
Two Opus reviews of the comparison pages, one fact-checking the rival claims against each project's own docs and one auditing the Hunk claims and the code, turned up errors worth fixing before this ships. Wrong about other projects: - diff-so-fancy computes character-level emphasis with a bundled copy of git contrib/diff-highlight. It does not pass through git --word-diff. - Plannotator toggles Split and Unified from its settings panel, polls the repo for a moved working tree, exposes WebMCP tools on its plan and annotate surfaces, and has AI review built in. All four were marked absent; the AI review row was missing entirely. - `diff.external` is Git's external diff driver, not a difftool, and other subcommands then need --ext-diff. - delta's n/N are opt-in via `navigate` and move between files, and delta has its own theme collection beyond bat's syntax themes. - difftastic's performance caveat is under README "Known Issues", not a FAQ, and its manual lists far more languages than the README's "over 30". - git diff does have word-level diffing (--word-diff, --color-words); the row was missing from the one table where Git is the subject. - diff-so-fancy gets the same partial mark delta gets for pager-based VCS support, rather than a bare no for the same mechanism. Wrong about Hunk: - The "Runtime dependency" row was polarity-inverted against every other row and contradicted Hunk's own install docs. It is now "Runs with no language runtime installed", marked honestly. - --fast is experimental everywhere else, so say so here. - Dropped a "predictable cost on heavily-changed files" row that asserted a property nothing in the repo establishes. - Hunk does open git log -p under `hunk pager`, so that is out of the blame/grep row, and saving preferences can write .hunk/config.toml. Structured data: - Row notes are no longer published as each product's `description`. A note describes the row, so attaching it to one product printed claims about the other tool under this tool's name. - Products are multi-typed ["SoftwareApplication", "Product"] because additionalProperty is outside SoftwareApplication's schema.org domain and validators would have dropped the whole payload. - Breadcrumbs carry a real trail, and datePublished no longer moves when claims are re-checked. Also derives the title year from the review date, moves the Markdown renderer to lib/comparisonMarkdown.ts so it is unit-testable without pulling Astro's types into the root program, and shares SITE_ORIGIN and Hunk's own language/license/platform facts instead of retyping them. Tests now cover the Markdown renderer directly, and assert capability names are unique, sources cite the rival's own host, the answer names both tools, the title year tracks the review date, and no row note leaks into the structured data.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR adds a catalog-backed comparison section with five HTML pages, parallel Markdown endpoints, and structured data, while extracting shared marketing-page metadata helpers.
Confidence Score: 4/5The PR appears safe to merge after the non-blocking unit-test colocation issue is addressed. The comparison routes, shared renderers, metadata extraction, and documented CLI surfaces have no established functional regression; the remaining issue is the repository-required placement of two new unit suites. Files Needing Attention: scripts/check-website-helpers.test.ts and scripts/check-comparison-catalog.test.ts Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Catalog[Comparison catalog] --> HTML[HTML comparison pages]
Catalog --> Markdown[Markdown endpoints]
Catalog --> JSONLD[JSON-LD structured data]
HTML --> Hub[Comparison hub and sibling links]
PageHead[Shared PageHead component] --> HTML
PageHead --> Home[Existing home page]
PageHead --> Extensions[Existing extensions page]
Prompt To Fix All With AI### Issue 1
scripts/check-website-helpers.test.ts:1-5
**Website unit tests are misplaced**
These suites directly test modules under `website/src/`, but they live in the unrelated root `scripts/` directory. Colocate this suite with the website helpers it covers, and likewise move `check-comparison-catalog.test.ts` beside the comparison catalog, so source changes and their unit coverage remain discoverable together.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(website): correct comparison claims ..." | Re-trigger Greptile |
`astro check` covers website/tests, so the destructured `({ name })`
callbacks added with the JSON-LD assertions failed noImplicitAny in CI.
Annotate the shape `evaluate` returns instead, which also documents what
the block is asserting about.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NsaTD6RoPx9Q6sQobq9fFK
The problem
People deciding on a terminal diff tool search "hunk vs delta", "hunk vs difftastic", "better git diff". hunk.dev had nothing to answer those queries, so the ranking went to third-party listicles that get Hunk wrong.
This adds a
/compare/section: a hub plus five head-to-head pages, at the URLs the questions are typed as./compare/hunk-vs-delta//compare/hunk-vs-difftastic//compare/hunk-vs-git-diff//compare/hunk-vs-diff-so-fancy//compare/hunk-vs-plannotator/Approach
Each page is one entry in
website/src/data/comparisons.ts, rendered three ways: the HTML page, a Markdown variant at the same URL plus.md, and JSON-LD. One catalog means a capability mark cannot differ between what a reader sees and what a crawler reads.Page shape is built for the reader who arrived from a "hunk vs X" query: the answer first, then a two-sided verdict, then the argument, then the capability table, then the questions that query implies.
For answer engines and agents. Every page carries
TechArticle,FAQPage, andBreadcrumbList, with the capability table republished asadditionalPropertyon both products so the comparison is readable without inferring it from a<table>. The products are multi-typed["SoftwareApplication", "Product"]becauseadditionalPropertyis outsideSoftwareApplication's schema.org domain and a validator would otherwise drop the payload. Row notes are deliberately not published as either product'sdescription: a note describes the row, so attaching it to one product prints claims about the other tool under this tool's name. Each page is also served as clean Markdown, linked with<link rel="alternate">and surfaced in/llms.txt, matching what the docs already do for AI crawlers.Editorial rule. Every mark comes from the other project's own documentation, with the caveat beside it wherever a bare mark would mislead, and rows the other tool wins stay in the tables. Tests enforce this rather than trusting it: a page that never recommends the other tool, concedes no capability, leaves a hedged mark unexplained, or cites no source from the rival's own host fails the suite.
Non-goals
Incidental refactors
PageHead.astroextracts the<head>shared by the hand-built marketing pages, rather than adding a third copy. The emitted head for/and/extensions/is byte-for-byte identical to before (verified against a build of the parent commit).website/src/lib/jsonLd.tsnow that two catalogs use it. As a side effect the home page picks up<-escaping it previously lacked.website/src/lib/comparisonMarkdown.tsso it is unit-testable without pulling Astro's DOM types into the root TypeScript program.Review process
Two Opus reviews ran against the first commit, one fact-checking rival claims against primary sources and one auditing the Hunk-side claims against this repo plus the code.
bc66289is the fixes; the notable ones:contrib/diff-highlight. It does not pass throughgit --word-diff.diff.externalis Git's external diff driver, not a difftool, and other subcommands then need--ext-diff.n/Nare opt-in vianavigateand move between files, and delta has its own theme collection beyond bat's syntax themes.git diffdoes have--word-diff/--color-words; the row was missing from the one table where Git is the subject.--fastlost its "experimental" qualifier, and one row asserted a performance property nothing in the repo establishes. All fixed or dropped.Verification
bun run typecheck,bun run lint,bun run format:check— cleanbun test scripts/— 302 passcd website && bun run check— 0 errors;bun run build— 60 pageswcag2a/wcag2aa) across the hub and all five comparison pagesNot run: the TUI suites (
test:integration,test:tty-smoke). This change touches no Hunk source, onlywebsite/and three root test files.Known limitations and follow-ups
scripts/, not beside the code they cover. Colocation would be better, but nothing currently runs unit tests underwebsite/src/:DEFAULT_TEST_PATTERNSinscripts/run-test-suite.tsdoes not include./website, and the website workspace's only test script is Playwright withtestDir: "./tests". Moving them today would silently drop the coverage. Doing it properly means wiring a Bun test runner into the website workspace plus a CI job — a separate change. The current placement follows the existing convention set byscripts/check-extension-catalog.test.ts, which testswebsite/src/data/extensions.tsthe same way. (Raised by Greptile; discussed on that thread.)og.png. Per-comparison OG images would be better;website/scripts/generate-og.tsalready exists if that is worth a follow-up.🤖 Generated with Claude Code
https://claude.ai/code/session_01NsaTD6RoPx9Q6sQobq9fFK