Changelog

What shipped, and when

LiveVault was rebuilt from scratch on 29 July 2026. The previous implementation was not under version control, so this log starts at the first commit of the rebuild rather than reconstructing dates that were never recorded.

  1. Extension UI pass: a real design system instead of bare utility classes

    • Replaced emoji type glyphs (πŸ“„βœ‚οΈπŸ”—πŸ–ΌοΈπŸ“ΈπŸ“) with a single consistent line-icon set (src/shared/components/Icon.tsx) β€” emoji render differently per OS and read as a placeholder rather than a finished interface.
    • Popup: branded header with the shield mark, a hover-sweep on the primary button, icons on every action, and an animated save-confirmation panel instead of a plain paragraph.
    • Vault dashboard: sidebar items get an active-state accent bar and per-section icons; item cards show a real image thumbnail for screenshots/saved images (via a shared useBlobUrl hook) instead of only a type glyph, plus a hover lift; the detail panel slides in instead of appearing instantly; empty states get an icon instead of just text.
    • Added a small set of shared CSS utilities (brand-wash, shine, surface-interactive, nav-item) mirroring the website's design language at a fraction of the weight β€” no aurora, no scroll-driven animation, since a popup has to open instantly.
  2. Added a first-run walkthrough β€” the extension now explains itself

    • New src/onboarding entry: a welcome page that opens automatically in its own tab the moment the extension is installed (chrome.runtime.onInstalled, reason 'install' only β€” not on every update or reload). Walks through the four things it does (save a page, right-click to save a piece, screenshot/note, search the vault) plus a reminder to pin the toolbar icon, since Chrome hides new extensions in the overflow menu by default.
    • The walkthrough is never a one-time-only thing: an info button in the popup header and a "Replay the welcome guide" button in vault Settings both reopen it at any point.
    • Settings.onboardingComplete (defined in the schema from the start but unused until now) is set the moment the page is reached, whether or not a button was clicked.
  3. Homepage: real product screenshots and an FAQ, plus a real popup bug fix

    • Set up a headless Chrome instance loaded with the actual built extension (Playwright) to run a genuine functional smoke test for the first time: install-time onboarding, storage writes, vault search/filtering, item detail, favorites, and the popup's note-capture path all verified end to end in a real browser β€” not just unit tests against isolated functions.
    • That test surfaced a real bug: the popup hid its "Add a note" button entirely on restricted pages (chrome://, the Web Store) because it lived inside the same conditional as the page/screenshot buttons β€” even though notes don't touch the current tab at all. Fixed so notes are always available; only the page-dependent buttons are gated.
    • The homepage's 'See it in action' section now shows real screenshots of the vault dashboard, the item detail panel, and the popup β€” captured from that same test run, not mockups.
    • Added an FAQ section answering the questions a skeptical first-time visitor actually has: what Save does, whether it's free, why it's not on the Web Store yet, what uninstalling does to the vault, whether it works everywhere, and what happened to the old LiveVault.
  4. Prepared the Chrome Web Store submission

    • Shortened manifest.json's description to 118 characters β€” Chrome enforces a hard 132-character limit at the manifest level, and the previous 136-character string would have failed validation outright.
    • Generated real, correctly-sized (1280x800, no alpha channel) store screenshots and promo tiles from the actual running extension, plus wrote out every store-listing field (summary, detailed description, single-purpose statement, per-permission justifications, privacy-practices answers) in apps/extension/store-assets/SUBMISSION.md, so the listing states exactly what the code does β€” no more, no less.
  5. Approved on the Chrome Web Store β€” every install CTA now points there

    • LiveVault is live at chromewebstore.google.com/detail/livevault/dkmhibiigghnlochphgbijajhhlcinkf. Every "Download for Chrome" button on the site (header, homepage hero, homepage early-access band, /about) now links directly to that listing instead of to /install, and reads "Add to Chrome" to match.
    • /install was rewritten: the Chrome Web Store is now the primary path, with the direct-download zip kept as a clearly secondary option for Chromium browsers without Web Store access or anyone who wants to inspect the source first β€” its old "not on the Chrome Web Store yet" framing was no longer true and would have been actively misleading to leave up.
    • The homepage's early-access copy and one FAQ answer were updated the same way: "not yet on the Chrome Web Store" became "just went live," since the underlying fact changed, not just the wording.
  6. New product: LiveVault Capture, a local-only browser extension

    • Added apps/extension: a Manifest V3 Chrome extension that saves pages, selections, links, images, screenshots, and notes to a private vault. No account, no server β€” data is written to chrome.storage.local and IndexedDB only, and the only permissions requested are activeTab, scripting, contextMenus, storage, and unlimitedStorage. No host_permissions, no <all_urls>.
    • The extension's icon set is generated from the same root linkvault_logo.png master the website's shield uses, via apps/extension/scripts/build-icons.mjs (same crop logic as apps/web/scripts/build-logo-assets.mjs), so the two can't visually drift apart.
    • This site now leads with the extension: the homepage, nav, and /security were rewritten around it, reusing the existing 3D/motion components (VaultCube, Aurora, TiltCard, ScrollCue) with new content rather than replacing them.
    • /privacy and /terms now describe the extension's actual (much simpler, local-only) data handling. The previous product's own accurate policies were not deleted β€” they moved to /legacy-privacy and /legacy-terms, linked from the new /privacy, since that product still runs on real infrastructure and still needs a real policy.
    • Added /install: a straightforward direct-download page with load-unpacked instructions, since the extension isn't on the Chrome Web Store yet and the site shouldn't pretend otherwise with a non-functional "Add to Chrome" button.
    • /demo and /pricing (the secure-link product) were removed from navigation and the sitemap but not from the codebase β€” they still work, they're just no longer what this site promotes.
  7. Fixed the logo being invisible sitewide, corrected stale facts

    • Next's built-in /_next/image optimizer was returning HTTP 400 on every request in production, so the shield logo never rendered anywhere it's used β€” header, footer, /about, and the homepage vault cube. next.config.ts now serves the two shipped PNGs unoptimized; both are already pre-sized by scripts/build-logo-assets.mjs, so nothing was lost.
    • Corrected an impossible date (29 Feb2025 β€” 2025 was not a leap year) that had been introduced into the founder story, this changelog, and the privacy/terms last-updated dates. The git history is unambiguous: this codebase's first commit is 29 July 2026.
    • Corrected every reference to the frontend host from Vercel to Netlify (site.ts's infrastructure list, /about, /privacy, the README) β€” the site has been served by Netlify since the domain cutover, and a page that claims to state only verifiable facts should not misname its own host.
    • The footer had its own paraphrase of the screenshot-capture disclosure, which had drifted from the canonical wording in captureDisclosure (site.ts) β€” the one sentence this codebase is explicit about never letting drift. The footer now renders that constant directly, same as /security, /demo, and the homepage.
    • Pricing consistency: the homepage badge said "Free during beta" while /pricing committed to a specific end date ("till 2027"); the homepage now states the same date. The struck-through offer badge on /pricing was also hardcoded text instead of the OFFER_NOTE constant already defined for it.
    • Assorted cleanup surfaced by an audit pass: dead imports on /pricing and /security, a duplicated "Founder and core developer" line repeated twice in one homepage section, three action cards on /about promoted straight to h2 with no section heading above them, and "view budget" vs. "view limit" used interchangeably for the same thing on /privacy.
  8. Renamed to LiveVault

    • The product is now called LiveVault. The name was changed everywhere in one pass: page copy, metadata, package names, the API service name, and the JWT issuer and audience claims.
    • The old wordmark could not come with it. The master logo artwork has the previous name baked into it as pixels, so the raster lockup was dropped and the wordmark is now set in type instead β€” same navy-and-blue colour split as the artwork, sharp at any size, and selectable text. The shield itself contains no text and was kept unchanged.
    • Token claims were rewritten while nothing is live. This invalidates any previously issued admin or stream token, which is the right time to do it: after launch the same change would sign everyone out.
  9. Contact form, and a demo that explains its own failures

    • The contact page now has a form: pick a topic, write the message, and it opens in your own email client fully composed. It deliberately does not post to a server β€” there is no mail-sending backend, and a form that accepts a message it cannot deliver is worse than no form. A copy-to-clipboard fallback covers browsers with no mail client registered.
    • The demo now names the actual reason it cannot start. A missing API address, an out-of-date API with no demo route, a database that is down, and a server that never answered used to look identical; each now gets its own explanation plus the raw technical line.
    • Fixed a real deployment trap: with no API address configured at build time, the site quietly fell back to calling localhost, which fails as mixed content on an HTTPS page and reported itself as a connection problem. It now says plainly that the address was never configured.
    • Network errors name the host that was tried, which separates a wrong address from a sleeping server from a CORS rejection.
  10. 3D vault fixed, and another pass of polish

    • Fixed the 3D vault: its resting tilt was being silently discarded, because a CSS animation on a transform replaces the whole property and the tilt shared an element with the spin. The top face was never visible. The two are now on separate layers.
    • The vault also sits properly on desktop now β€” nudged left of centre and lifted above the card rather than hanging off the right edge.
    • Added a scroll position indicator across the top of the page, driven by CSS scroll-linked animation with no scroll listener and nothing to hydrate.
    • Card hover shadows are tinted with the brand blue instead of grey. On a near-white page a grey shadow reads as dirt; a blue one reads as light.
    • Added a trace of film grain behind the hero sections, because wide areas of near-white look flat on a good display.
    • The about page is properly responsive at every width, and now shows the contact address rather than only linking away to it.
  11. Light theme, official logo, and a 3D motion system

    • The whole site moved from a dark theme to a light one, rebuilt on the brand palette: #0053FF for actions and links, #1A7CF1 for hover states, #62EAFF as a decorative accent, and #2C4267 for body text. Cyan is used for decoration only β€” it sits at roughly 1.4:1 on white, so it never carries text.
    • The official LiveVault logo replaced the placeholder inline SVG. Three optimised assets are generated from the master artwork by a build script: a 512px transparent shield, a trimmed 960px lockup, and a 64px favicon. The 2.2 MB source file is not shipped to the browser.
    • The tagline on the site is now the one on the logo itself β€” Secure. Tokenized. Temporary.
    • New motion system: scroll-linked section reveals, pointer-tracked 3D tilt cards with a specular sheen, a CSS-only rotating vault cube, drifting aurora fields, and masked dot grids.
    • All of it degrades safely. The reveal animations are wrapped in a feature query, so browsers without scroll-driven animation support get the content plainly visible rather than blank, and everything is disabled under prefers-reduced-motion.
    • Open Graph cards redrawn in the brand palette instead of the old dark card.
  12. Pricing in rupees and a named founder

    • Pricing is quoted in INR: Free at β‚Ή0, Pro at β‚Ή999 a month, Team at β‚Ή2,999 a month. Pro and Team are labelled as planned, because neither is purchasable yet.
    • The about page names the founder, Saifullah Faizan, and states plainly that LiveVault is solo-built, pre-launch, and unfunded.
    • Contact lists support@livevault.live for support and owner@livevault.live for direct purchase questions. There is no phone number β€” a form that silently fails is worse than no form.
  13. Marketing site, public demo, viewer, and admin panel

    • New server-rendered Next.js frontend. Every public page returns real HTML on first load, replacing the previous single-page app that served an empty shell.
    • Public demo at /demo: upload an image, get a tokenized link, watch it expire after one view or fifteen minutes. No account needed.
    • Secure viewer at /v/<token> with sequential reveal, per-asset countdown, and session lock states.
    • Admin panel at /admin: upload media, create links with view limits and deadlines, monitor link status, destroy links early, and approve pending admin accounts.
    • Per-page meta descriptions, Open Graph and Twitter card tags, robots.txt, and sitemap.xml.
  14. Media storage moved off the container filesystem

    • Uploads now go to a private Cloudflare R2 bucket over the S3 API. The previous build wrote to local disk on Render, where the filesystem is ephemeral β€” every deploy or restart silently destroyed the media while the link records survived, so links looked valid and then failed.
    • Media is streamed through the API behind a short-lived, session-bound ticket rather than a shareable presigned URL. HTTP range requests pass through so video seeking works.
    • A cleanup worker deletes objects from storage before dropping the link record, and retries rather than orphaning bytes if a delete fails.
  15. Real time-based link expiry

    • Links now carry an absolute expiresAt deadline, enforced on every read path independently of the view counter. The previous schema had no deadline at all: an active link that was never opened stayed viewable indefinitely.
    • Separate purgeAt field controls when the underlying media is deleted, so expiry and deletion are no longer conflated.
    • Opening a link on a phone is refused and recorded instead of expiring the link. This removed the replacement-link mechanism the old build needed to undo its own penalty.
  16. Security hardening in the rebuilt API

    • Configuration is validated at boot and the server refuses to start on a missing, too-short, or placeholder secret. The previous build defaulted its JWT and stream-token secrets to change-me, so a misconfigured deploy came up healthy while signing forgeable tokens.
    • CORS is an exact-origin allowlist. The previous check accepted any bare public IPv4 address because its LAN-address pattern had no private-range restriction.
    • Rate limiting added across authentication, token validation, viewer traffic, and demo uploads. There was previously none.
    • Demo uploads are restricted to images by inspecting magic bytes rather than trusting the client's declared content type.
    • Share tokens carry 256 bits of entropy and are stored only as SHA-256 digests.