Commit graph

53 commits

Author SHA1 Message Date
Shekhar Vaidya
fe889e85a7 fix(frontend): use npm install instead of npm ci (no lockfile committed) 2026-09-02 11:41:07 +05:30
Shekhar Vaidya
16f034e18c feat(frontend): add nginx config for SPA routing 2026-09-02 11:38:34 +05:30
Shekhar Vaidya
3407bc31c4 feat(frontend): add multi-stage Dockerfile for Coolify static build 2026-09-02 11:29:07 +05:30
Shekhar Vaidya
d562bf8d0e fix(frontend): Windows 10 lifecycle text/badge were stale (dated Oct 2025, now Aug 2026)
Homepage's featured card said "Security support until October 2025" --
that date has already passed, so it read as a future deadline that
wasn't. Updated to reflect actual status (mainstream support ended,
consumer ESU runs through Oct 2026) -- kept tight to match the other
three cards' description length so the grid stays even (the first
draft ran long enough to wrap to 3 lines and grow that one card's
height past its siblings).

Also found products.json still tagged both Windows 10 22H2 variants
(2618, 2378) as "EOL SOON" -- inconsistent with the homepage's own
"EOL"/"END OF LIFE" badge for the same product, and equally stale
for the same reason. products.json's badge field renders verbatim
on the product detail page, so this was live and user-facing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 23:28:21 +05:30
Shekhar Vaidya
5a806eea87 fix(frontend): remove redundant, ignored _redirects rule
Cloudflare's deploy log has been flagging the SPA fallback rule
(/* /index.html 200) as a false-positive infinite loop and ignoring
it on every deploy. Investigated live: direct navigation to /about, a
dynamic route, and a genuinely invalid path all return 200 with the
correct content already, since Cloudflare Pages' own default fallback
serves index.html for any unmatched path. The rule was dead weight --
removing it to stop the recurring warning noise. Closes the tracked
issue in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 10:19:50 +05:30
Shekhar Vaidya
73eee730c9 fix(frontend): CLI curl-command copy bug, stale/missing content, and Fido attribution cleanup
- CliHandoff: the visible curl install command was a hardcoded truncated
  placeholder ("...install.sh"), so the copy button worked but manually
  selecting/copying the text gave a broken command. Now shows the real URL
  and lets CSS `truncate` handle the visual clipping.
- Dock: adds a full-width backdrop-blur shelf under the floating desktop
  dock so it doesn't visually blend into scrolled content (page bg is
  near-black, so plain color gradients were invisible -- blur is what
  actually reads). Desktop only; the mobile dock is already a flush bar.
- HomePage: hero now mentions "Open source" (linked, dotted underline) --
  previously absent anywhere on the landing page.
- StatsBar: "releases available" count now includes eval/enterprise
  editions, not just the consumer catalog (17 -> combined total).
- About/Privacy/Disclaimer: these hadn't been updated since the CLI
  shipped. Privacy Policy now discloses the CLI's anonymous telemetry and
  crowdsourced link-contribution behavior (previously undisclosed). About
  page's stale hardcoded product list replaced with a link to the catalog,
  plus a new section explaining the CLI. Disclaimer now covers the CLI
  binary under the same terms.
- Fido/Rufus attribution was scattered with duplicate linked mentions on
  the same pages; consolidated to one canonical linked credit per surface
  (About's Credits section, README's intro) instead of repeating it.
- FAQAccordion: fixed a factual error ("ported to Go and Node.js" -- no
  Node.js backend exists), and linked the actual repo in the open-source
  FAQ answer (previously just asserted it with no link).
- sitemap.xml: removed a dead entry for product 48, which was already
  removed from the catalog (Microsoft returns 502 for it).
- README: fixed three inaccuracies in the /contribute API doc (wrong auth
  header, wrong body field name, wrong status codes) against the actual
  backend/main.go implementation, and added the missing telemetry/sentinel
  fields to the /metrics example response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 10:10:38 +05:30
Shekhar Vaidya
da8787e93a feat: add check-new-releases tools; fix msdls_v3.py; add missing 25H2 V2 China variants
Moves msdls_v3.py from repo root into scripts/check-new-releases/,
alongside a new Go tool, documented as Method 1 (Python brute-force
range scan, can write results to a catalog-shaped JSON) and Method 2
(Go auto-discovery via page-scrape + bounded adjacent-ID probe, no
range-guessing needed). Only Windows 11 is checked -- 8.1 is fully
frozen and Windows 10 is past end-of-life, so neither will produce a
new consumer ISO again.

Fixed msdls_v3.py's release-name extraction: it checked EditionName/
ReleaseName/FriendlyName, none of which exist in the real API
response -- the actual field is ProductDisplayName, confirmed live.
Also added the vlscppe session-permit call to setup_session(), which
was skipped entirely; higher-risk gap for this script's brute-force
range-scan usage pattern than for a single lookup.

Both tools' live runs surfaced a real catalog gap: product IDs
3322/3323/3325/3326 (Home/Pro China variants of the 25H2 "V2" refresh)
exist on Microsoft's side but weren't in our catalog. Added them to
cli/catalog.go, products.json, validContributeProducts, and
sitemap.xml, and renamed 3321/3324 from our own guessed "(Updated
Oct)" label to Microsoft's actual name for this refresh, "(V2)"
(their internal name is "Windows 11 25H2__V2"; cleaned up the
double-underscore for user-facing display).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 11:07:45 +05:30
Shekhar Vaidya
3ceb179ae6 fix(frontend): remove redundant brew formula-name disclaimer from CLI page
The msdl-cli vs msdl naming footnote is useful context in README/release
notes, but unnecessary clutter for a casual visitor on the web CLI page --
the "recommended" badge and the command itself are enough.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 00:58:35 +05:30
Shekhar Vaidya
4dce41483d fix: update Homebrew install command to msdl-cli formula
homebrew/core already has an unrelated package literally named "msdl"
(a streaming-protocol downloader). brew install msdl silently
resolved to that instead of our tap, since Homebrew always prefers
core for a bare-name collision -- confirmed in production when a
user's `brew install msdl` pulled homebrew-core's msdl 1.2.7-r2
instead of ours. The tap's formula is renamed to msdl-cli
(starkSV/homebrew-msdl, separate repo) to fix this permanently; the
installed command itself is unaffected, still just `msdl`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 00:52:57 +05:30
Shekhar Vaidya
5eec0351e7 feat: add curl | bash installer for Linux/macOS without Homebrew
Adds a GET /install.sh endpoint on the backend (embedded via Go's
embed package, so the script stays a real, shellcheck-able .sh file
rather than a Go string literal). Auto-detects OS/arch (including
Termux on Android via $PREFIX) and always resolves the latest GitHub
release via the /releases/latest/download/ redirect, so unlike the
winget/brew/AUR manifests it needs no per-release maintenance.

Verified end-to-end in an ephemeral Ubuntu container (both the normal
/usr/local/bin path and the Termux $PREFIX path), and locally against
a running backend instance.

Documented alongside the existing winget/Homebrew instructions in
README.md, the release notes template, the web CLI page, and the
per-product CliHandoff card.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 22:28:23 +05:30
Shekhar Vaidya
eddf7802bb docs: note AUR publishing is blocked; add Homebrew install everywhere
Arch Linux disabled new AUR account registrations on 2026-06-15 after
a malware campaign compromised 1,500+ AUR packages. There's no
announced reopening date, so aur/msdl-bin/README.md now says so
clearly instead of implying publishing is just a pending step.

Adds the Homebrew tap install command (brew tap starkSV/msdl && brew
install msdl) to every place winget is already documented: README.md,
the release workflow's notes, the web CLI page, and the per-product
CliHandoff card. Also adds the missing linux-arm64 row to the manual
download tables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 13:39:30 +05:30
Shekhar Vaidya
a9c713cd6a feat(cli): combined product picker with eval products + clipboard fix
- Interactive `msdl` (no flags) now lists consumer + eval products in one
  picker with an Evaluation / Enterprise separator; selecting a server
  product routes to the eval flow automatically
- copyToClipboard calls clip.exe by full SystemRoot path, bypassing
  cmd.exe PATH lookup that failed in some terminal environments
- CliHandoff card: winget primary install + msdl (no .exe) in run command

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 07:25:03 +05:30
Shekhar Vaidya
9e836503c0 Merge branch 'main' into feat/cli-telemetry 2026-06-30 06:40:46 +05:30
Shekhar Vaidya
d2c5c3c082 feat(frontend): use tracked shortlink for CLI releases download button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 12:17:59 +05:30
Shekhar Vaidya
40327c33b4 fix(frontend): show lockdown message on error path when no stale data
When the backend returns 429+lockdown with no cached stale data to serve,
the error section now shows the human-readable lockdown explanation instead
of the raw "Sentinel marked this request as rejected." string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 12:12:51 +05:30
Shekhar Vaidya
3141635300 feat(backend+frontend): Sentinel lockdown mode + stale UX overhaul
Backend (main.go):
- negCacheEntry gains IsSentinel bool; lockdownTTL = 90min constant
- Lockdown gate at top of handleProxy: serves stale with X-MSDL-Lockdown:1
  header or 429 {"error":"...","lockdown":true} — zero MS API calls made
- Sentinel stale path: sets 90min lockdown neg cache, adds lockdown header,
  suppresses background refresh (retrying extends the Sentinel block timer)
- Non-Sentinel stale path: unchanged (60s neg cache, bg refresh fires)
- Expose X-MSDL-Lockdown in Access-Control-Expose-Headers

Frontend (ProductDetailPage.tsx):
- isLockdown state: set from X-MSDL-Lockdown header or data.lockdown field
- Stale state hides expired download links entirely; shows CLI recommendation
  inside the card instead of sending users to look for options elsewhere
- Lockdown: red banner explaining 90min cooldown + highlighted CLI card,
  no Refresh button (it cannot help while Sentinel block is active)
- Normal stale: amber banner + highlighted CLI card + secondary Refresh button
- Outer CliHandoff suppressed when already shown inside card (stale states)

Frontend (CliHandoff.tsx):
- CLI command uses msdl.exe (primary audience is Windows users)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 12:07:00 +05:30
Shekhar Vaidya
29d6b6b3f1 feat(frontend): elevate winget install to primary method on CLI page
Replaces the dim "coming soon" footnote with a featured green card at the
top of the Install section. Manual binary downloads moved to a secondary
"Other platforms" section below. Ships with the post-winget-approval release.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 21:38:40 +05:30
Shekhar Vaidya
b27d7c0b9f feat: CLI page, dock entry, homepage promo, and clear recently viewed
- Add /cli page with install guide, usage examples, and contribute section
- Add CLI item to nav dock (between Products and About)
- Add homepage CLI promo strip (terminal snippet style, links to /cli)
- Add clear button to recently viewed section
- Integrate CliHandoff component into ProductDetailPage error states

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:22:00 +05:30
Shekhar Vaidya
bf5dca1fe4 feat: Phase 4 web-to-CLI handoff UX
- Add CliHandoff component: shows install link + pre-filled msdl command
- Highlighted card (Recommended) shown inline on Sentinel/WAF errors
- Collapsed version shown below OfficialFallback on stale links
- Rename instructions with platform-specific filenames (msdl.exe / msdl)
- Fix backend CORS to allow local network origins (100.x, 192.168.x)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 12:16:43 +05:30
Shekhar Vaidya
123643a947 feat: use short links for guide URLs in OfficialFallback; add Win 8.1 guide
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:29:38 +05:30
Shekhar Vaidya
3cd8528430 feat: add tech-latest guide links to official fallback component
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:20:42 +05:30
Shekhar Vaidya
77056cb50f feat: Phase 1 graceful degradation for WAF-blocked links
- Backend: emit X-MSDL-Link-Status (fresh/cached/stale) and
  X-MSDL-Link-Expires headers on every /proxy response; expose
  both via Access-Control-Expose-Headers
- Frontend: read headers in handleGetLinks/handleRefreshLinks;
  show amber stale warning when backend is WAF-blocked
- Frontend: new OfficialFallback component (collapsible) with
  step-by-step guide to Microsoft's official download page,
  pre-filled with the user's selected language; shown on stale
- Plan: add Redis/Valkey persistence section to Phase 3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:13:46 +05:30
Shekhar Vaidya
5d1d402715 chore: remove product 48 (Win 8.1 Single Language) — Microsoft removed it server-side
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:59:39 +05:30
Shekhar Vaidya
b2c9e2d874 feat: expiry countdown, refresh links, CLI tabs, recently viewed
- Backend: ?force=true on /proxy bypasses cache for fresh link fetch
- Frontend: live expiry countdown from `se` param; falls back to static 24h for consumer links
- Frontend: Refresh button appears when link expires in <6h, fires force fetch
- Frontend: CliCommand replaces Aria2Tip — wget/curl/aria2 tabs, persists in localStorage, on all pages
- Frontend: RecentlyViewed on homepage — localStorage, tracks consumer + eval pages, shows expired state
- chore: add .claude/ to .gitignore; remove FileSize (not returned by Microsoft CDN)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 21:55:10 +05:30
Shekhar Vaidya
1c54c36d03 feat: expiry countdown, refresh links, CLI tabs, recently viewed, file size support
- Backend: ?force=true on /proxy bypasses cache for fresh link fetch
- Frontend: parse `se` param for live expiry countdown on download links
- Frontend: show Refresh button when link expires in <6h, force-fetches fresh URL
- Frontend: CliCommand component replaces Aria2Tip — wget/curl/aria2 tabs, persists selection in localStorage
- Frontend: RecentlyViewed component — localStorage, shows active countdown or expired state
- Frontend: FileSize shown alongside arch if returned by Microsoft CDN

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 21:06:17 +05:30
Shekhar Vaidya
ddc657e0a7 fix(seo): audit and fix SEO across all pages
- ProductsPage: align <title> with og:title ("All Windows ISO Releases")
- Disclaimer + PrivacyPolicy: add noindex (legal/thin pages shouldn't rank)
- ProductDetailPage: improve auto-generated meta description wording;
  add SoftwareApplication JSON-LD to match EvalDetailPage
- HomePage: update JSON-LD description to include Windows Server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:14:52 +05:30
Shekhar Vaidya
fe1191b07f fix(ui): mention Server & Enterprise in HowItWorks step 1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:10:37 +05:30
Shekhar Vaidya
4ad8cfbfcc feat: update ComparisonTable and FAQAccordion to reflect eval ISOs
Add "Server & Enterprise ISOs" row to the Why MSDL comparison table
and a new FAQ entry explaining eval editions, the 180-day trial, and
where to find them. Closes #eval-polish.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:08:55 +05:30
Shekhar Vaidya
b1458934c3 fix(ui): standardise page widths to two-tier system
Listing pages (home, products, eval): max-w-4xl
Content pages (product detail, eval detail, about, privacy, disclaimer): max-w-2xl

Previously four different widths were in use across the app.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-18 22:04:09 +05:30
Shekhar Vaidya
fdf4d7258d fix(seo): improve meta tags and JSON-LD for eval product pages
- Add unique seoDesc field to each eval product (≤155 chars)
- EvalDetailPage: use seoDesc for description, add Evaluation to
  title, add SoftwareApplication JSON-LD alongside breadcrumb
- EvalPage: add ItemList JSON-LD for the listing page

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-18 22:01:55 +05:30
Shekhar Vaidya
a78059187f feat: add Enterprise & Server eval ISOs via Microsoft evalcenter
Adds /eval listing page and /product/<slug> detail pages for Windows
Server 2025/2022/2019/2016 and Windows 11 Enterprise evaluation ISOs,
sourced from Microsoft evalcenter without any session flow.

Backend: new /evallinks endpoint fetches evalcenter page, extracts
fwlinks, follows all redirects in parallel, detects arch + locale.
24h cache per product with startup warming so first hit is instant.

Frontend: EvalPage listing at /eval, EvalDetailPage at /product/<slug>
matching consumer structure with downloads, aria2 template, system
requirements, and also-available section. Smart ProductRouter in
App.tsx dispatches slug vs numeric productId. Dock highlights Products
tab for /product/* and /eval routes. CTA banner on home page and
footer link added. sitemap.xml updated with 6 new URLs.

Closes #13

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-18 21:56:57 +05:30
Shekhar Vaidya
58d66fe06d docs: update README, About, Privacy and Disclaimer for CF Worker
- README: add cloudflare-worker/ to project structure, update How It
  Works diagram to show CF Worker hop, add CF Worker setup instructions
  under Running Locally, and fix Deployment section (Worker is an
  outbound proxy, not the backend host)
- About: mention CF Worker distributes requests across Cloudflare edge
- Privacy: add Cloudflare as a third-party service, update date
- Disclaimer: update date

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:58:07 +05:30
Shekhar Vaidya
e7b0fea94b fix(frontend): fix TypeScript error in Back button navigate call
Split ternary into two separate navigate() calls to satisfy TypeScript
overload resolution — navigate(delta: number) and navigate(to: To)
are distinct overloads that cannot share a ternary return type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:11:35 +05:30
Shekhar Vaidya
8b036e94ba feat: route Microsoft API calls through Cloudflare Worker to avoid IP blocks
- Add cloudflare-worker/worker.js: edge proxy forwarding requests to allowed
  Microsoft hosts from Cloudflare distributed IPs. Set CF_WORKER_URL env var
  to activate; omit to keep direct-to-Microsoft behaviour (self-hosters unaffected).
- Wrap all outbound Microsoft URLs in proxyURL() in main.go so the Worker
  sits transparently in front of every session and download-link request.
- Fix Back button navigating to external referrer when user lands directly
  on a product URL (#5) — use window.history.state?.idx to detect whether
  there is prior in-app history before calling navigate(-1).

Closes #5, Closes #6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:01:03 +05:30
Shekhar Vaidya
a8f9ba1da1 feat(frontend): add Google Search Console verification meta tag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 20:51:28 +05:30
Shekhar Vaidya
86da27cb8c feat(frontend): add per-page SEO, 404 page, OG tags, and sitemap updates
- Replace react-helmet-async (React 19 incompatible) with native React 19
  document metadata hoisting across all pages
- Add per-page <title>, <meta name="description">, <link rel="canonical">,
  og:title, og:description, og:url to HomePage, ProductsPage, ProductDetailPage,
  AboutPage, DisclaimerPage, PrivacyPolicyPage
- Add JSON-LD SoftwareApplication schema to HomePage and BreadcrumbList to
  ProductDetailPage
- Add 404 NotFoundPage with noindex meta and canonical to home
- Add og:site_name, og:image, og:type, twitter:card/title/description/image
  to index.html as static fallback; remove duplicate static canonical
- Update sitemap.xml with product IDs 3321, 3324 and lastmod dates
- Add product screenshots to README and update description
- Add og-image.png placeholder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 20:35:48 +05:30
Shekhar Vaidya
79e21bb487 fix(frontend): add --disable-ipv6=true to generated aria2 command
IPv6 failures (broken routing, disabled IPv6, VPN/Pi-hole setups) cause
aria2 to abort instead of falling back to IPv4. The flag is a safe
default on all network configurations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 19:37:17 +05:30
google-labs-jules[bot]
fc60a9f37b fix: prevent inactive products from triggering backend requests
- Update ProductDetailPage.tsx to only set isValidated(true) for active products.
- Add regex validation to ensure productId is numeric.
- Initialize meta.active to false.
- Add loading state for catalog fetch.
- Fix minor lint issue in ProductsPage.tsx.

Co-authored-by: starkSV <21262426+starkSV@users.noreply.github.com>
2026-05-12 09:47:48 +00:00
Shekhar Vaidya
79450e4b35 Prevent skuinfo API calls when product is marked inactive 2026-04-11 13:11:01 +05:30
Shekhar Vaidya
2d688ae7e8 Implement inactive product state, restore backend tracker limits, and add dedicated catalog error UI panel 2026-04-11 13:01:56 +05:30
Shekhar Vaidya
aac8f5d990 Modernize UI, unify product catalog, and backend optimization
- Migrated products.json to structured metadata format.

- Refactored ProductDetailPage to eagerly reset state and validate product IDs against local catalog.

- Dynamic data fetching in HomePage and StatsBar for total release counts.

- Adjusted UI layout in App.tsx and UX states (404/Loading) for missing dependencies.

- Shortened backend tracking HTTP timeouts to prevent local Pi-Hole hangs.
2026-04-11 11:17:54 +05:30
Shekhar
f43a0e2dfa perf: replace heavy blur-3xl filter with css radial gradient to maximize mobile lighthouse score 2026-04-10 23:18:22 +05:30
Shekhar
4c0539517c fix: remove unused useNavigate hook causing TS6133 build error 2026-04-10 23:04:29 +05:30
Shekhar
a1ef9a6baa feat: improve accessibility and structural SEO logic 2026-04-10 22:59:16 +05:30
Shekhar
1e63d3e5ff feat: implement dynamic SEO metadata for static pages 2026-04-10 22:58:27 +05:30
Shekhar
089662d1f3 feat: setup dynamic document metadata bindings for SEO SPA crawling 2026-04-10 22:56:34 +05:30
Shekhar
f7052ee539 feat: add robots.txt and sitemap.xml for SEO 2026-04-10 22:47:31 +05:30
Shekhar
41bee3b7d1 chore: remove incorrect business product IDs and patch referer proxy logic 2026-04-10 22:38:48 +05:30
Shekhar Vaidya
ed87d0cb0e feat: add 404 fallback and update products 2026-04-10 21:58:57 +05:30
Shekhar Vaidya
9c5cb88f19 feat: add Windows 10 Business Edition ID 2026-04-10 21:39:59 +05:30