Skip to content

feat: real search engine, favourites, safe AI assistant, CI/tests, docs — and two secret leaks fixed - #1

Merged
krishna3163 merged 1 commit into
mainfrom
arena/c5e2ce5a-opendiscover
Oct 10, 2026
Merged

krishna3163 merged 1 commit into
mainfrom
arena/c5e2ce5a-opendiscover

Conversation

@krishna3163

Copy link
Copy Markdown
Owner

Summary

A full pass over the repository: two critical secret leaks fixed, search rebuilt into a real ranking engine, favourites added, the AI assistant de-deprecated (and made to work with no API key), plus routing/a11y/SEO robustness, a design system in CSS, 100 tests, CI, and real contributor docs.

106 files changed, +12,138 / −2,190 · every commit builds, lints, type-checks and passes tests.


🔴 Security — action required from the maintainer

Issue Status in this PR What you still need to do
A live Gemini API key was committed in .env (commit 56c5666, public repo) Untracked, git-ignored, replaced with .env.example; SECURITY.md documents rotation + history purge Revoke the key at aistudio.google.com/apikey and issue a new one. It is still in git history.
Real staff passwords hard-coded in src/pages/LoginPage.tsx (krishna0858 / @krishna, etc.) Removed. Demo auth now verifies nothing and grants the staff view by display name only (VITE_DEMO_ADMINS) Nothing — but treat those passwords as compromised and don't reuse them anywhere.
5 stray PDFs (4.3 MB) committed at repo root Untracked + ignored (/*.pdf); files left on disk Delete them locally if they were accidental.
Browser-visible AI key by design Added proxy mode (VITE_AI_PROXY_URL) + a deployable Cloudflare Worker in examples/ai-proxy/ (CORS allow-list, rate limiting, no key in the bundle) Deploy the proxy before production.

npm run lint went from 2 errors + 1 warning → 0 problems.


What changed

🔍 Search & discovery (src/lib/search.ts, src/lib/tags.ts, ProjectExplorer)

  • Replaced title.includes(q) with tokenised, accent-insensitive, typo-tolerant ranking across title · tags · category · licence · platform · source · description, with stopword handling and coverage-based matching so padded queries still work.
  • Faceted filters (category, licence, platform, source, min Trust Score, verified-only), 5 sort orders, load-more pagination, <mark> highlighting of why a result matched, / to focus, Esc to clear, recent-search chips, honest empty state.
  • The URL is the source of truth — /?q=privacy+browser&sort=trust&license=GPL-3.0&verified=1 is a shareable result set, and the hero search drives the same state.
  • Intent tags are derived from the dataset (vpn, notes, llm, password-manager, terminal…), so new entries are findable without hand-maintained keywords.

❤️ Favourites

  • FavoritesProvider + /favorites page, localStorage persistence with cross-tab sync, heart toggle on every card, toast feedback, "storage blocked" fallback messaging.

🤖 AI assistant (src/services/ai.ts, localAssistant.ts)

  • Dropped the deprecated @google/generative-ai SDK and the retired gemini-pro model (the chat could not have worked). Now plain fetch against Gemini REST with gemini-2.0-flash, real multi-turn history, timeouts, abort-on-unmount, safety thresholds and readable errors.
  • Three modes auto-selected: proxy → direct → local. The local engine answers from the real catalogue using the same ranking as the UI, so the assistant is never dead in a demo, in CI, or for a visitor with no key.
  • Chat history persists per conversation, renders HTML-safe markdown (no dangerouslySetInnerHTML), and the notification prompt is now opt-in instead of firing on page load.

🧭 Robustness, a11y, SEO

  • ErrorBoundary on all routes, a 404 page that suggests real projects (and echoes the failed path), route-level code splitting + vendor chunks + skeletons, ScrollToTop, dynamic document.title.
  • Skip link, semantic landmarks, visible focus rings, aria-pressed/aria-expanded, aria-live result counts, full prefers-reduced-motion support; the particle canvas now pauses on hidden tabs and caps its O(n²) work.
  • Meta/OG/Twitter/JSON-LD, custom favicon, robots.txt, sitemap.xml, and a GitHub Pages deep-link fix (public/404.html + src/lib/ghPages.ts) so /project/42 survives a refresh.

🧾 Data honesty

  • Licence explainer now covers MIT, Apache, GPL, AGPL, LGPL, MPL, BSD, CC0, Unlicense + model licences (RAIL, Llama, Gemma, Qwen), and flags proprietary entries as "Not open source" instead of showing a green tick — this caught Obsidian in the existing dataset.
  • Removed lorem ipsum and the fake activity sparkline. The detail page shows derived signals, related projects, a Trust Score ring, quick facts, a maintenance meter and a "report this listing" shortcut that pre-fills the issue template.

🧪 Tests, CI, docs, packaging

  • 100 Vitest tests: search/scoring, tags, catalogue, licence lookup, time helpers, offline assistant, jsdom smoke tests that render the real app, and dataset-integrity checks (duplicate ids/titles, non-official link hosts, download portals, out-of-range Trust Scores, unparseable dates, proprietary-but-verified).
  • .github/workflows/ci.yml (lint · typecheck · test · build on every push/PR) and deploy.yml (GitHub Pages, sets VITE_BASE_PATH for you).
  • Issue templates incl. "Bad / outdated listing", a PR template, rewritten README.md, CONTRIBUTING.md (with the Trust Score rubric), SECURITY.md, LICENSE (MIT), docs/DEPLOYMENT.md, docs/ROADMAP.md, Dockerfile + nginx.conf.
  • Build-time export of public/data/projects.json — a real, keyless static API.
  • Fixed project metadata (name: opendiscover, version, licence, repo/homepage/bugs, engines) and removed dead files (App.css, react.svg, vite.svg, unused SubmitProjectModal, old deploy docs).

Verification

npm run lint        → 0 problems
npm run typecheck   → clean (strict mode)
npm test            → Test Files 7 passed | Tests 100 passed
npm run build       → ✓ built, 42 projects exported to public/data/projects.json
                      route chunks: ChatPage 15.8 kB, ProjectDetail 12.3 kB, react 46.9 kB, motion 115.9 kB

Manually exercised: home search + filters + sort + shareable URL, category pages, project detail (licence explainer, trust ring, related, discussion), favourites round-trip, demo sign-in as krishna0858 (any password, any 6-digit OTP), AI chat in offline mode, community/forum, 404 route, mobile drawer.


Notes for the reviewer

  • No behaviour you rely on was removed. Admin/staff chat simulation still works — it is now behind an explicit "Simulate incoming" toggle and driven by VITE_DEMO_ADMINS instead of a name list baked into a component.
  • Login still accepts the same handles; only the password check is gone (it was never real security and it leaked credentials).
  • dist/, public/data/ and .env are git-ignored; the JSON API is regenerated by prebuild.
  • Full "what to build next" list lives in docs/ROADMAP.md — top item is live GitHub/Hugging Face metadata sync, since hand-typed stars go stale.

…docs

Security & repo hygiene
- Untrack `.env` (a live Gemini key was committed) and five stray PDFs; add
  `.env.example`, `SECURITY.md`, `LICENSE` (MIT) and hardened `.gitignore`.
- Remove hard-coded staff usernames/passwords from `LoginPage.tsx`. Demo auth
  now checks nothing and grants the staff view by display name only
  (`VITE_DEMO_ADMINS`), so no credential ever lives in the source again.

Search & discovery (src/lib/search.ts, src/lib/tags.ts, ProjectExplorer)
- Replace `title.includes(q)` with tokenised, accent-insensitive, typo-tolerant
  ranking over title/tags/category/licence/platform/source/description, with
  stopword handling and coverage-based matching for long queries.
- Faceted filters (category, licence, platform, source, min Trust Score,
  verified-only), five sort orders, load-more pagination, `<mark>` highlighting
  of why a result matched, `/` shortcut, recent searches, empty state.
- The URL is the source of truth: `/?q=vpn&sort=trust&license=GPL-3.0` is a
  shareable result set, and the hero search drives the same state.
- Search tags are derived from the dataset (intent keywords such as vpn, notes,
  llm, password-manager), so new entries are findable without hand-maintained
  keywords.

Favourites
- New `FavoritesProvider` + `/favorites` page, localStorage persistence with
  cross-tab sync, toast feedback, and a heart toggle on every card.

AI assistant (src/services/ai.ts)
- Drop the deprecated `@google/generative-ai` SDK and the retired `gemini-pro`
  model: plain `fetch` against Gemini REST with real multi-turn history,
  timeouts, abort on unmount, safety thresholds and readable errors.
- Proxy mode (`VITE_AI_PROXY_URL`) keeps the key server-side; a ready-to-deploy
  Cloudflare Worker with CORS + rate limiting lives in `examples/ai-proxy/`.
- Offline fallback (`localAssistant`) answers from the real catalogue when no
  key is configured, so the chat is never dead in demos or CI.
- Chat history persists per conversation, renders HTML-safe markdown, and the
  notification prompt is opt-in instead of firing on page load.

Robustness, a11y and SEO
- ErrorBoundary on all routes, 404 page that suggests real projects,
  ScrollToTop, dynamic `document.title`, route-level code splitting, vendor
  chunks, lazy-load skeletons.
- Skip link, semantic landmarks, visible focus rings, ARIA states, `aria-live`
  result counts, `prefers-reduced-motion` support; the particle canvas now
  pauses on hidden tabs and honours reduced motion.
- Meta/OG/Twitter/JSON-LD, custom favicon, robots.txt, sitemap.xml, and a
  GitHub Pages deep-link fix (`public/404.html` + `src/lib/ghPages.ts`).

Data honesty
- Licence explainer covers MIT/Apache/GPL/AGPL/LGPL/MPL/BSD/CC0/Unlicense plus
  model licences, and flags proprietary entries as "Not open source" instead of
  showing a green tick. Removed lorem ipsum and the fake activity sparkline;
  the detail page now shows derived signals, related projects, a Trust Score
  ring, quick facts and a "report this listing" shortcut.

Tooling, tests, docs
- `public/data/projects.json` generated at build time (real static API).
- 100 Vitest tests: search/scoring, tags, catalogue, licence lookup, time
  helpers, offline assistant, dataset integrity (duplicate ids, non-official
  link hosts, download portals, out-of-range scores, proprietary-but-verified)
  and jsdom smoke tests that render the real app.
- GitHub Actions CI (lint, typecheck, test, build) + Pages deploy workflow,
  issue/PR templates, rewritten README, CONTRIBUTING, docs/DEPLOYMENT,
  docs/ROADMAP, Dockerfile + nginx.conf.
- Project metadata fixed (name `opendiscover`, version, license, repo links)
  and dead files removed (App.css, react.svg, vite.svg, SubmitProjectModal).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@vercel

vercel Bot commented Oct 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
open-discover Ready Ready Preview Oct 10, 2026 8:02am UTC

@krishna3163
krishna3163 merged commit 87fff03 into main Oct 10, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — bcdba924 Deployed Oct 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant