Commit graph

111 commits

Author SHA1 Message Date
Shekhar Vaidya
3e45bfd0c7 feat(cli): architecture picker + post-fetch O/C/Enter menu
When multiple download links are returned (e.g. x32+x64 for consumer
ISOs), an architecture picker is shown before printing the URL.

After the URL is printed, an interactive menu lets the user open the
link in the default browser (O), copy it to the clipboard (C), or exit
(Enter). Menu is suppressed when stdout is not a terminal (piping).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:49:31 +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
1e00dcee2e fix(backend): validate telemetry fields; add method guard to /cli/version
- Add platform allowlist validation (windows, darwin, linux) and length caps for version (≤20) and product_id (≤10) in handleTelemetry to prevent unbounded Redis hash growth from attacker-controlled field values.
- Add HTTP method guard to handleCLIVersion to reject non-GET requests with 405 Method Not Allowed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 21:14:21 +05:30
Shekhar Vaidya
70f0da6464 docs: add CLI telemetry disclosure to README 2026-06-21 21:09:55 +05:30
Shekhar Vaidya
a21f05239a feat(cli): update check and anonymous telemetry on every run 2026-06-21 21:07:18 +05:30
Shekhar Vaidya
c047a2929f feat(cli): Version var injected via ldflags, updated --help text 2026-06-21 21:03:20 +05:30
Shekhar Vaidya
2978012120 feat(backend): include telemetry counters in /metrics response 2026-06-21 20:58:11 +05:30
Shekhar Vaidya
470abbc94b feat(backend): Redis persistence for metrics (seed + 5min flush + graceful shutdown)
- seedMetricsFromRedis: loads persisted counters into atomics on startup
- flushMetricsToRedis: writes all 12 counters to 3 Redis hashes on demand
- startMetricsFlusher: goroutine that flushes every 5 minutes
- Graceful shutdown: SIGINT/SIGTERM flushes metrics then drains HTTP in 10s
- http.ListenAndServe replaced with http.Server for Shutdown support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 20:48:08 +05:30
Shekhar Vaidya
cbe5ca2f9b feat(backend): POST /telemetry endpoint with Redis HINCRBY counters 2026-06-21 20:43:27 +05:30
Shekhar Vaidya
f968942763 feat(backend): GET /cli/version returns latest CLI version 2026-06-21 20:40:13 +05:30
Shekhar Vaidya
68466da7da docs: spec and implementation plan for CLI telemetry + update check
- docs/superpowers/specs/2026-06-21-cli-telemetry-update-check-design.md
- docs/superpowers/plans/2026-06-21-cli-telemetry-update-check.md

Covers: GET /cli/version, POST /telemetry (Redis HINCRBY), Redis persistence
for existing in-memory metrics (seed + 5min flush + graceful shutdown),
CLI update check goroutine, telemetry goroutine, --help update, MSDL_NO_TELEMETRY opt-out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 20:33:27 +05:30
Shekhar Vaidya
2a41874ad4 fix: evict session and serve stale on Sentinel WAF block
When Microsoft Sentinel rejects a request (HTTP 502 with 'Sentinel'
in body), the session was being reused on every retry — hammering the
same poisoned session and making the block worse.

Now: detect Sentinel response, evict the session from cache, and
return a rateLimitError so stale-on-failure kicks in and users get
the last cached link instead of an error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:46:16 +05:30
Shekhar Vaidya
1ca871a839 fix: support P1 (Unix timestamp) expiry param in contribute endpoint
Consumer ISO CDN URLs use P1 (Unix timestamp) instead of se (RFC3339).
extractRawExpiry now tries se first then falls back to P1, so CLI
contributions of consumer ISOs are no longer rejected.

Also refactors parseLinkExpiry to call extractRawExpiry (DRY) and
fixes stale log message referencing 'se param'.
2026-06-21 19:40:18 +05:30
Shekhar Vaidya
0bad3d1582 fix: update stale log message in contribute expiry validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:39:49 +05:30
Shekhar
84429ebaaf fix: support P1 query parameter for consumer download link expiry 2026-06-21 09:09:54 +05:30
Shekhar Vaidya
3a007662be docs: update README with CLI tool, Redis cache, /contribute endpoint
- Add CLI Tool section: install table, usage examples, crowdsourced cache opt-out
- Update project structure to include cli/ directory
- Add /contribute API reference
- Update caching section to mention Redis/Valkey L2
- Add CLI and Redis to tech stack table
- Bump winget manifests from 0.1.0 to 0.2.0 with updated SHA256

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:32:12 +05:30
Shekhar Vaidya
9c7ae6e6cb feat: Phase 4 — CLI showcase, CliHandoff, CORS fix, recently viewed clear
Merges feat/resilience-phase4 into main.

- CliHandoff component: shows install + msdl command when Microsoft WAF blocks backend
- /cli page: install guide, usage examples, contribute explanation
- CLI nav dock entry and homepage promo strip
- Recently viewed clear button
- Backend CORS fix for Tailscale/LAN subnets
2026-06-20 14:24:06 +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
6bc2785994 feat(cli): formatted download output and contribute message
Show the ISO filename above each link with a separator rule so the
output is easier to read. Updated contribute message to reference
MSDL Web App with URL instead of bare domain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 11:21:19 +05:30
Shekhar Vaidya
36c875ab23 fix: use extractRawExpiry for /contribute expiry validation
parseLinkExpiry has a 1h safety floor that causes it to treat already-
expired URLs as valid. Replace with extractRawExpiry + direct se
timestamp comparison so any URL expiring < 1h out is rejected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 16:12:36 +05:30
Shekhar Vaidya
9a5f41290d feat: Phase 3 crowdsourced cache contribution
- Redis L2 persistent cache: initRedis() from REDIS_URL env, seed
  in-memory linkCache on startup, write-through on every fresh fetch
  and background refresh (silent fallback to memory-only if unavailable)
- POST /contribute endpoint: validates product catalog, expiry > 1h,
  Microsoft CDN host allow-list, per-IP token bucket (~5/min),
  CONTRIBUTE_SECRET header; writes to in-memory + Redis; logs all
  accepts and rejections
- CLI --no-contribute flag (also MSDL_NO_CONTRIBUTE=1 env var):
  background goroutine posts raw MS JSON to /contribute after every
  consumer fetch; best-effort 5s timeout; opt-out message to stderr

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 14:07:35 +05:30
Shekhar
7ebf5a9560
feat: msdl CLI — direct Windows ISO downloads from user's machine (Phase 2)
feat: msdl CLI — direct Windows ISO downloads from user's machine (Phase 2)
2026-06-18 13:13:04 +05:30
Shekhar
72ad55eda8
feat: web graceful degradation for Microsoft WAF blocks (Phase 1)
feat: web graceful degradation for Microsoft WAF blocks (Phase 1)
2026-06-18 13:09:58 +05:30
Shekhar Vaidya
9acc5dbf31 feat(cli): interactive language picker for eval downloads 2026-06-18 13:08:05 +05:30
Shekhar Vaidya
4cc344e666 chore(winget): fill SHA256 for v0.1.0 Windows binary 2026-06-18 12:47:04 +05:30
Shekhar Vaidya
ad7ebb312f fix(ci): check WINGET_TOKEN in shell, not in workflow if condition 2026-06-18 12:43:10 +05:30
Shekhar Vaidya
17691b0c79 chore(winget): initial manifest for starkSV.msdl v0.1.0 2026-06-18 12:17:00 +05:30
Shekhar Vaidya
5c7f805f41 ci: GitHub Actions release workflow for msdl CLI binaries 2026-06-18 12:11:56 +05:30
Shekhar Vaidya
cdf64f4c3e feat(cli): main flow with interactive and named-arg modes 2026-06-18 12:09:56 +05:30
Shekhar Vaidya
2f93726ec9 fix(cli): guard empty slices in pickers, propagate scanner I/O errors 2026-06-18 12:01:13 +05:30
Shekhar Vaidya
e8a4be2698 feat(cli): interactive numbered picker (stdin/stderr separated) 2026-06-18 11:53:59 +05:30
Shekhar Vaidya
09c3b2b175 feat(cli): direct Microsoft client (session, SKU, links, eval scrape) 2026-06-18 11:45:14 +05:30
Shekhar Vaidya
86f9b685de feat(cli): product catalog with word-based search 2026-06-18 11:39:09 +05:30
Shekhar Vaidya
9a860022fd feat(cli): scaffold Go module 2026-06-18 11:36:33 +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
eb0fc51fe2 chore: remove debug cookie-count log from proxy handler
Diagnostic log added during Sentinel investigation — no longer needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 22:09:26 +05:30
Shekhar Vaidya
04a4d7e58c debug: log cookie count in jar before proxy request
Temporary diagnostic — tells us whether Set-Cookie headers from
Microsoft are actually reaching the backend through the CF Worker.
If count is 0, the Worker is stripping them or MS sets cookies via JS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:50:12 +05:30
Shekhar Vaidya
6f2c02d79b fix: forward cookies through CF Worker to satisfy Microsoft Sentinel
Sentinel started rejecting all /proxy requests because cookies set during
the fingerprinting flow (vlscppe/ov-df) were never reaching the
GetProductDownloadLinksBySku call.

Two gaps closed:
- CF Worker now forwards Cookie header to Microsoft and Set-Cookie headers
  back to the backend
- Backend uses a simpleCookieJar (domain-scoping disabled) shared across
  the full session: setup → warmup → download link fetch. Standard
  cookiejar rejects microsoft.com cookies when the request URL is the
  Worker domain.

Tested locally without Worker (direct MS calls): download links returned,
no Sentinel error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:36:43 +05:30
Shekhar Vaidya
04e745272b chore: mark v1.2.0 shipped in CLAUDE.md and PROGRESS.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 22:14:29 +05:30
Shekhar
56549b7201
Merge pull request #17 from starkSV/feat/ux-improvements
feat: expiry countdown, refresh links, CLI tabs, recently viewed
2026-05-22 21:56:07 +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
0557339e72 chore: remove .claude/ from git tracking, add to .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 21:07: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
e3f34016c6 chore: plan frontend UX improvements — expiry countdown, refresh, CLI tabs, recently viewed, file size
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 20:54:55 +05:30
Shekhar Vaidya
17315ad4e9 docs: add PROGRESS.md with full shipping history and production metrics
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 16:27:19 +05:30
Shekhar Vaidya
efe0c241ab chore: update CLAUDE.md — mark #12 and Beyond #12 items complete, defer rate limiter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:34:21 +05:30