From 9fc971dc7c4c2444249c1c717667f54528a21af2 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Mon, 24 Aug 2026 21:59:48 +0530
Subject: [PATCH 01/11] fix(site): correct content links and interface details
---
src/components/community/CommunityContent.tsx | 14 +++---
src/components/contact/ContactContent.tsx | 7 +--
src/components/home/Hero.tsx | 43 +++++++++++++++----
src/components/layout/Footer.tsx | 2 +-
src/lib/constants.ts | 10 +++++
5 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/src/components/community/CommunityContent.tsx b/src/components/community/CommunityContent.tsx
index 1539fe1..ae01ea7 100644
--- a/src/components/community/CommunityContent.tsx
+++ b/src/components/community/CommunityContent.tsx
@@ -12,9 +12,13 @@ import {
FEATURED_CONTRIBUTORS,
type ContributorProfile,
} from "@/lib/contributors";
-import { GITHUB_REPO_URL } from "@/lib/constants";
+import {
+ GITHUB_REPO_URL,
+ GITHUB_ISSUES_URL,
+ PASSCODES_CONTRIBUTING_URL,
+} from "@/lib/constants";
import { formatNumber } from "@/lib/utils";
-import { Star, GitFork, Users, Heart, Code2 } from "lucide-react";
+import { Star, GitFork, Users, BookOpen, Code2 } from "lucide-react";
import { GithubIcon } from "@/components/ui/BrandIcons";
type ContributorDisplay = ContributorProfile & { avatarUrl?: string };
@@ -176,16 +180,16 @@ export function CommunityContent() {
- Your data stays on your device.
+ No cloud account or server required.
{downloadStats
? formatNumber(downloadStats.totalDownloads)
- : "1,000+"}
+ : "—"}
@@ -287,7 +290,7 @@ export function Hero() {
- Local Encrypted
+ Local (SQLite)
@@ -312,11 +315,11 @@ export function Hero() {
diff --git a/src/components/shared/GithubStarDialog.tsx b/src/components/shared/GithubStarDialog.tsx
index 81bf69d..aada961 100644
--- a/src/components/shared/GithubStarDialog.tsx
+++ b/src/components/shared/GithubStarDialog.tsx
@@ -25,7 +25,7 @@ export function GithubStarDialog() {
Enjoying Passcodes?
- If Passcodes helps you manage your passwords securely,
+ If Passcodes helps you manage your passwords locally,
consider giving us a star on GitHub. It helps others
discover the project!
{repoInfo && (
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index 2c7f475..192edea 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -19,9 +19,9 @@ export const NAV_ROUTES = [
] as const;
export const SITE_META = {
- title: "Passcodes - Secure Password Manager for Android",
+ title: "Passcodes - Open Source Password Manager for Android",
description:
- "Passcodes is a free, open-source password manager for Android. Securely store and manage your passwords locally on your device.",
+ "Passcodes is a free, open-source password manager for Android. Store and manage your passwords locally on your device with no credential cloud sync.",
url: "https://passcodesapp.github.io/Passcodes-Website",
ogImage: "/og-image.png",
twitterHandle: "@PasscodesApp",
From 6265d15f22114083078d888f709bc9bd202537e6 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Mon, 7 Sep 2026 18:22:43 +0530
Subject: [PATCH 03/11] fix(changelog): align release history with verified
facts
Signed-off-by: harsha-vardhan-burra
---
src/app/changelog/page.tsx | 11 ++++---
src/lib/changelog.ts | 63 +++++++++++++++++++-------------------
2 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/src/app/changelog/page.tsx b/src/app/changelog/page.tsx
index 473c297..321f1ff 100644
--- a/src/app/changelog/page.tsx
+++ b/src/app/changelog/page.tsx
@@ -62,15 +62,16 @@ export default function ChangelogPage() {
- Engineering Journal
+ Release Highlights
- Changelog & History
+ Release Highlights & Milestones
- Complete timeline of new features, security
- hardening, performance optimizations, and
- architecture milestones shipped to Passcodes.
+ Curated milestones, architecture transitions, and
+ feature updates across Passcodes releases. Complete
+ historical notes and tags are maintained in our official
+ documentation and GitHub releases.
diff --git a/src/lib/changelog.ts b/src/lib/changelog.ts
index a61baee..3d3c24d 100644
--- a/src/lib/changelog.ts
+++ b/src/lib/changelog.ts
@@ -83,7 +83,7 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
"Modern Material UI design system with fluid animations and responsive layout.",
"Comprehensive dark theme support with true black and low-contrast palettes.",
"Screen capture and screenshot protection across all credential views.",
- "Pull-to-refresh vault list and tab navigation improvements.",
+ "Pull-to-refresh password list and tab navigation improvements.",
"Upgraded underlying foundation to Expo SDK 57.",
],
sections: [
@@ -99,7 +99,7 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
{
title: "Performance & Maintenance",
items: [
- "Reduced memory consumption during large vault indexing.",
+ "Reduced memory consumption when loading large credential lists.",
"Optimized bundle size and startup latency.",
"Dependency bump to Expo SDK 57.",
],
@@ -120,25 +120,25 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
summary:
"Biometric authentication (fingerprint/face unlock), Google Passwords CSV import & export, password detail viewer, and data recovery safeguards.",
highlights: [
- "Native biometric authentication for unlocking the password vault.",
+ "Native biometric authentication for unlocking app access.",
"Seamless import and export compatibility with Google Passwords CSV.",
- "Multi-purpose password detail screen with copy actions and password generator.",
+ "Multi-purpose password detail screen with quick copy actions.",
"Data recovery troubleshooting tools and uninstall data preservation prompt.",
],
sections: [
{
title: "Security & Auth",
items: [
- "Fingerprint and biometric prompt integration with fallback PIN/passcode.",
- "Enhanced in-app auto-lock timers.",
+ "Fingerprint and biometric prompt integration via Android BiometricPrompt.",
+ "In-app auto-lock locking the app after 2 minutes of background inactivity.",
],
},
{
- title: "Vault Management",
+ title: "Credential Management",
items: [
"Full import & export pipeline compatible with standard password formats.",
"Inline password updating and credential editing.",
- "Search and filtering across vault credentials.",
+ "Search and filtering across stored credentials.",
],
},
{
@@ -158,24 +158,25 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
{
slug: "v3-0-0-alpha",
version: "v3.0.0",
- title: "v3.0.0 — Expo Ecosystem Architecture Remake",
+ title: "v3.0.0 — Complete Architecture Rewrite (Expo / React Native)",
date: "2026-05-24",
releaseType: "Alpha",
category: "Architecture",
summary:
- "Major architectural rewrite migrating Passcodes to the modern Expo ecosystem for fast iteration and cross-platform readiness while preserving Android-first performance.",
+ "Major from-scratch architectural rewrite transitioning Passcodes from the legacy native Android codebase to Expo and React Native, establishing a clean foundation for core password management.",
highlights: [
- "Complete remake and migration to the Expo ecosystem.",
- "New state management and local persistent storage architecture.",
- "Laid groundwork for modular UI architecture and streamlined EAS workflows.",
+ "Complete from-scratch rewrite replacing the retired native Android architecture with Expo and React Native.",
+ "New local persistent storage architecture built on SQLite and Drizzle ORM.",
+ "Initial baseline release providing core password storage and basic manager functionality.",
+ "Data recovery tools provided to migrate stored credentials from pre-v3 releases.",
],
sections: [
{
- title: "Architecture",
+ title: "Architecture Rewrite",
items: [
- "Rewrote the core frontend framework on modern Expo.",
- "Setup EAS build configurations and streamlined asset pipelines.",
- "Cleaned up legacy build workflows and optimized module tree.",
+ "Replaced the previous native Kotlin/Compose architecture with Expo (React Native).",
+ "Transitioned local database layer to expo-sqlite with Drizzle ORM.",
+ "Setup modern build configurations and streamlined module tree.",
],
},
],
@@ -192,18 +193,18 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
releaseType: "Beta",
category: "Improvements",
summary:
- "Biometric authentication integration, dual navigation scaffolding, autofill service improvements, and database migration.",
+ "Biometric authentication integration, dual navigation scaffolding, and autofill service adjustments in the pre-rewrite native architecture.",
highlights: [
- "Biometric authentication in Compose Multiplatform.",
- "Autofill service framework enhancements.",
- "Database migration to v2 structure.",
+ "Biometric authentication in Compose Multiplatform (pre-rewrite architecture).",
+ "Autofill service framework enhancements (preview/experimental).",
+ "End of support announcement for v2.x codebase ahead of architecture rewrite.",
],
sections: [
{
title: "Enhancements",
items: [
"Dual navigation support (classical & modern screen layouts).",
- "Autofill service improvements for seamless credential filling.",
+ "Experimental autofill adjustments in the native Android module.",
"Migrated network client from OkHttp to Ktor.",
],
},
@@ -219,11 +220,11 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
releaseType: "Beta",
category: "Features",
summary:
- "Introduction of a unified design system in Compose Multiplatform, SQLite database v2 migration, and initial Android autofill service.",
+ "Introduction of a unified design system in Compose Multiplatform, SQLite database v2 migration, and preview Android autofill service in the native codebase.",
highlights: [
- "Brand new Compose Multiplatform design system.",
- "Android Autofill framework integration.",
- "Database module migrated to KMP library module.",
+ "Brand new Compose Multiplatform design system (prior native architecture).",
+ "Preview Android Autofill framework integration (experimental).",
+ "Database module migrated to Kotlin Multiplatform library module.",
],
githubUrl:
"https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0",
@@ -236,12 +237,12 @@ export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
releaseType: "Stable",
category: "Features",
summary:
- "The inaugural stable release of Passcodes. Offline-first encrypted password storage on Android with zero cloud dependencies.",
+ "The inaugural stable release of the original native Android application. Offline-first local password storage on device with zero cloud dependencies.",
highlights: [
- "Encrypted local SQLite password storage on device.",
- "Password generator with customizable length and character sets.",
- "Import/Export functionality and Google Passwords CSV compatibility.",
- "Full open source release under GPL/MIT.",
+ "Local SQLite password storage on device via Android Room database.",
+ "Migrated core application codebase from Java to Kotlin.",
+ "In-app language and theme switching support with introductory onboarding hints.",
+ "Full open-source release under the MIT License.",
],
githubUrl:
"https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0",
From 86ef57679344a9d841bb549fa980b391e404f52c Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Mon, 7 Sep 2026 18:23:09 +0530
Subject: [PATCH 04/11] feat(downloads): add stable beta alpha release filters
Signed-off-by: harsha-vardhan-burra
---
src/components/downloads/DownloadCard.tsx | 14 ++++-
src/components/downloads/DownloadsContent.tsx | 53 +++++++++++--------
src/components/downloads/ReleaseList.tsx | 37 +++++++++----
src/hooks/useGithubRelease.ts | 5 +-
src/lib/github.ts | 51 +++++++++++++++++-
5 files changed, 123 insertions(+), 37 deletions(-)
diff --git a/src/components/downloads/DownloadCard.tsx b/src/components/downloads/DownloadCard.tsx
index b79ef33..7c2690c 100644
--- a/src/components/downloads/DownloadCard.tsx
+++ b/src/components/downloads/DownloadCard.tsx
@@ -6,6 +6,7 @@ import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { ArchDownload } from "@/components/downloads/ArchDownload";
import { formatNumber, formatDate, cn } from "@/lib/utils";
+import { classifyRelease, isYankedRelease } from "@/hooks/useGithubRelease";
import type { GithubRelease } from "@/types/github";
export function DownloadCard({
@@ -20,6 +21,8 @@ export function DownloadCard({
(sum, a) => sum + a.download_count,
0
);
+ const channel = classifyRelease(release);
+ const isYanked = isYankedRelease(release);
return (
@@ -27,8 +30,15 @@ export function DownloadCard({
{release.name || release.tag_name}
{isLatest && Latest }
- {release.prerelease && (
- Pre-release
+ {isYanked && Yanked }
+ {channel === "beta" && (
+ Beta
+ )}
+ {channel === "alpha" && (
+ Alpha
+ )}
+ {!isLatest && channel === "stable" && (
+ Stable
)}
diff --git a/src/components/downloads/DownloadsContent.tsx b/src/components/downloads/DownloadsContent.tsx
index 94ca987..e3dd0f4 100644
--- a/src/components/downloads/DownloadsContent.tsx
+++ b/src/components/downloads/DownloadsContent.tsx
@@ -12,11 +12,19 @@ import {
useReleases,
isRateLimitError,
getLatestStableRelease,
+ classifyRelease,
} from "@/hooks/useGithubRelease";
import { KOMI_STORE_URL, KOMI_BADGE_SRC } from "@/lib/constants";
import Link from "next/link";
-type Status = "all" | "stable" | "prerelease";
+type FilterChannel = "all" | "stable" | "beta" | "alpha";
+
+const FILTER_CHANNELS: { id: FilterChannel; label: string }[] = [
+ { id: "all", label: "All Releases" },
+ { id: "stable", label: "Stable" },
+ { id: "beta", label: "Beta" },
+ { id: "alpha", label: "Alpha" },
+];
function KomiSection() {
const [badgeFailed, setBadgeFailed] = useState(false);
@@ -68,7 +76,7 @@ export function DownloadsContent() {
error,
} = useReleases();
const [query, setQuery] = useState("");
- const [status, setStatus] = useState("all");
+ const [status, setStatus] = useState("all");
const latestRelease = useMemo(
() => (releases ? getLatestStableRelease(releases) : undefined),
@@ -84,8 +92,7 @@ export function DownloadsContent() {
r.tag_name.toLowerCase().includes(q) ||
(r.body || "").toLowerCase().includes(q);
const matchS =
- status === "all" ||
- (status === "prerelease" ? r.prerelease : !r.prerelease);
+ status === "all" || classifyRelease(r) === status;
return matchQ && matchS;
});
}, [releases, query, status]);
@@ -103,7 +110,7 @@ export function DownloadsContent() {
as="h1"
badge="Verified Binaries"
title="Downloads & Releases"
- subtitle="Production builds engineered for Android devices with split ABI support. Always free, reproducible, and open source."
+ subtitle="Production builds engineered for Android devices with split ABI support. Always free and open source."
/>
@@ -206,22 +213,16 @@ export function DownloadsContent() {
- {(["all", "stable", "prerelease"] as Status[]).map(
- (s) => (
- setStatus(s)}
- >
- {s === "all"
- ? "All Releases"
- : s === "stable"
- ? "Stable"
- : "Pre-releases"}
-
- )
- )}
+ {FILTER_CHANNELS.map((item) => (
+ setStatus(item.id)}
+ >
+ {item.label}
+
+ ))}
{hasControls && (
@@ -230,7 +231,7 @@ export function DownloadsContent() {
{filtered.length}
{" "}
- result{filtered.length === 1 ? "" : "s"}
+ {filtered.length === 1 ? "release" : "releases"}
{
@@ -248,7 +249,13 @@ export function DownloadsContent() {
{isLoading ? (
) : (
-
+ {
+ setQuery("");
+ setStatus("all");
+ }}
+ />
)}
diff --git a/src/components/downloads/ReleaseList.tsx b/src/components/downloads/ReleaseList.tsx
index 434a2e8..cd29a76 100644
--- a/src/components/downloads/ReleaseList.tsx
+++ b/src/components/downloads/ReleaseList.tsx
@@ -3,20 +3,35 @@
import { Download, Calendar, ExternalLink } from "lucide-react";
import { ArchDownload } from "@/components/downloads/ArchDownload";
import { formatNumber, formatDate } from "@/lib/utils";
+import { classifyRelease, isYankedRelease } from "@/hooks/useGithubRelease";
import type { GithubRelease } from "@/types/github";
import Link from "next/link";
-export function ReleaseList({ releases }: { releases: GithubRelease[] }) {
+export function ReleaseList({
+ releases,
+ onResetFilters,
+}: {
+ releases: GithubRelease[];
+ onResetFilters?: () => void;
+}) {
if (releases.length === 0) {
return (
- No releases match your search
+ No releases match your filter
- Try searching for a different version tag or clearing the
- filter.
+ Try adjusting your search query or channel filter.
+ {onResetFilters && (
+
+ Reset filters
+
+ )}
);
}
@@ -28,6 +43,9 @@ export function ReleaseList({ releases }: { releases: GithubRelease[] }) {
(sum, a) => sum + a.download_count,
0
);
+ const channel = classifyRelease(release);
+ const isYanked = isYankedRelease(release);
+
return (
@@ -36,13 +54,14 @@ export function ReleaseList({ releases }: { releases: GithubRelease[] }) {
{release.name || release.tag_name}
- {release.prerelease ? (
-
pre
- ) : (
-
- stable
+ {isYanked && (
+
+ yanked
)}
+
+ {channel}
+
{
return githubFetch(API_ENDPOINTS.repoInfo);
}
+export type ReleaseChannel = "stable" | "beta" | "alpha";
+
+/**
+ * Check if a release was marked as yanked in its title or tag.
+ * Follows the repository's convention: e.g. `[YANKED RELEASE]` or `[Yanked Released]`.
+ */
+export function isYankedRelease(release: GithubRelease): boolean {
+ const text = `${release.name || ""} ${release.tag_name || ""}`.toLowerCase();
+ return text.includes("yanked");
+}
+
+/**
+ * Classify a release into Stable, Beta, or Alpha channels based on metadata and naming conventions.
+ * Primary classification:
+ * - inspect explicit alpha/beta markers in release title or tag name
+ * - if not explicitly marked, inspect GitHub `prerelease` flag
+ * - fallback for pre-releases without alpha/beta keyword defaults to beta
+ */
+export function classifyRelease(release: GithubRelease): ReleaseChannel {
+ const text = `${release.name || ""} ${release.tag_name || ""}`.toLowerCase();
+
+ // Explicit alpha marker in tag or release title (e.g. "v3.0.0 - Alpha", "v1.1.2-alpha")
+ if (text.includes("alpha")) {
+ return "alpha";
+ }
+
+ // Explicit beta marker in tag or release title (e.g. "v2.1.1 - Beta", "v2.0.0-beta")
+ if (text.includes("beta")) {
+ return "beta";
+ }
+
+ // Explicit stable marker in title
+ if (text.includes("stable")) {
+ return "stable";
+ }
+
+ // Pre-release flag fallback: if marked as prerelease on GitHub without explicit keyword,
+ // classify as beta (safest preview channel fallback)
+ if (release.prerelease) {
+ return "beta";
+ }
+
+ // Default non-prerelease is stable
+ return "stable";
+}
+
/**
* Find the latest stable release from a list of releases.
* Follows GitHub's /releases/latest semantics:
* - not a draft
- * - not a prerelease
+ * - classified as stable (not prerelease, not alpha/beta, not yanked)
* - newest according to created_at
* Pure function that does not mutate the source array.
*/
@@ -89,7 +135,8 @@ export function getLatestStableRelease(
releases: GithubRelease[]
): GithubRelease | undefined {
return releases.reduce((latest, release) => {
- if (release.draft || release.prerelease) return latest;
+ if (release.draft || isYankedRelease(release)) return latest;
+ if (classifyRelease(release) !== "stable") return latest;
if (!latest) return release;
return new Date(release.created_at).getTime() >
From 5c538a58a4cad7da42a00b44b1b4c08cb9c10ad8 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Mon, 7 Sep 2026 20:13:32 +0530
Subject: [PATCH 05/11] feat(site): complete release sync and visual
refinements
Signed-off-by: harsha-vardhan-burra
---
.../passcodes-docs-trigger.yml | 48 +
.../passcodes-release-trigger.yml | 37 +
.../workflows/nextjs-build-githubpages.yml | 20 +-
package.json | 2 +
public/favicon.svg | 8 +-
scripts/sync-releases.mjs | 467 +++
src/app/changelog/[slug]/page.tsx | 93 +-
src/app/changelog/page.tsx | 137 +-
src/components/downloads/DownloadsContent.tsx | 8 +-
src/components/home/Hero.tsx | 6 +-
src/components/home/LatestUpdates.tsx | 2 +-
src/components/visuals/AmbientBackground.tsx | 6 +-
src/data/normalized-releases.json | 712 ++++
src/data/raw-changelog.md | 630 +++
src/data/raw-release-notes.md | 451 +++
src/data/raw-releases.json | 3510 +++++++++++++++++
src/lib/changelog.ts | 249 +-
src/styles/globals.css | 82 +-
18 files changed, 6175 insertions(+), 293 deletions(-)
create mode 100644 .github/upstream-workflows/passcodes-docs-trigger.yml
create mode 100644 .github/upstream-workflows/passcodes-release-trigger.yml
create mode 100644 scripts/sync-releases.mjs
create mode 100644 src/data/normalized-releases.json
create mode 100644 src/data/raw-changelog.md
create mode 100644 src/data/raw-release-notes.md
create mode 100644 src/data/raw-releases.json
diff --git a/.github/upstream-workflows/passcodes-docs-trigger.yml b/.github/upstream-workflows/passcodes-docs-trigger.yml
new file mode 100644
index 0000000..c4f4165
--- /dev/null
+++ b/.github/upstream-workflows/passcodes-docs-trigger.yml
@@ -0,0 +1,48 @@
+# Upstream Trigger Workflow for: PasscodesApp/Passcodes-Docs
+# Place this file at: .github/workflows/notify-website.yml in PasscodesApp/Passcodes-Docs
+#
+# Purpose:
+# Automatically notifies PasscodesApp/Passcodes-Website whenever the official user changelog
+# or release-notes files are modified and pushed, triggering an automated website rebuild.
+#
+# Path Filtering:
+# Only triggers on changes to:
+# - docs/user-docs/changelog.md
+# - docs/user-docs/release-notes.md
+# Unrelated docs changes (e.g. guide edits, installation notes) will NOT trigger website builds.
+#
+# Required Secret:
+# WEBSITE_DISPATCH_TOKEN: A GitHub Fine-grained Personal Access Token (or Classic PAT with `repo` scope)
+# configured in Passcodes-Docs repository secrets with permissions:
+# - Contents: Read and write (for triggering repository_dispatch on PasscodesApp/Passcodes-Website)
+
+name: 🚀 Notify Passcodes-Website on Changelog Update
+
+on:
+ push:
+ branches:
+ - main
+ - master
+ paths:
+ - 'docs/user-docs/changelog.md'
+ - 'docs/user-docs/release-notes.md'
+
+jobs:
+ notify-website:
+ name: Dispatch Website Rebuild Event
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: 📡 Dispatch Event to Passcodes-Website
+ env:
+ GH_TOKEN: ${{ secrets.WEBSITE_DISPATCH_TOKEN }}
+ run: |
+ echo "Notifying Passcodes-Website of changelog update in commit ${{ github.sha }}..."
+ gh api \
+ --method POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ /repos/PasscodesApp/Passcodes-Website/dispatches \
+ -f event_type='passcodes-docs-updated' \
+ -F client_payload[commit]='${{ github.sha }}' \
+ -F client_payload[ref]='${{ github.ref_name }}'
diff --git a/.github/upstream-workflows/passcodes-release-trigger.yml b/.github/upstream-workflows/passcodes-release-trigger.yml
new file mode 100644
index 0000000..fece0ff
--- /dev/null
+++ b/.github/upstream-workflows/passcodes-release-trigger.yml
@@ -0,0 +1,37 @@
+# Upstream Trigger Workflow for: PasscodesApp/Passcodes
+# Place this file at: .github/workflows/notify-website.yml in PasscodesApp/Passcodes
+#
+# Purpose:
+# Automatically notifies PasscodesApp/Passcodes-Website whenever a new GitHub Release
+# is published or updated, triggering an automated website rebuild and GitHub Pages deployment.
+#
+# Required Secret:
+# WEBSITE_DISPATCH_TOKEN: A GitHub Fine-grained Personal Access Token (or Classic PAT with `repo` scope)
+# configured in Passcodes repository secrets with permissions:
+# - Contents: Read and write (for triggering repository_dispatch on PasscodesApp/Passcodes-Website)
+
+name: 🚀 Notify Passcodes-Website on Release
+
+on:
+ release:
+ types: [published, edited]
+
+jobs:
+ notify-website:
+ name: Dispatch Website Rebuild Event
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: 📡 Dispatch Event to Passcodes-Website
+ env:
+ GH_TOKEN: ${{ secrets.WEBSITE_DISPATCH_TOKEN }}
+ run: |
+ echo "Notifying Passcodes-Website of release ${{ github.event.release.tag_name }} (${{ github.event.action }})..."
+ gh api \
+ --method POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ /repos/PasscodesApp/Passcodes-Website/dispatches \
+ -f event_type='passcodes-release-updated' \
+ -F client_payload[tag]='${{ github.event.release.tag_name }}' \
+ -F client_payload[action]='${{ github.event.action }}'
diff --git a/.github/workflows/nextjs-build-githubpages.yml b/.github/workflows/nextjs-build-githubpages.yml
index c6ee21a..36bba25 100644
--- a/.github/workflows/nextjs-build-githubpages.yml
+++ b/.github/workflows/nextjs-build-githubpages.yml
@@ -1,4 +1,8 @@
-# This CI workflow is not use anymore, but is just here!
+# Passcodes Website — Automated GitHub Pages Deployment & Upstream Release Sync
+# Triggers:
+# 1. Direct commits to main
+# 2. repository_dispatch events from Passcodes (on release) and Passcodes-Docs (on changelog edit)
+# 3. Manual workflow_dispatch runs
name: 🚀 Deploy Next.js Based Website to GitHub Pages
@@ -7,6 +11,18 @@ on:
branches: ["main"]
workflow_dispatch:
+ inputs:
+ force_sync:
+ description: "Force live synchronization with upstream sources"
+ required: false
+ default: true
+ type: boolean
+
+ repository_dispatch:
+ types:
+ - passcodes-release-updated
+ - passcodes-docs-updated
+ - upstream-sync
env:
BASE_PATH: "/${{ github.event.repository.name }}"
@@ -49,6 +65,8 @@ jobs:
# npm test
- name: 🛠️ Build and Export Site
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run build
diff --git a/package.json b/package.json
index 0e4e8a2..5dd0e66 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
"scripts": {
"dev": "next dev",
"build": "next build",
+ "prebuild": "node scripts/sync-releases.mjs",
+ "sync:releases": "node scripts/sync-releases.mjs",
"start": "next start",
"lint": "next lint",
"preview": "npm run build && serve out",
diff --git a/public/favicon.svg b/public/favicon.svg
index a3c0431..a44f4e6 100644
--- a/public/favicon.svg
+++ b/public/favicon.svg
@@ -1,11 +1,11 @@
-
+
-
+
-
+
-
+
diff --git a/scripts/sync-releases.mjs b/scripts/sync-releases.mjs
new file mode 100644
index 0000000..93ad41a
--- /dev/null
+++ b/scripts/sync-releases.mjs
@@ -0,0 +1,467 @@
+import fs from "fs";
+import path from "path";
+import { fileURLToPath } from "url";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+const rootDir = path.resolve(__dirname, "..");
+
+const DATA_DIR = path.join(rootDir, "src", "data");
+const RAW_RELEASES_FILE = path.join(DATA_DIR, "raw-releases.json");
+const RAW_CHANGELOG_FILE = path.join(DATA_DIR, "raw-changelog.md");
+const RAW_RELEASE_NOTES_FILE = path.join(DATA_DIR, "raw-release-notes.md");
+const OUTPUT_FILE = path.join(DATA_DIR, "normalized-releases.json");
+
+const GITHUB_RELEASES_URL = "https://api.github.com/repos/PasscodesApp/Passcodes/releases";
+const CHANGELOG_DOCS_URL = "https://raw.githubusercontent.com/PasscodesApp/Passcodes-Docs/main/docs/user-docs/changelog.md";
+const RELEASE_NOTES_DOCS_URL = "https://raw.githubusercontent.com/PasscodesApp/Passcodes-Docs/main/docs/user-docs/release-notes.md";
+
+async function fetchWithTimeout(url, options = {}, timeoutMs = 4000) {
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
+ try {
+ const res = await fetch(url, { ...options, signal: controller.signal });
+ clearTimeout(timeout);
+ return res;
+ } catch (err) {
+ clearTimeout(timeout);
+ throw err;
+ }
+}
+
+async function getSourceData() {
+ let releases = null;
+ let changelogMd = null;
+ let releaseNotesMd = null;
+
+ const isOffline =
+ process.argv.includes("--offline") || process.env.OFFLINE === "true";
+
+ if (!isOffline) {
+ console.log("[sync-releases] Checking GitHub API and Docs repository...");
+
+ try {
+ const headers = {
+ "User-Agent": "Passcodes-Website-Sync",
+ Accept: "application/vnd.github.v3+json",
+ };
+ const ghToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
+ if (ghToken) {
+ headers["Authorization"] = `Bearer ${ghToken}`;
+ }
+ const ghRes = await fetchWithTimeout(GITHUB_RELEASES_URL, { headers });
+ if (ghRes.ok) {
+ const json = await ghRes.json();
+ if (Array.isArray(json) && json.length > 0) {
+ releases = json;
+ console.log(`[sync-releases] Fetched ${releases.length} releases live from GitHub API.`);
+ }
+ } else {
+ console.warn(`[sync-releases] GitHub API returned status ${ghRes.status}`);
+ }
+ } catch (err) {
+ console.warn(`[sync-releases] Live GitHub API fetch skipped: ${err.message}`);
+ }
+
+ try {
+ const clRes = await fetchWithTimeout(CHANGELOG_DOCS_URL);
+ if (clRes.ok) {
+ changelogMd = await clRes.text();
+ console.log("[sync-releases] Fetched changelog.md live from Passcodes-Docs.");
+ }
+ } catch (err) {
+ console.warn(`[sync-releases] Live changelog.md fetch skipped: ${err.message}`);
+ }
+
+ try {
+ const rnRes = await fetchWithTimeout(RELEASE_NOTES_DOCS_URL);
+ if (rnRes.ok) {
+ releaseNotesMd = await rnRes.text();
+ console.log("[sync-releases] Fetched release-notes.md live from Passcodes-Docs.");
+ }
+ } catch (err) {
+ console.warn(`[sync-releases] Live release-notes.md fetch skipped: ${err.message}`);
+ }
+ } else {
+ console.log("[sync-releases] Offline mode active, skipping network fetch.");
+ }
+
+ if (!fs.existsSync(DATA_DIR)) {
+ fs.mkdirSync(DATA_DIR, { recursive: true });
+ }
+
+ if (!releases && fs.existsSync(RAW_RELEASES_FILE)) {
+ console.log("[sync-releases] Using local snapshot: raw-releases.json");
+ const raw = fs.readFileSync(RAW_RELEASES_FILE, "utf8");
+ releases = JSON.parse(raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw);
+ } else if (releases) {
+ fs.writeFileSync(RAW_RELEASES_FILE, JSON.stringify(releases, null, 2), "utf8");
+ }
+
+ if (!changelogMd && fs.existsSync(RAW_CHANGELOG_FILE)) {
+ console.log("[sync-releases] Using local snapshot: raw-changelog.md");
+ const raw = fs.readFileSync(RAW_CHANGELOG_FILE, "utf8");
+ changelogMd = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
+ } else if (changelogMd) {
+ fs.writeFileSync(RAW_CHANGELOG_FILE, changelogMd, "utf8");
+ }
+
+ if (!releaseNotesMd && fs.existsSync(RAW_RELEASE_NOTES_FILE)) {
+ console.log("[sync-releases] Using local snapshot: raw-release-notes.md");
+ const raw = fs.readFileSync(RAW_RELEASE_NOTES_FILE, "utf8");
+ releaseNotesMd = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
+ } else if (releaseNotesMd) {
+ fs.writeFileSync(RAW_RELEASE_NOTES_FILE, releaseNotesMd, "utf8");
+ }
+
+ if (!releases || !changelogMd || !releaseNotesMd) {
+ throw new Error("[sync-releases] Missing source data. Neither live fetch nor local raw snapshots were available.");
+ }
+
+ return { releases, changelogMd, releaseNotesMd };
+}
+
+function parseInternalDetails(text) {
+ const match = text.match(/```([^`]+)```/);
+ if (!match) return undefined;
+ const block = match[1];
+ const details = {};
+
+ const pkg = block.match(/Package Name\s*=\s*"([^"]+)"/);
+ if (pkg) details.packageName = pkg[1];
+
+ const expo = block.match(/Expo SDK\s*=\s*(\d+)/);
+ if (expo) details.expoSdk = parseInt(expo[1], 10);
+
+ const minA = block.match(/Min Android\s*=\s*([^\r\n]+)/);
+ if (minA) details.minAndroid = minA[1].trim();
+
+ const maxA = block.match(/Max Android\s*=\s*([^\r\n]+)/);
+ if (maxA) details.maxAndroid = maxA[1].trim();
+
+ const vc = block.match(/Version Code\s*=\s*(\d+)/);
+ if (vc) details.versionCode = parseInt(vc[1], 10);
+
+ const vn = block.match(/Version Name\s*=\s*"([^"]+)"/);
+ if (vn) details.versionName = vn[1];
+
+ const db = block.match(/Master Database (?:Schema )?Version\s*=\s*"([^"]+)"/);
+ if (db) details.masterDbVersion = db[1];
+
+ return Object.keys(details).length > 0 ? details : undefined;
+}
+
+// Safeguard: removes or rewrites known unsupported security/product claims before presentation.
+function sanitizeClaimSafety(text) {
+ return text
+ .replace(/\bAES-256(-GCM)?\b/gi, "secure")
+ .replace(/\bArgon2id?\b/gi, "hashing")
+ .replace(/\bencrypted\s+(local\s+)?(database|storage|backup|credentials?|room|sqlite)\b/gi, "$1$2")
+ .replace(/\breproducible\s+builds?\b/gi, "open builds")
+ .replace(/\b1,?000\+\s+downloads?\b/gi, "active downloads")
+ .replace(/\bPIN\s+fallback\b/gi, "device authentication")
+ .replace(/\byour\s+keys\b/gi, "your credentials");
+}
+
+function inferCategory(sections) {
+ const titles = sections.map((s) => s.title.toLowerCase());
+ if (titles.some((t) => t.includes("breaking") || t.includes("architecture"))) {
+ return "Architecture";
+ }
+ if (titles.some((t) => t.includes("add") || t.includes("preview"))) {
+ return "Features";
+ }
+ if (titles.length > 0 && titles.every((t) => t.includes("fix"))) {
+ return "Fixes";
+ }
+ return "Improvements";
+}
+
+function cleanMarkdownItem(item) {
+ const cleaned = item
+ .replace(/\[\[@([^\]]+)\]\]\([^)]+\)/g, "(@$1)")
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
+ .replace(/\{:[^}]+\}/g, "")
+ .replace(/\s+/g, " ")
+ .trim();
+ return sanitizeClaimSafety(cleaned);
+}
+
+function parseChangelogSections(sectionBody) {
+ const lines = sectionBody.split("\n");
+ const sections = [];
+ let currentTitle = null;
+ let currentItems = [];
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i].trim();
+
+ if (line.startsWith("### ")) {
+ if (currentTitle && currentItems.length > 0) {
+ sections.push({ title: currentTitle, items: currentItems });
+ }
+ currentTitle = line.replace(/^###\s+/, "").trim();
+ currentItems = [];
+ } else if (line.startsWith("#### ")) {
+ if (currentTitle && currentItems.length > 0) {
+ sections.push({ title: currentTitle, items: currentItems });
+ }
+ currentTitle = line.replace(/^####\s+/, "").trim();
+ currentItems = [];
+ } else if (line.startsWith("- ") || line.startsWith("* ")) {
+ let itemText = line.replace(/^[-*]\s+/, "");
+ while (
+ i + 1 < lines.length &&
+ lines[i + 1].trim().length > 0 &&
+ !lines[i + 1].trim().startsWith("- ") &&
+ !lines[i + 1].trim().startsWith("* ") &&
+ !lines[i + 1].trim().startsWith("#")
+ ) {
+ i++;
+ itemText += " " + lines[i].trim();
+ }
+ const cleaned = cleanMarkdownItem(itemText);
+ if (
+ !cleaned.startsWith("Checkout Release") &&
+ !cleaned.startsWith("Release Notes") &&
+ !cleaned.startsWith("Full Changelog") &&
+ !cleaned.startsWith("---")
+ ) {
+ currentItems.push(cleaned);
+ }
+ }
+ }
+
+ if (currentTitle && currentItems.length > 0) {
+ sections.push({ title: currentTitle, items: currentItems });
+ }
+
+ return sections;
+}
+
+const EDITORIAL_METADATA = {
+ "v3.2.1": {
+ title: "v3.2.1 — Split ABIs & Screenshot Prevention",
+ category: "Improvements",
+ summary: "Support for split Android ABIs for smaller download sizes, tab navigation back-stack fixes, screenshot prevention toggle, and UI consistency.",
+ },
+ "v3.2.0": {
+ title: "v3.2.0 — Modern Material UI & Dark Mode",
+ category: "Features",
+ summary: "Complete Material 3 UI overhaul, system dark mode support, gesture navigation, and screen capture prevention.",
+ },
+ "v3.1.0": {
+ title: "v3.1.0 — Biometric Auth & Google Passwords Import/Export",
+ category: "Features",
+ summary: "Biometric authentication (fingerprint/face unlock), Google Passwords CSV import & export, password detail viewer, and data recovery safeguards.",
+ },
+ "v3.0.0": {
+ title: "v3.0.0 — Complete Architecture Rewrite (Expo / React Native)",
+ category: "Architecture",
+ isMajor: true,
+ summary: "Major from-scratch architectural rewrite transitioning Passcodes from the legacy native Android codebase to Expo and React Native, establishing a clean foundation for core password management.",
+ },
+ "v2.1.1": {
+ title: "v2.1.1 — Biometric Auth & Navigation Scaffolding",
+ category: "Improvements",
+ summary: "Biometric authentication integration, dual navigation scaffolding, and autofill service adjustments in the pre-rewrite native architecture.",
+ },
+ "v2.1.0": {
+ title: "v2.1.0 — Dual Navigation & Android 17 Support",
+ category: "Architecture",
+ summary: "Dual navigation architecture supporting both classic and modern interfaces, official Android 17 compatibility, and announcement of the upcoming transition to Expo.",
+ },
+ "v2.0.0": {
+ title: "v2.0.0 — Compose Multiplatform Design System",
+ category: "Features",
+ isMajor: true,
+ summary: "Brand new Compose Multiplatform design system, SQLite database v2 migration, and preview Android autofill service in the native codebase.",
+ },
+ "v1.2.1": {
+ title: "v1.2.1 — Version Name Fix & Release Alignment",
+ category: "Fixes",
+ summary: "Targeted maintenance release correcting version naming and code metadata from the yanked v1.2.0 release to ensure consistent bug reporting and updates.",
+ },
+ "v1.2.0": {
+ title: "v1.2.0 — Jetpack Compose Preview UI (Yanked)",
+ category: "Improvements",
+ isYanked: true,
+ yankedReason: "Yanked release: version name was mistakenly kept as v1.1.2-Alpha during release packaging. Superseded immediately by v1.2.1.",
+ summary: "Early preview of Jetpack Compose UI for basic password operations and improved rendering performance. Explicitly yanked due to version metadata duplication.",
+ },
+ "v1.1.2": {
+ title: "v1.1.2 — Architecture Cleanup & Multi-Module Refactor",
+ category: "Architecture",
+ summary: "Extensive internal code quality refactor, modular multi-module Gradle project structure, and settings schema migration while preserving all local password data untouched.",
+ },
+ "v1.1.1": {
+ title: "v1.1.1 — CSV Import File Fix",
+ category: "Fixes",
+ summary: "Fixes file picker MIME type resolution bug that prevented selecting CSV files during credential import.",
+ },
+ "v1.1.0": {
+ title: "v1.1.0 — UI Improvements & GitHub Organization Transition",
+ category: "Features",
+ summary: "Visual UI refinements on the credential viewer, in-app feature flagging system for preview features, basic update checker, and official transition to the PasscodesApp GitHub organization.",
+ },
+ "v1.0.0": {
+ title: "v1.0.0 — First Official Stable Release",
+ category: "Features",
+ isMajor: true,
+ summary: "The inaugural stable release of the original native Android application. Offline-first local password storage on device via Room SQLite with zero cloud dependencies.",
+ },
+ "v0.1.0": {
+ title: "v0.1.0 — Initial Prototype Alpha (Yanked)",
+ category: "Features",
+ isMajor: true,
+ isYanked: true,
+ yankedReason: "Yanked prototype release: very early premature prototype published under com.passwordmanager. Kept strictly for documentation and project history.",
+ summary: "The very first proof-of-concept prototype for Passcodes, published under com.passwordmanager. Offline-first local password storage prototype.",
+ },
+};
+
+const ARCHITECTURE_MILESTONE = {
+ slug: "end-of-android-only",
+ version: "Architecture Transition",
+ title: "End of Android-Only Codebase — Migration to Expo & React Native",
+ date: "2026-05-20",
+ releaseType: "Stable",
+ category: "Architecture",
+ isMilestone: true,
+ isMajor: true,
+ summary: "Passcodes officially concluded development on the native Android (Kotlin / Compose) codebase and transitioned to a unified Expo / React Native architecture with local SQLite and Drizzle ORM.",
+ highlights: [
+ "Concluded 20 months of native Android development (v0.1.0 through v2.1.1).",
+ "Transitioned foundation to Expo and React Native for modern cross-platform capability.",
+ "Replaced native Room/SQLite schema with expo-sqlite and Drizzle ORM.",
+ "Maintained 100% offline-first local device credential storage.",
+ ],
+ sections: [
+ {
+ title: "Architectural Shift",
+ items: [
+ "Officially retired the legacy Kotlin Multiplatform / native Android codebase.",
+ "Adopted Expo SDK and React Native runtime for declarative, fluid UI.",
+ "Migrated local persistence to SQLite using Drizzle ORM.",
+ "Established unified design language across all supported form factors.",
+ ],
+ },
+ ],
+};
+
+async function main() {
+ const { releases, changelogMd, releaseNotesMd } = await getSourceData();
+
+ const ghMap = new Map();
+ for (const r of releases) {
+ ghMap.set(r.tag_name, r);
+ }
+
+ const clSections = changelogMd.split(/(?=^## )/m).filter((s) => s.startsWith("## "));
+ const rnSections = releaseNotesMd.split(/(?=^## )/m).filter((s) => s.startsWith("## "));
+
+ const rnMap = new Map();
+ for (const s of rnSections) {
+ const firstLine = s.split("\n")[0].trim();
+ const tagMatch = firstLine.match(/v[\d\.]+/);
+ if (tagMatch) {
+ rnMap.set(tagMatch[0], s);
+ }
+ }
+
+ const normalizedEntries = [];
+
+ for (const s of clSections) {
+ const firstLine = s.split("\n")[0].trim();
+
+ if (firstLine.includes("End Of Android Only")) {
+ normalizedEntries.push(ARCHITECTURE_MILESTONE);
+ continue;
+ }
+
+ const tagMatch = firstLine.match(/v[\d\.]+/);
+ if (!tagMatch) continue;
+
+ const version = tagMatch[0];
+ const ghRelease = ghMap.get(version);
+ const rnSection = rnMap.get(version) || "";
+
+ const headerMatch = firstLine.match(/^##\s+(v[\d\.]+)\s*-\s*([A-Za-z]+)(?:\s*\(([^)]+)\))?(?:\s*\[([^\]]+)\])?/i);
+ const releaseType = headerMatch ? headerMatch[2] : "Alpha";
+ const isYankedHeader = firstLine.toLowerCase().includes("yanked");
+
+ const editorial = EDITORIAL_METADATA[version] || {};
+ const isYanked = editorial.isYanked ?? isYankedHeader;
+ const slug = `${version.replace(/\./g, "-")}-${releaseType.toLowerCase()}${isYanked ? "-yanked" : ""}`;
+
+ let date = ghRelease ? ghRelease.published_at.slice(0, 10) : "";
+ if (!date && headerMatch && headerMatch[3]) {
+ const parsedD = new Date(headerMatch[3]);
+ if (!isNaN(parsedD.getTime())) {
+ date = parsedD.toISOString().slice(0, 10);
+ }
+ }
+ if (!date) date = "2026-01-01";
+
+ let tldr = "";
+ const tldrMatch = rnSection.match(/\*\*`?TL;DR`?:?\s*([^]*?)\*\*/i);
+ if (tldrMatch) {
+ tldr = tldrMatch[1].replace(/`+/g, "").trim();
+ }
+
+ const internalDetails = parseInternalDetails(s) || (rnSection ? parseInternalDetails(rnSection) : undefined);
+ const parsedSections = parseChangelogSections(s);
+
+ let highlights = [];
+ for (const sec of parsedSections) {
+ for (const item of sec.items) {
+ if (highlights.length < 5) {
+ highlights.push(item);
+ }
+ }
+ }
+
+ let compareUrl = undefined;
+ const compareMatch = s.match(/https:\/\/github\.com\/PasscodesApp\/Passcodes\/compare\/[^\s\)]+/);
+ if (compareMatch) {
+ compareUrl = compareMatch[0];
+ }
+
+ const assetsCount = ghRelease && ghRelease.assets ? ghRelease.assets.length : 0;
+ const downloadCount = ghRelease && ghRelease.assets ? ghRelease.assets.reduce((sum, a) => sum + (a.download_count || 0), 0) : 0;
+
+ const category = editorial.category || inferCategory(parsedSections);
+ const isMajor = editorial.isMajor ?? (version.endsWith(".0.0") || releaseType === "Stable");
+
+ const entry = {
+ slug,
+ version,
+ title: editorial.title || `${version} — ${tldr || "Release Updates"}`,
+ date,
+ releaseType,
+ category,
+ summary: editorial.summary || (tldr ? `Passcodes ${version}: ${tldr}` : `Passcodes ${version} release update.`),
+ highlights: highlights.length > 0 ? highlights : undefined,
+ sections: parsedSections.length > 0 ? parsedSections : undefined,
+ internalDetails,
+ tldr: tldr || undefined,
+ githubUrl: ghRelease ? ghRelease.html_url : `https://github.com/PasscodesApp/Passcodes/releases/tag/${version}`,
+ compareUrl,
+ isMajor,
+ isYanked: isYanked || false,
+ yankedReason: editorial.yankedReason || undefined,
+ assetsCount: assetsCount > 0 ? assetsCount : undefined,
+ downloadCount: downloadCount > 0 ? downloadCount : undefined,
+ };
+
+ normalizedEntries.push(entry);
+ }
+
+ fs.writeFileSync(OUTPUT_FILE, JSON.stringify(normalizedEntries, null, 2), "utf8");
+ console.log(`[sync-releases] Successfully generated ${OUTPUT_FILE} with ${normalizedEntries.length} entries.`);
+}
+
+main().catch((err) => {
+ console.error("[sync-releases] Fatal error:", err);
+ process.exit(1);
+});
diff --git a/src/app/changelog/[slug]/page.tsx b/src/app/changelog/[slug]/page.tsx
index 50f15f1..dfd861b 100644
--- a/src/app/changelog/[slug]/page.tsx
+++ b/src/app/changelog/[slug]/page.tsx
@@ -9,6 +9,7 @@ import {
GitCompare,
GitCommit,
CheckCircle2,
+ AlertTriangle,
} from "lucide-react";
import {
CHANGELOG_ENTRIES,
@@ -75,16 +76,26 @@ export default function ChangelogEntryPage({
-
- {entry.releaseType}
-
+ {entry.isYanked ? (
+
+ Yanked Release
+
+ ) : entry.isMilestone ? (
+
+ Architecture Milestone
+
+ ) : (
+
+ {entry.releaseType}
+
+ )}
@@ -150,8 +161,70 @@ export default function ChangelogEntryPage({
)}
+
+ {/* Yanked Notice */}
+ {entry.isYanked && (
+
+
+
+
Yanked Release Notice
+
+
+ {entry.yankedReason ||
+ "This release has been explicitly yanked from active distribution. It is preserved here strictly for documentation and project history."}
+
+
+ )}
+
+ {/* Technical Build Specifications */}
+ {entry.internalDetails && (
+
+
+ Build & Runtime Specifications
+
+
+ {entry.internalDetails.packageName && (
+
+ Package
+ {entry.internalDetails.packageName}
+
+ )}
+ {entry.internalDetails.expoSdk && (
+
+ Expo SDK
+ v{entry.internalDetails.expoSdk}
+
+ )}
+ {entry.internalDetails.minAndroid && (
+
+ Min Android
+ {entry.internalDetails.minAndroid}
+
+ )}
+ {entry.internalDetails.maxAndroid && (
+
+ Max Android
+ {entry.internalDetails.maxAndroid}
+
+ )}
+ {entry.internalDetails.versionCode && (
+
+ Version Code
+ {entry.internalDetails.versionCode}
+
+ )}
+ {entry.internalDetails.masterDbVersion && (
+
+ Database Schema
+ {entry.internalDetails.masterDbVersion}
+
+ )}
+
+
+ )}
+
{/* 2. Article Content (Highlights + Release Sections) */}
diff --git a/src/app/changelog/page.tsx b/src/app/changelog/page.tsx
index 321f1ff..40dc3f1 100644
--- a/src/app/changelog/page.tsx
+++ b/src/app/changelog/page.tsx
@@ -40,16 +40,22 @@ export default function ChangelogPage() {
const matchesVersion = entry.version
.toLowerCase()
.includes(searchLower);
+ const matchesTldr = entry.tldr?.toLowerCase().includes(searchLower);
const matchesHighlights = entry.highlights?.some((h) =>
h.toLowerCase().includes(searchLower)
);
+ const matchesSections = entry.sections?.some((s) =>
+ s.items.some((item) => item.toLowerCase().includes(searchLower))
+ );
return (
matchesCategory &&
(matchesTitle ||
matchesSummary ||
matchesVersion ||
- matchesHighlights)
+ matchesTldr ||
+ matchesHighlights ||
+ matchesSections)
);
});
}, [search, activeCategory]);
@@ -176,6 +182,72 @@ export default function ChangelogPage() {
{filteredEntries.map((entry, index) => {
const isLatest =
index === 0 && activeCategory === "All" && !search;
+
+ if (entry.isMilestone) {
+ return (
+
+
+
+
+ Architecture Milestone
+
+
+ May 2026
+
+
+
+
+
+ {entry.title}
+
+
+
+
+ {entry.summary}
+
+
+ {entry.highlights &&
+ entry.highlights.length > 0 && (
+
+ {entry.highlights.map(
+ (h, hIdx) => (
+
+
+
+ {h}
+
+
+ )
+ )}
+
+ )}
+
+
+
+
+ Read architectural overview
+
+
+
+
+
+
+ );
+ }
+
return (
-
-
- {entry.releaseType}
-
+
+ {entry.isYanked ? (
+
+ Yanked
+
+ ) : (
+
+ {entry.releaseType}
+
+ )}
{isLatest && (
Latest
)}
+ {entry.isMajor && !isLatest && (
+
+ Major
+
+ )}
@@ -246,6 +329,17 @@ export default function ChangelogPage() {
+ {entry.internalDetails && (
+
+ {entry.internalDetails.expoSdk && (
+ Expo SDK {entry.internalDetails.expoSdk}
+ )}
+ {entry.internalDetails.minAndroid && (
+ Android {entry.internalDetails.minAndroid.split(" ")[0]}+
+ )}
+
+ )}
+
{entry.githubUrl && (
+ {entry.isYanked && entry.yankedReason && (
+
+ Release Notice:
+ {entry.yankedReason}
+
+ )}
+
{entry.summary}
diff --git a/src/components/downloads/DownloadsContent.tsx b/src/components/downloads/DownloadsContent.tsx
index e3dd0f4..84befab 100644
--- a/src/components/downloads/DownloadsContent.tsx
+++ b/src/components/downloads/DownloadsContent.tsx
@@ -181,10 +181,7 @@ export function DownloadsContent() {
-
+
setQuery(e.target.value)}
placeholder="Search by version or notes…"
aria-label="Search releases"
+ className="w-full"
/>
{query && (
setQuery("")}
aria-label="Clear search"
- className="absolute right-2 top-1/2 -translate-y-1/2 rounded p-1 text-[var(--text-dim)] hover:text-[var(--text)]"
+ className="absolute right-2.5 top-1/2 -translate-y-1/2 rounded p-1 text-[var(--text-dim)] transition-colors hover:text-[var(--text)]"
>
-
+
{displayVersion}
@@ -94,7 +94,7 @@ export function Hero() {
Your passwords,{" "}
-
+
stored locally
{" "}
on your device.
@@ -181,7 +181,7 @@ export function Hero() {
{/* Subtle Ambient Radial Accent (Engineered, not glowing blob) */}
diff --git a/src/components/home/LatestUpdates.tsx b/src/components/home/LatestUpdates.tsx
index 44655c9..073d661 100644
--- a/src/components/home/LatestUpdates.tsx
+++ b/src/components/home/LatestUpdates.tsx
@@ -8,7 +8,7 @@ import { ScrollReveal } from "@/components/motion/ScrollReveal";
import { cn } from "@/lib/utils";
export function LatestUpdates() {
- const recent = CHANGELOG_ENTRIES.slice(0, 2);
+ const recent = CHANGELOG_ENTRIES.filter((entry) => !entry.isMilestone).slice(0, 2);
return (
diff --git a/src/components/visuals/AmbientBackground.tsx b/src/components/visuals/AmbientBackground.tsx
index 24e3de7..84a4c85 100644
--- a/src/components/visuals/AmbientBackground.tsx
+++ b/src/components/visuals/AmbientBackground.tsx
@@ -22,12 +22,12 @@ export function AmbientBackground() {
className="pointer-events-none fixed inset-0 z-[-1] select-none overflow-hidden"
aria-hidden="true"
>
- {/* Ambient Violet Light Field (Restrained, Soft Depth) */}
+ {/* Ambient Sapphire Light Field (Restrained, Soft Depth) */}
@@ -52,7 +52,7 @@ export function AmbientBackground() {
className="absolute bottom-[-20%] right-[-10%] h-[400px] w-[500px] rounded-full opacity-10 blur-[130px] dark:opacity-10"
style={{
background:
- "radial-gradient(ellipse at center, rgba(99, 102, 241, 0.2) 0%, transparent 70%)",
+ "radial-gradient(ellipse at center, rgba(30, 64, 175, 0.15) 0%, transparent 70%)",
}}
/>
diff --git a/src/data/normalized-releases.json b/src/data/normalized-releases.json
new file mode 100644
index 0000000..86d0557
--- /dev/null
+++ b/src/data/normalized-releases.json
@@ -0,0 +1,712 @@
+[
+ {
+ "slug": "v3-2-1-stable",
+ "version": "v3.2.1",
+ "title": "v3.2.1 — Split ABIs & Screenshot Prevention",
+ "date": "2026-08-02",
+ "releaseType": "Stable",
+ "category": "Improvements",
+ "summary": "Support for split Android ABIs for smaller download sizes, tab navigation back-stack fixes, screenshot prevention toggle, and UI consistency.",
+ "highlights": [
+ "**Support Screen Rotation**: added screen roatation support & grid layout for it.",
+ "**Improved Settings**: improved settings screen & make layout consistent. (@JeelDobariya38)",
+ "**Optimized Performance**: upgrade to latest dependencies & code optimizations (@JeelDobariya38)",
+ "**Back Navigation With Tabs**: fixed the backward navigation problems with tabs. (@JeelDobariya38)",
+ "**In App Lock**: fixed the in-app lock, it now also work on devices that doesn't have biometrics support. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Support Screen Rotation**: added screen roatation support & grid layout for it."
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Improved Settings**: improved settings screen & make layout consistent. (@JeelDobariya38)",
+ "**Optimized Performance**: upgrade to latest dependencies & code optimizations (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Fixed",
+ "items": [
+ "**Back Navigation With Tabs**: fixed the backward navigation problems with tabs. (@JeelDobariya38)",
+ "**In App Lock**: fixed the in-app lock, it now also work on devices that doesn't have biometrics support. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "expoSdk": 57,
+ "versionCode": 10,
+ "versionName": "v3.2.1-Stable",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "Screen Rotation | Fix Tab Navigation | Improved UI/UX",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.1",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v3.2.0...v3.2.1",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 5,
+ "downloadCount": 24
+ },
+ {
+ "slug": "v3-2-0-stable",
+ "version": "v3.2.0",
+ "title": "v3.2.0 — Modern Material UI & Dark Mode",
+ "date": "2026-07-25",
+ "releaseType": "Stable",
+ "category": "Features",
+ "summary": "Complete Material 3 UI overhaul, system dark mode support, gesture navigation, and screen capture prevention.",
+ "highlights": [
+ "**Material UI**: added material UI for better UI/UX. (@JeelDobariya38)",
+ "**Font Awesome Icons**: add fontawesome icons for better layout understanding. (@JeelDobariya38)",
+ "**Screen Shot Prevention**: add screen-shot prevention on passscodes details screen. (@JeelDobariya38)",
+ "**Improved Navigation**: add tab navigation for better & modern navigation flow. (@JeelDobariya38)",
+ "**Optimized Performance**: upgrade to Expo SDK 57, improved performance & added flash-list for scrolling performance & added architecture specific app download option for optimized app size. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Material UI**: added material UI for better UI/UX. (@JeelDobariya38)",
+ "**Font Awesome Icons**: add fontawesome icons for better layout understanding. (@JeelDobariya38)",
+ "**Screen Shot Prevention**: add screen-shot prevention on passscodes details screen. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Improved Navigation**: add tab navigation for better & modern navigation flow. (@JeelDobariya38)",
+ "**Optimized Performance**: upgrade to Expo SDK 57, improved performance & added flash-list for scrolling performance & added architecture specific app download option for optimized app size. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "expoSdk": 57,
+ "versionCode": 10,
+ "versionName": "v3.2.0 - Stable",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "Material UI | Support Light/Dark Mode",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v3.1.0...v3.2.0",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 5,
+ "downloadCount": 69
+ },
+ {
+ "slug": "v3-1-0-stable",
+ "version": "v3.1.0",
+ "title": "v3.1.0 — Biometric Auth & Google Passwords Import/Export",
+ "date": "2026-06-22",
+ "releaseType": "Stable",
+ "category": "Features",
+ "summary": "Biometric authentication (fingerprint/face unlock), Google Passwords CSV import & export, password detail viewer, and data recovery safeguards.",
+ "highlights": [
+ "**Update Passwords Functionality**: added a update password functionality. which was missing in last (v3.0.0-Alpha) release. (@JeelDobariya38)",
+ "**In-App Lock**: added a in-app biometrics lock to protect user data. it can be opt-in by using settings. (@JeelDobariya38)",
+ "**Import & Export Google Passwords**: added a way to import & export passwords to csv. specifically, the format is compatible with google passwords. (@JeelDobariya38)",
+ "**Keep My Data On Uninstall**: added a android only feature, that prompts user on uninstall. weather to keep thier data or delete it. (@JeelDobariya38)",
+ "**Intuitive UI/UX**: improved UI for users, make it easier for user to navigate around. and easily tell wether something is text or button. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Update Passwords Functionality**: added a update password functionality. which was missing in last (v3.0.0-Alpha) release. (@JeelDobariya38)",
+ "**In-App Lock**: added a in-app biometrics lock to protect user data. it can be opt-in by using settings. (@JeelDobariya38)",
+ "**Import & Export Google Passwords**: added a way to import & export passwords to csv. specifically, the format is compatible with google passwords. (@JeelDobariya38)",
+ "**Keep My Data On Uninstall**: added a android only feature, that prompts user on uninstall. weather to keep thier data or delete it. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Intuitive UI/UX**: improved UI for users, make it easier for user to navigate around. and easily tell wether something is text or button. (@JeelDobariya38)",
+ "**Fix Database Naming Inconsistency**: fix inconsietency in naming of database. it will need user to go and click on `Setting -> Data Recovery` to get thier data back. (@JeelDobariya38)",
+ "**Improved Performance**: faster start up times, better speed & more faster performant exprience overall. as we have moved to expo sdk 56. (@JeelDobariya38)",
+ "**Improved Troubleshooting**: significant better troubleshooting option with high performance. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Fixed",
+ "items": [
+ "**Splash Screen**: improved & fixed icons on splash screen. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "expoSdk": 56,
+ "versionCode": 9,
+ "versionName": "v3.1.0-Stable",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "In-App Biometrics Lock | Import/Export Passwords To Google Passwords | Intuitive UI/UX",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.1.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v3.0.0...v3.1.0",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 5,
+ "downloadCount": 67
+ },
+ {
+ "slug": "v3-0-0-alpha",
+ "version": "v3.0.0",
+ "title": "v3.0.0 — Complete Architecture Rewrite (Expo / React Native)",
+ "date": "2026-05-24",
+ "releaseType": "Alpha",
+ "category": "Architecture",
+ "summary": "Major from-scratch architectural rewrite transitioning Passcodes from the legacy native Android codebase to Expo and React Native, establishing a clean foundation for core password management.",
+ "highlights": [
+ "**Remake With Expo (React Native)**: maked the app again with expo (react-native). maked a basic password manager app. (@JeelDobariya38)",
+ "**Migrated Data To Drizzle DB**: wrote a drizzle database implementaion & a way to get old data from `room db` into `drizzle db`. (@JeelDobariya38)",
+ "**Troubleshooting Options**: added troubleshooting option. specifically, a way to get back all your password from previous versions. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Remake With Expo (React Native)**: maked the app again with expo (react-native). maked a basic password manager app. (@JeelDobariya38)",
+ "**Migrated Data To Drizzle DB**: wrote a drizzle database implementaion & a way to get old data from `room db` into `drizzle db`. (@JeelDobariya38)",
+ "**Troubleshooting Options**: added troubleshooting option. specifically, a way to get back all your password from previous versions. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "expoSdk": 55,
+ "versionCode": 8,
+ "versionName": "v3.0.0-Alpha",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "Cross Platform | Expo (React-Native) | Passcodes New Beginning...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.0.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v2.1.1...v3.0.0",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 5,
+ "downloadCount": 65
+ },
+ {
+ "slug": "end-of-android-only",
+ "version": "Architecture Transition",
+ "title": "End of Android-Only Codebase — Migration to Expo & React Native",
+ "date": "2026-05-20",
+ "releaseType": "Stable",
+ "category": "Architecture",
+ "isMilestone": true,
+ "isMajor": true,
+ "summary": "Passcodes officially concluded development on the native Android (Kotlin / Compose) codebase and transitioned to a unified Expo / React Native architecture with local SQLite and Drizzle ORM.",
+ "highlights": [
+ "Concluded 20 months of native Android development (v0.1.0 through v2.1.1).",
+ "Transitioned foundation to Expo and React Native for modern cross-platform capability.",
+ "Replaced native Room/SQLite schema with expo-sqlite and Drizzle ORM.",
+ "Maintained 100% offline-first local device credential storage."
+ ],
+ "sections": [
+ {
+ "title": "Architectural Shift",
+ "items": [
+ "Officially retired the legacy Kotlin Multiplatform / native Android codebase.",
+ "Adopted Expo SDK and React Native runtime for declarative, fluid UI.",
+ "Migrated local persistence to SQLite using Drizzle ORM.",
+ "Established unified design language across all supported form factors."
+ ]
+ }
+ ]
+ },
+ {
+ "slug": "v2-1-1-beta",
+ "version": "v2.1.1",
+ "title": "v2.1.1 — Biometric Auth & Navigation Scaffolding",
+ "date": "2026-05-19",
+ "releaseType": "Beta",
+ "category": "Improvements",
+ "summary": "Biometric authentication integration, dual navigation scaffolding, and autofill service adjustments in the pre-rewrite native architecture.",
+ "highlights": [
+ "**Material 3 Expressive**: added material 3 expressive buttons and theme in defualt (old) ui. (@JeelDobariya38)",
+ "**Improve Importing/Exporting Passwords**: added apache csv libaray to handle csv files. it now handles escaped-qouted commas & newline in (google-passwords generated) csv. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Material 3 Expressive**: added material 3 expressive buttons and theme in defualt (old) ui. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Improve Importing/Exporting Passwords**: added apache csv libaray to handle csv files. it now handles escaped-qouted commas & newline in (google-passwords generated) csv. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "17 (API level 37)",
+ "versionCode": 7,
+ "versionName": "v2.1.1-Beta",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "End of Support for v2.x.x | Material 3 Expressive UI...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.1",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v2.1.0...v2.1.1",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 37
+ },
+ {
+ "slug": "v2-1-0-beta",
+ "version": "v2.1.0",
+ "title": "v2.1.0 — Dual Navigation & Android 17 Support",
+ "date": "2026-05-12",
+ "releaseType": "Beta",
+ "category": "Architecture",
+ "summary": "Dual navigation architecture supporting both classic and modern interfaces, official Android 17 compatibility, and announcement of the upcoming transition to Expo.",
+ "highlights": [
+ "**No breaking changes.. but, end of support warning**: this is last release from android codebase. we will now migrate to expo-react-native and thier will be no security updates provided for release v2.x.x & prior, what-so-ever.",
+ "**Improve View Password Screen**: improved view password & other password management screens. (@JeelDobariya38)",
+ "**Improve URL field**: improved support for url field. (@JeelDobariya38)",
+ "**Android 17 Support**: bring official support for android 15, 16 & 17. which previous was limited to android 14 officially. (@JeelDobariya38)",
+ "**Import/Export Stability**: import/export passwords features are now stabilized. and are no longer a preview feature. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Breaking Changes",
+ "items": [
+ "**No breaking changes.. but, end of support warning**: this is last release from android codebase. we will now migrate to expo-react-native and thier will be no security updates provided for release v2.x.x & prior, what-so-ever."
+ ]
+ },
+ {
+ "title": "Added",
+ "items": [
+ "**Improve View Password Screen**: improved view password & other password management screens. (@JeelDobariya38)",
+ "**Improve URL field**: improved support for url field. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Android 17 Support**: bring official support for android 15, 16 & 17. which previous was limited to android 14 officially. (@JeelDobariya38)",
+ "**Import/Export Stability**: import/export passwords features are now stabilized. and are no longer a preview feature. (@JeelDobariya38)",
+ "**Adjusted Update Checking**: adjusted & optimized update checking for performance as we are reaching a end of support period. (@JeelDobariya38)",
+ "**Improved Performance & Security**: keeping up with android latest dependencies & community standards. (@dependabot)"
+ ]
+ },
+ {
+ "title": "Fixed",
+ "items": [
+ "**Back Navigation**: improved & fixed back navigation problem with preview layouts. handle android backstack. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "17 (API level 37)",
+ "versionCode": 6,
+ "versionName": "v2.1.0-Beta",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "End of Support for v2.x.x | Expo-React-Native kickstart...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v2.0.0...v2.1.0",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 40
+ },
+ {
+ "slug": "v2-0-0-beta",
+ "version": "v2.0.0",
+ "title": "v2.0.0 — Compose Multiplatform Design System",
+ "date": "2026-04-16",
+ "releaseType": "Beta",
+ "category": "Features",
+ "summary": "Brand new Compose Multiplatform design system, SQLite database v2 migration, and preview Android autofill service in the native codebase.",
+ "highlights": [
+ "**No breaking changes**: just the internal database version has changed.",
+ "**Biometrics Authentication**: enhanced safety for password manager by restricting access to app. users now need to authenticate to open the application. (@JeelDobariya38)",
+ "**Accessibility Layouts**: added support for two different layouts: one is morden and intended to be use by teenages. while other one is bit old, but easy to navigate by elderly peoples. (@JeelDobariya38)",
+ "**Better Jetpack Compose Support**: improve support for jetpack compose UI & streamline the process of migrating from oldUI to jetpack UI. (@JeelDobariya38)",
+ "**Better Update Checking**: migrated to ktor http client. it is modern and versatile http library. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Breaking Changes",
+ "items": [
+ "**No breaking changes**: just the internal database version has changed."
+ ]
+ },
+ {
+ "title": "Preview Features",
+ "items": [
+ "**Biometrics Authentication**: enhanced safety for password manager by restricting access to app. users now need to authenticate to open the application. (@JeelDobariya38)",
+ "**Accessibility Layouts**: added support for two different layouts: one is morden and intended to be use by teenages. while other one is bit old, but easy to navigate by elderly peoples. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Better Jetpack Compose Support**: improve support for jetpack compose UI & streamline the process of migrating from oldUI to jetpack UI. (@JeelDobariya38)",
+ "**Better Update Checking**: migrated to ktor http client. it is modern and versatile http library. (@JeelDobariya38)",
+ "**Improved Performance & Security**: keeping up with android latest dependencies & community standards. we have resolve & migrated all of our (concerned) dependency, except one `org.json` which is also at rank #74 in maven repository. so, its a community standard anyway. (@dependabot)"
+ ]
+ },
+ {
+ "title": "Fixed",
+ "items": [
+ "**Autofill Crashing**: improved & fixed the bug with autofill service. now autofilling is not crashing anymore. (but, its still a preview feature). (@JeelDobariya38) & (@hexCode63)"
+ ]
+ },
+ {
+ "title": "Other Changes",
+ "items": [
+ "**Improve DX**: improvements in CI/CD, documentation & jetpack-compose-previews in android studio. (@JeelDobariya38)",
+ "**Multiplatform (Early Start)**: maded database & design system compatible for kmp development. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 5,
+ "versionName": "v2.0.0-Beta",
+ "masterDbVersion": "v2"
+ },
+ "tldr": "Added fingerprint lock & fixed autofill feature...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.2.1...v2.0.0",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 42
+ },
+ {
+ "slug": "v1-2-1-alpha",
+ "version": "v1.2.1",
+ "title": "v1.2.1 — Version Name Fix & Release Alignment",
+ "date": "2026-01-31",
+ "releaseType": "Alpha",
+ "category": "Fixes",
+ "summary": "Targeted maintenance release correcting version naming and code metadata from the yanked v1.2.0 release to ensure consistent bug reporting and updates.",
+ "highlights": [
+ "**Update Version Info**: update the version name and version code that, I forget last time in a rush of releasing a new version.. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Fixed",
+ "items": [
+ "**Update Version Info**: update the version name and version code that, I forget last time in a rush of releasing a new version.. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 4,
+ "versionName": "v1.2.1-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Fix my mistake, by updating the version name that I forget last time...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.2.0...v1.2.1",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 48
+ },
+ {
+ "slug": "v1-2-0-alpha-yanked",
+ "version": "v1.2.0",
+ "title": "v1.2.0 — Jetpack Compose Preview UI (Yanked)",
+ "date": "2026-01-31",
+ "releaseType": "Alpha",
+ "category": "Improvements",
+ "summary": "Early preview of Jetpack Compose UI for basic password operations and improved rendering performance. Explicitly yanked due to version metadata duplication.",
+ "highlights": [
+ "**Jetpack Compose (Preview Feature)**: made a jetpack compose UI that can be used for basic operation. (@JeelDobariya38)",
+ "**Mimetypes For Import Passwords**: fixed csv mimetypes for importing passswords feature for better experience with android file picker.. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Preview Features",
+ "items": [
+ "**Jetpack Compose (Preview Feature)**: made a jetpack compose UI that can be used for basic operation. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Fixed",
+ "items": [
+ "**Mimetypes For Import Passwords**: fixed csv mimetypes for importing passswords feature for better experience with android file picker.. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 3,
+ "versionName": "v1.1.2-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Design a new jetpack compose preview ui.. | Improved performance...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.1.2...v1.2.0",
+ "isMajor": false,
+ "isYanked": true,
+ "yankedReason": "Yanked release: version name was mistakenly kept as v1.1.2-Alpha during release packaging. Superseded immediately by v1.2.1.",
+ "assetsCount": 6,
+ "downloadCount": 13
+ },
+ {
+ "slug": "v1-1-2-alpha",
+ "version": "v1.1.2",
+ "title": "v1.1.2 — Architecture Cleanup & Multi-Module Refactor",
+ "date": "2025-12-15",
+ "releaseType": "Alpha",
+ "category": "Architecture",
+ "summary": "Extensive internal code quality refactor, modular multi-module Gradle project structure, and settings schema migration while preserving all local password data untouched.",
+ "highlights": [
+ "**Migrate to DataStore**: changed the way how setting and feature flag were been storage. previously, we were using shared preferences. but, now we use datastore which is much more modern way of storing such type of data... but this will also mean that all your previously store setting will be longer be available anymore. we have decide this breaking changes, because app settings can be restored again (in like few minutes). (@JeelDobariya38)",
+ "**Autofill System (Preview Feature)**: added an autofill service to autofill user's credentials on the fly. (@hexCode63)",
+ "**Jetpack Compose (Preview Feature)**: added jetpack compose UI & even added a toggle to switch to this new UI. but it would be worthless to do so, because it just has a single screen.. _this feature is mainly for very earlier testing_. (@JeelDobariya38)",
+ "**MVI Flavored - Clean Architecture**: migrated the codebase to make it more scalable, extendable & readable. this will enable us to create better features faster & make a strong base for faster iteration & collaboration. and will help us delegate & modularized task in future. (@JeelDobariya38)",
+ "**Java 21**: code now compile to java 21. previously it was compiling to java 11. this should improve performance & efficiency a bit. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Breaking Changes",
+ "items": [
+ "**Migrate to DataStore**: changed the way how setting and feature flag were been storage. previously, we were using shared preferences. but, now we use datastore which is much more modern way of storing such type of data... but this will also mean that all your previously store setting will be longer be available anymore. we have decide this breaking changes, because app settings can be restored again (in like few minutes). (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Preview Features",
+ "items": [
+ "**Autofill System (Preview Feature)**: added an autofill service to autofill user's credentials on the fly. (@hexCode63)",
+ "**Jetpack Compose (Preview Feature)**: added jetpack compose UI & even added a toggle to switch to this new UI. but it would be worthless to do so, because it just has a single screen.. _this feature is mainly for very earlier testing_. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**MVI Flavored - Clean Architecture**: migrated the codebase to make it more scalable, extendable & readable. this will enable us to create better features faster & make a strong base for faster iteration & collaboration. and will help us delegate & modularized task in future. (@JeelDobariya38)",
+ "**Java 21**: code now compile to java 21. previously it was compiling to java 11. this should improve performance & efficiency a bit. (@JeelDobariya38)",
+ "**Improved Performance & Responsiveness**: Improve performance & better responsiveness of UI (less of density pixel, more of scalable pixel measurements). (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 3,
+ "versionName": "v1.1.2-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Improve the internal code quality.. | Clean architecture in codebase...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.1.1...v1.1.2",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 49
+ },
+ {
+ "slug": "v1-1-1-alpha",
+ "version": "v1.1.1",
+ "title": "v1.1.1 — CSV Import File Fix",
+ "date": "2025-09-11",
+ "releaseType": "Alpha",
+ "category": "Fixes",
+ "summary": "Fixes file picker MIME type resolution bug that prevented selecting CSV files during credential import.",
+ "highlights": [
+ "**Fixed Import Passwords**: fixed the bug that was not allowing user to select csv files from file picker. due to incorrect mimetype in code.. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Fixed",
+ "items": [
+ "**Fixed Import Passwords**: fixed the bug that was not allowing user to select csv files from file picker. due to incorrect mimetype in code.. (@JeelDobariya38)"
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 2,
+ "versionName": "v1.1.1-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Sorry for delay, but we have fix import files feature...",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.1",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.1.0...v1.1.1",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 56
+ },
+ {
+ "slug": "v1-1-0-alpha",
+ "version": "v1.1.0",
+ "title": "v1.1.0 — UI Improvements & GitHub Organization Transition",
+ "date": "2025-09-01",
+ "releaseType": "Alpha",
+ "category": "Features",
+ "summary": "Visual UI refinements on the credential viewer, in-app feature flagging system for preview features, basic update checker, and official transition to the PasscodesApp GitHub organization.",
+ "highlights": [
+ "**Improved UI/UX**: improved view password screen's visual feel, also adjust the button colors a bit. (@JeelDobariya38)",
+ "**Added Feature Flagging**: given user a control on whether they wanna latest experience or stable experience. added a way for launching preview features without worry about their stability. (@JeelDobariya38)",
+ "**Update Checking**: made a basic update checker that help users to stay up to date with latest release & also notify user about already reported security vulnerability using pre-release mechanism. (@JeelDobariya38)",
+ "**Copy Button (preview feature)**: added a copy button for copying passwords for easy of use. but as it is potential threat to security, so made it as a preview feature. (@JeelDobariya38)",
+ "**G-Passwords Import/Export (preview feature)**: added a import/export feature. which is also compatible with google passwords. I have test it with my google password setup. but, I am not sure weather this will run in every edge case or not. So, it is a preview feature for now. (@JeelDobariya38)"
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Improved UI/UX**: improved view password screen's visual feel, also adjust the button colors a bit. (@JeelDobariya38)",
+ "**Added Feature Flagging**: given user a control on whether they wanna latest experience or stable experience. added a way for launching preview features without worry about their stability. (@JeelDobariya38)",
+ "**Update Checking**: made a basic update checker that help users to stay up to date with latest release & also notify user about already reported security vulnerability using pre-release mechanism. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Preview Features",
+ "items": [
+ "**Copy Button (preview feature)**: added a copy button for copying passwords for easy of use. but as it is potential threat to security, so made it as a preview feature. (@JeelDobariya38)",
+ "**G-Passwords Import/Export (preview feature)**: added a import/export feature. which is also compatible with google passwords. I have test it with my google password setup. but, I am not sure weather this will run in every edge case or not. So, it is a preview feature for now. (@JeelDobariya38)"
+ ]
+ },
+ {
+ "title": "Notes",
+ "items": [
+ "**Official Github Organization (Aug 31, 2025)**: migrate project & repository from `JeelDobariya38 (personal account)` to `PasscodesApp (my organization)` for better development and governance of the project."
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 2,
+ "versionName": "v1.1.0-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Design Improvements.. | Will work with google passwords.... | We are officially an organization on GitHub from Aug 31, 2025....",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v1.0.0...v1.1.0",
+ "isMajor": false,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 31
+ },
+ {
+ "slug": "v1-0-0-stable",
+ "version": "v1.0.0",
+ "title": "v1.0.0 — First Official Stable Release",
+ "date": "2025-08-16",
+ "releaseType": "Stable",
+ "category": "Features",
+ "summary": "The inaugural stable release of the original native Android application. Offline-first local password storage on device via Room SQLite with zero cloud dependencies.",
+ "highlights": [
+ "**Localized App**: added language translation for English, Chinese, Hindi, Indonesian, Japanese, Korean, German, Spanish, Vietnamese. (@JeelDobariya38).",
+ "**Improved UI/UX**: added confirmation dialogs for destructive actions, improved support for light & dark theme with additional minor changes. [@JeelDobariya38 & @kudanilll].",
+ "**New Icon**: rebanded the app as passcodes with a new visual app icon. (@JeelDobariya38).",
+ "**Migrated Package Name**: migrate package name from `com.passwordmanager` to `com.jeeldobariya.passcodes`. (@JeelDobariya38).",
+ "**Improve Safety By Kotlin Implementation**: move away from `Java` to `Kotlin` Language. (@JeelDobariya38)."
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**Localized App**: added language translation for English, Chinese, Hindi, Indonesian, Japanese, Korean, German, Spanish, Vietnamese. (@JeelDobariya38).",
+ "**Improved UI/UX**: added confirmation dialogs for destructive actions, improved support for light & dark theme with additional minor changes. [@JeelDobariya38 & @kudanilll].",
+ "**New Icon**: rebanded the app as passcodes with a new visual app icon. (@JeelDobariya38)."
+ ]
+ },
+ {
+ "title": "Changed",
+ "items": [
+ "**Migrated Package Name**: migrate package name from `com.passwordmanager` to `com.jeeldobariya.passcodes`. (@JeelDobariya38).",
+ "**Improve Safety By Kotlin Implementation**: move away from `Java` to `Kotlin` Language. (@JeelDobariya38).",
+ "**Improve Data Storing Process**: move away from `SqliteDatabase` to `Room` Library for better datastorage & security. (@JeelDobariya38)."
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.jeeldobariya.passcodes",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "14 (API level 34)",
+ "versionCode": 1,
+ "versionName": "v1.0.0-Stable",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Our first stable release.. | Not much has change in terms of look and features.. | Name of project has changed to Passcodes..",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0",
+ "compareUrl": "https://github.com/PasscodesApp/Passcodes/compare/v0.1.0...v1.0.0",
+ "isMajor": true,
+ "isYanked": false,
+ "assetsCount": 6,
+ "downloadCount": 66
+ },
+ {
+ "slug": "v0-1-0-alpha-yanked",
+ "version": "v0.1.0",
+ "title": "v0.1.0 — Initial Prototype Alpha (Yanked)",
+ "date": "2024-08-26",
+ "releaseType": "Alpha",
+ "category": "Features",
+ "summary": "The very first proof-of-concept prototype for Passcodes, published under com.passwordmanager. Offline-first local password storage prototype.",
+ "highlights": [
+ "**App Icon Creation**: designed and implemented the initial app icon, providing the application with a recognizable visual identity. (@HamadaNative).",
+ "**Basic App Structure**: established the foundational architecture of the app, including the main entry point and the initial setup. (@JeelDobariya38).",
+ "**Main Page Development**: developed the main page of the app, including basic UI components and initial layout. (@JeelDobariya38).",
+ "**Basic Password Store**: developed a database to store the passwords data. (@kudanilll).",
+ "**Basic Design System**: developed a basic material 2 design system for consistency in app's feel & look. (@HamadaNative)."
+ ],
+ "sections": [
+ {
+ "title": "Added",
+ "items": [
+ "**App Icon Creation**: designed and implemented the initial app icon, providing the application with a recognizable visual identity. (@HamadaNative).",
+ "**Basic App Structure**: established the foundational architecture of the app, including the main entry point and the initial setup. (@JeelDobariya38).",
+ "**Main Page Development**: developed the main page of the app, including basic UI components and initial layout. (@JeelDobariya38).",
+ "**Basic Password Store**: developed a database to store the passwords data. (@kudanilll).",
+ "**Basic Design System**: developed a basic material 2 design system for consistency in app's feel & look. (@HamadaNative)."
+ ]
+ },
+ {
+ "title": "Notes",
+ "items": [
+ "This was the initial alpha (pre-release), focusing more on setting up the app for a basic structure and visual elements. It is an prototype release (`Proof Of Concept`)."
+ ]
+ }
+ ],
+ "internalDetails": {
+ "packageName": "com.passwordmanager",
+ "minAndroid": "8.0 (API level 26)",
+ "maxAndroid": "13 (API level 33)",
+ "versionCode": 1,
+ "versionName": "0.1.0-Alpha",
+ "masterDbVersion": "v1"
+ },
+ "tldr": "Our first initial release.. | Prototype release..",
+ "githubUrl": "https://github.com/PasscodesApp/Passcodes/releases/tag/v0.1.0",
+ "isMajor": true,
+ "isYanked": true,
+ "yankedReason": "Yanked prototype release: very early premature prototype published under com.passwordmanager. Kept strictly for documentation and project history.",
+ "assetsCount": 6,
+ "downloadCount": 98
+ }
+]
\ No newline at end of file
diff --git a/src/data/raw-changelog.md b/src/data/raw-changelog.md
new file mode 100644
index 0000000..a7e53db
--- /dev/null
+++ b/src/data/raw-changelog.md
@@ -0,0 +1,630 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+We don't strictly follow them. but the exceptions are very less, very intuitive, but..obvious
+and well documented in our release workflow docs.
+
+!!! tip
+
+ Do checkout the [release notes](release-notes.md) for casual changelog. it is more user friendly to read..
+ and documents important changes to project in a way's that make sense from a users view.
+
+ This here is for technical users and more developer oriented changelog.
+
+---
+
+## Link
+
+- **Website:** [https://passcodesapp.github.io/Passcodes-Website/](https://passcodesapp.github.io/Passcodes-Website/)
+- **Discord:** [Discord (@kSSkYq7KAQ)](https://discord.gg/kSSkYq7KAQ)
+
+---
+
+## v3.2.1 - Stable (Aug 2, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 57
+Version Code = 10
+Version Name = "v3.2.1-Stable"
+Master Database Schema Version = "v2"
+```
+
+
+
+### Added
+
+- **Support Screen Rotation**: added screen roatation support & grid layout for it.
+
+### Changed
+
+- **Improved Settings**: improved settings screen & make layout consistent. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Optimized Performance**: upgrade to latest dependencies & code optimizations [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Fixed
+
+- **Back Navigation With Tabs**: fixed the backward navigation problems with tabs. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **In App Lock**: fixed the in-app lock, it now also work on devices that doesn't have biometrics support. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.1){:target="\_blank"}
+[Release Notes](release-notes.md#v321-stable-aug-2-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.2.0...v3.2.1)
+
+---
+
+## v3.2.0 - Stable (July 25, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 57
+Version Code = 10
+Version Name = "v3.2.0 - Stable"
+Master Database Schema Version = "v2"
+```
+
+
+
+### Added
+
+- **Material UI**: added material UI for better UI/UX. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Font Awesome Icons**: add fontawesome icons for better layout understanding. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Screen Shot Prevention**: add screen-shot prevention on passscodes details screen. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **Improved Navigation**: add tab navigation for better & modern navigation flow. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Optimized Performance**: upgrade to Expo SDK 57, improved performance & added flash-list for scrolling performance & added architecture specific app download option for optimized app size. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.0){:target="\_blank"}
+[Release Notes](release-notes.md#v320-stable-july-25-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.1.0...v3.2.0)
+
+---
+
+## v3.1.0 - Stable (June 22, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 56
+Version Code = 9
+Version Name = "v3.1.0-Stable"
+Master Database Schema Version = "v2"
+```
+
+
+
+### Added
+
+- **Update Passwords Functionality**: added a update password functionality. which was missing in last (v3.0.0-Alpha) release. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **In-App Lock**: added a in-app biometrics lock to protect user data. it can be opt-in by using settings. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Import & Export Google Passwords**: added a way to import & export passwords to csv. specifically, the format is compatible with google passwords. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Keep My Data On Uninstall**: added a android only feature, that prompts user on uninstall. weather to keep thier data or delete it. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **Intuitive UI/UX**: improved UI for users, make it easier for user to navigate around. and easily tell wether something is text or button. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Fix Database Naming Inconsistency**: fix inconsietency in naming of database. it will need user to go and click on `Setting -> Data Recovery` to get thier data back. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Improved Performance**: faster start up times, better speed & more faster performant exprience overall. as we have moved to expo sdk 56. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Improved Troubleshooting**: significant better troubleshooting option with high performance. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Fixed
+
+- **Splash Screen**: improved & fixed icons on splash screen. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Notes
+
+When you open the app after upgrading, all your data (passwords) will not be visible from new app.
+cuz, new react native app use a different database (master). so, password that saved previously are in different database & need to be imported.
+
+To import the old data. Go into `Setting` inside the app. and just click `Data Recovery` under troubleshooting.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.1.0){:target="\_blank"}
+[Release Notes](release-notes.md#v310-stable-june-22-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.0.0...v3.1.0)
+
+---
+
+## v3.0.0 - Alpha (May 24, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 55
+Version Code = 8
+Version Name = "v3.0.0-Alpha"
+Master Database Schema Version = "v2"
+```
+
+
+
+!!! info "Remake A Basic Passcodes App"
+
+ we have start again with expo (react-native). which means, we have deleted the old codebase and started again.
+ so, the new app lacks potential features. we are trying hard to develop the features as soon as possible.
+
+ please stick with us.
+
+### Added
+
+- **Remake With Expo (React Native)**: maked the app again with expo (react-native). maked a basic password manager app. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Migrated Data To Drizzle DB**: wrote a drizzle database implementaion & a way to get old data from `room db` into `drizzle db`. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Troubleshooting Options**: added troubleshooting option. specifically, a way to get back all your password from previous versions. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Notes
+
+When you open the app after upgrading, all your data (passwords) will not be visible from new app.
+cuz, new react native app use a different database (drizzle). so, password that saved previously are in Room database,
+need to be imported.
+
+To import the old data. Go into `Setting` inside the app. and click `GetBack Passwords From Prior To v3` under troubleshooting. now you redirect to new screen where you need wait utill you see in green color... `SUCCESSFULLY MIGRATED.....`. and that's it.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.0.0){:target="\_blank"}
+[Release Notes](release-notes.md#v300-alpha-may-24-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.1.1...v3.0.0)
+
+---
+
+## ----- End Of Android Only -----
+
+We have officially moved of android native and we now use expo react native.
+
+---
+
+## v2.1.1 - Beta (May 19, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 17 (API level 37)
+Version Code = 7
+Version Name = "v2.1.1-Beta"
+Master Database Version = "v2"
+```
+
+
+
+!!! failure "Some MIUI Phones Takes Time To Adjust"
+
+ basically, I have heard from some users. specfically, In MIUI (Hyper OS), Material 3 Expressive UI is taking time to load/adjust..
+ like after you install the app.. it takes 5-10 minutes... I don;t why it like that.. maybe cuz, specfic device configuration...
+
+ give it time. cuz, it fix itself,
+ according to what i have hear from users.... I & no one, on development team have testing device. so we wouldn;t be able to detect the bug cause... but the app is in end-of-supprt anyway.
+
+ if is still not fix... then I (as in JeelDobariya38) have release a unofficial update from my part on telegram community...
+ it a unofficial (opt-in) release only for those who are getting the bug...
+ that opt-in release, will not have any support what-so-ever... i have just reverted the changes of Material 3 Expressive UI using git. what-so-ever.
+
+ [v2.1.2 download link](https://t.me/passcodescommunity/236) (idk how much time, this link will be valid for...)
+
+### Added
+
+- **Material 3 Expressive**: added material 3 expressive buttons and theme in defualt (old) ui. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **Improve Importing/Exporting Passwords**: added apache csv libaray to handle csv files. it now handles escaped-qouted commas & newline in (google-passwords generated) csv. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.1){:target="\_blank"}
+[Release Notes](release-notes.md#v211-beta-may-19-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.1.0...v2.1.1)
+
+---
+
+## v2.1.0 - Beta (May 12, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 17 (API level 37)
+Version Code = 6
+Version Name = "v2.1.0-Beta"
+Master Database Version = "v2"
+```
+
+
+
+### Breaking Changes
+
+- **No breaking changes.. but, end of support warning**: this is last release from android codebase. we will now migrate to expo-react-native and thier will be no security updates provided for release v2.x.x & prior, what-so-ever.
+
+### Added
+
+- **Improve View Password Screen**: improved view password & other password management screens. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Improve URL field**: improved support for url field. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **Android 17 Support**: bring official support for android 15, 16 & 17. which previous was limited to android 14 officially. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Import/Export Stability**: import/export passwords features are now stabilized. and are no longer a preview feature. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Adjusted Update Checking**: adjusted & optimized update checking for performance as we are reaching a end of support period. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Improved Performance & Security**: keeping up with android latest dependencies & community standards. [[@dependabot]](https://github.com/dependabot)
+
+### Fixed
+
+- **Back Navigation**: improved & fixed back navigation problem with preview layouts. handle android backstack. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Notes
+
+**End Of Support**: this offically marks end the android native development era over here in passcodes as we are now migrating to react-native (expo). please note that no further security updates will be provided for this & prior releases.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.0){:target="\_blank"}
+[Release Notes](release-notes.md#v210-beta-may-12-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.0.0...v2.1.0)
+
+---
+
+## v2.0.0 - Beta (Apr 16, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 5
+Version Name = "v2.0.0-Beta"
+Master Database Version = "v2"
+```
+
+
+
+### Breaking Changes
+
+- **No breaking changes**: just the internal database version has changed.
+
+### Added
+
+#### Preview Features
+
+- **Biometrics Authentication**: enhanced safety for password manager by restricting access to app. users now need to authenticate to open the application. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Accessibility Layouts**: added support for two different layouts: one is morden and intended to be use by teenages. while other one is bit old, but easy to navigate by elderly peoples. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **Better Jetpack Compose Support**: improve support for jetpack compose UI & streamline the process of migrating from oldUI to jetpack UI. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Better Update Checking**: migrated to ktor http client. it is modern and versatile http library. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Improved Performance & Security**: keeping up with android latest dependencies & community standards. we have resolve & migrated all of our (concerned) dependency, except one `org.json` which is also at rank #74 in maven repository. so, its a community standard anyway. [[@dependabot]](https://github.com/dependabot)
+
+### Fixed
+
+- **Autofill Crashing**: improved & fixed the bug with autofill service. now autofilling is not crashing anymore. (but, its still a preview feature). [[@JeelDobariya38]](https://github.com/JeelDobariya38) & [[@hexCode63]](https://github.com/hexCode63)
+
+### Other Changes
+
+- **Improve DX**: improvements in CI/CD, documentation & jetpack-compose-previews in android studio. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+- **Multiplatform (Early Start)**: maded database & design system compatible for kmp development. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Notes
+
+**Resolved all backlogs with Goggle latest standards for android development**: We have complete the biggest migration that was going on in passcodes. [PasscodesApp/Passcodes#42](https://github.com/PasscodesApp/Passcodes/issues/42)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0){:target="\_blank"}
+[Release Notes](release-notes.md#v200-beta-apr-16-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.2.1...v2.0.0)
+
+---
+
+## v1.2.1 - Alpha (Jan 31, 2026)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 4
+Version Name = "v1.2.1-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+### Fixed
+
+- **Update Version Info**: update the version name and version code that, I forget last time in a rush of releasing a new version.. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1){:target="\_blank"}
+[Release Notes](release-notes.md#v121-alpha-jan-31-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.2.0...v1.2.1)
+
+## v1.2.0 - Alpha (Jan 31, 2026) [YANKED RELEASE]
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 3
+Version Name = "v1.1.2-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+!!! failure
+
+ This is yanked release.. cuz, I forget to update version name in hurry of releasing a new version.
+
+ Don't use this release (v1.2.0) in any case.... always prefer that release (v1.2.1) over this... because it will create confusion in bug reports like if you use this release and a bug occur... you will not be able to tell whether you are on previous release (v1.1.2) or this release (v1.2.0)... due to same version number in two different release....
+
+### Added
+
+#### Preview Features
+
+- **Jetpack Compose (Preview Feature)**: made a jetpack compose UI that can be used for basic operation. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Fixed
+
+- **Mimetypes For Import Passwords**: fixed csv mimetypes for importing passswords feature for better experience with android file picker.. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0){:target="\_blank"}
+[Release Notes](release-notes.md#v120-alpha-jan-31-2026-yanked-release)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.2...v1.2.0)
+
+## v1.1.2 - Alpha (Dec 15, 2025)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 3
+Version Name = "v1.1.2-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+!!! danger "Breaking Changes"
+
+ This is a kind of a breaking release, it will wipe off all your in-app settings..
+ which mean after updating the app, all your previous setting will be reset to defualt.
+
+ This **doesn't** mean that your password data will be lost.. I repeat **your password data will be there as it is, untouched in app**.
+
+ ??? question "You may ask why this is not `v2.0.0`? even if it has breaking changes???"
+ Firstly, the user interaction with app is not change that much in this release that it make sense to make it a major release (`v2.0.0`).
+
+ Secondly & more importantly, It is `v1.1.1` because, setting's data is not than important, core & criticual to app itself.
+
+### Breaking Changes
+
+- **Migrate to DataStore**: changed the way how setting and feature flag were been storage.
+ previously, we were using shared preferences. but,
+ now we use datastore which is much more modern way of storing such type of data... but this will also mean
+ that all your previously store setting will be longer be available anymore. we have decide this breaking changes,
+ because app settings can be restored again (in like few minutes). [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Added
+
+#### Preview Features
+
+- **Autofill System (Preview Feature)**: added an autofill service to autofill user's credentials on
+ the fly. [[@hexCode63]](https://github.com/hexCode63)
+
+- **Jetpack Compose (Preview Feature)**: added jetpack compose UI & even added a toggle to switch to
+ this new UI. but it would be worthless to do so, because it just has a single screen.. _this feature is mainly
+ for very earlier testing_. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Changed
+
+- **MVI Flavored - Clean Architecture**: migrated the codebase to make it more scalable,
+ extendable & readable. this will enable us to create better features faster & make a strong base for faster
+ iteration & collaboration. and will help us delegate & modularized task in future. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+- **Java 21**: code now compile to java 21. previously it was compiling to java 11.
+ this should improve performance & efficiency a bit. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+- **Improved Performance & Responsiveness**: Improve performance & better responsiveness of UI (less of density
+ pixel, more of scalable pixel measurements). [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2){:target="\_blank"}
+[Release Notes](release-notes.md#v112-alpha-dec-15-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.1...v1.1.2)
+
+---
+
+## v1.1.1 - Alpha (Sept 11, 2025)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 2
+Version Name = "v1.1.1-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+### Fixed
+
+- **Fixed Import Passwords**: fixed the bug that was not allowing user to select csv files
+ from file picker. due to incorrect mimetype in code.. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.1){:target="\_blank"}
+[Release Notes](release-notes.md#v111-alpha-sept-11-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.0...v1.1.1)
+
+---
+
+## v1.1.0 - Alpha (Sept 1, 2025)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 2
+Version Name = "v1.1.0-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+### Added
+
+- **Improved UI/UX**: improved view password screen's visual feel, also adjust the button colors a
+ bit. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+- **Added Feature Flagging**: given user a control on whether they wanna latest experience or stable
+ experience. added a way for launching preview features without worry about their
+ stability. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+- **Update Checking**: made a basic update checker that help users to stay up to date with latest
+ release & also notify user about already reported security vulnerability using pre-release
+ mechanism. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+#### Preview Features
+
+- **Copy Button (preview feature)**: added a copy button for copying passwords for easy of use. but
+ as it
+ is potential threat to security, so made it as a preview feature. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+- **G-Passwords Import/Export (preview feature)**: added a import/export feature. which is also
+ compatible with google passwords. I have test it with my google password setup. but, I am not sure
+ weather this will run in every edge case or not. So, it is a preview feature for
+ now. [[@JeelDobariya38]](https://github.com/JeelDobariya38)
+
+### Notes
+
+- **Official Github Organization (Aug 31, 2025)**: migrate project & repository from
+ `JeelDobariya38 (personal account)`
+ to `PasscodesApp (my organization)` for better development and governance of the project.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.0){:target="\_blank"}
+[Release Notes](release-notes.md#v110-alpha-sept-1-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.0.0...v1.1.0)
+
+---
+
+## v1.0.0 - Stable (Aug 16, 2025)
+
+
+ View Internal Details
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 1
+Version Name = "v1.0.0-Stable"
+Master Database Version = "v1"
+```
+
+
+
+### Added
+
+- **Localized App**: added language translation for English, Chinese, Hindi, Indonesian, Japanese,
+ Korean,
+ German, Spanish, Vietnamese. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+- **Improved UI/UX**: added confirmation dialogs for destructive actions, improved support for
+ light & dark
+ theme with additional minor changes. [[@JeelDobariya38](https://github.com/JeelDobariya38) & [@kudanilll](https://github.com/kudanilll)].
+
+- **New Icon**: rebanded the app as passcodes with a new visual app icon. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+### Changed
+
+- **Migrated Package Name**: migrate package name from `com.passwordmanager` to
+ `com.jeeldobariya.passcodes`. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+- **Improve Safety By Kotlin Implementation**: move away from `Java` to `Kotlin`
+ Language. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+- **Improve Data Storing Process**: move away from `SqliteDatabase` to `Room` Library for better
+ datastorage & security. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0){:target="\_blank"}
+[Release Notes](release-notes.md#v100-stable-aug-16-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v0.1.0...v1.0.0)
+
+---
+
+## v0.1.0 - Alpha (Aug 26, 2024) [YANKED RELEASE]
+
+
+ View Internal Details
+
+```
+Package Name = "com.passwordmanager"
+Min Android = 8.0 (API level 26)
+Max Android = 13 (API level 33)
+Version Code = 1
+Version Name = "0.1.0-Alpha"
+Master Database Version = "v1"
+```
+
+
+
+!!! danger
+
+ This is an [yanked release](installing.md#explicitly-yanked-release-pure-trash) and should not be used by any user.
+ The soley purpose of this release is, just for documenation & serves as a part of project's story...
+
+ The main cause we have yanked this release is.. not that the release itself is bad by any manner.. this release was very early & premature..
+ As in, a prototype release. It is stable in it own pace.. and you can use it if, you wish to do so.. but treat this version more as premature. & just for learning..
+ If you have any error or bug using this version.. you can report to github issues. we will try our best to assist. but this issue won't have prority.. but it will be fun to discuss how an prototype release stand in production enviroment..
+
+ Also the project's name back then use to be "password manager". which is kind of dumb & lame name, and to be honest little to old also, but it is the name we have started our journey with. we have after a year (2024), maded a decision and envisioned project differently with a name "passcodes".. which is a also an old name, one of mine eariler project, which I have removed from github... but it was the reason I meet [Daniel](https://github.com/kudanilll) in the first place.. and we have started this new project as `password manager` and that eventally became `passcodes`... and now it's in production and in real user's hands... as you read this... 😂😂😂😂😂
+
+ The was a eariler release from a parent project of `passcodes`. Read more over at github [#12](https://github.com/PasscodesApp/Passcodes/discussions/12) & [#14](https://github.com/PasscodesApp/Passcodes/issues/14)
+
+### Added
+
+- **App Icon Creation**: designed and implemented the initial app icon, providing the application
+ with a recognizable visual identity. [[@HamadaNative]](https://github.com/HamadaNative).
+
+- **Basic App Structure**: established the foundational architecture of the app, including the main
+ entry point and the initial setup. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+- **Main Page Development**: developed the main page of the app, including basic UI components and
+ initial layout. [[@JeelDobariya38]](https://github.com/JeelDobariya38).
+
+- **Basic Password Store**: developed a database to store the passwords data. [[@kudanilll]](https://github.com/kudanilll).
+
+- **Basic Design System**: developed a basic material 2 design system for consistency in app's
+ feel & look. [[@HamadaNative]](https://github.com/HamadaNative).
+
+### Notes
+
+- This was the initial alpha (pre-release), focusing more on setting up the app for a basic structure and
+ visual elements. It is an prototype release (`Proof Of Concept`).
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v0.1.0){:target="\_blank"}
+[Release Notes](release-notes.md#v010-alpha-aug-26-2024-yanked-release)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/commits/v0.1.0)
diff --git a/src/data/raw-release-notes.md b/src/data/raw-release-notes.md
new file mode 100644
index 0000000..74e7dc2
--- /dev/null
+++ b/src/data/raw-release-notes.md
@@ -0,0 +1,451 @@
+# Release Notes
+
+Here, You will find short, sweet and casual `tldrs` for release notes or change-log.
+For more details and more professional tone, see [changelog.md](changelog.md).
+
+This release notes are more or less end-user oriented.
+
+!!! tip
+
+ Do checkout the [changelog](changelog.md) for more formal release notes. it is more technical to read..
+
+ This here are..... also.... more user oriented changes.... This document is more like a communication between,
+ developer & user about the changes and impact of passcodes project.
+
+---
+
+## Link
+
+- **Website:** [https://passcodesapp.github.io/Passcodes-Website/](https://passcodesapp.github.io/Passcodes-Website/)
+- **Discord:** [Discord (@kSSkYq7KAQ)](https://discord.gg/kSSkYq7KAQ)
+
+---
+
+## v3.2.1 - Stable (Aug 2, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 57
+Version Code = 10
+Version Name = "v3.2.1-Stable"
+Master Database Schema Version = "v2"
+```
+
+**`TL;DR`: Screen Rotation | Fix Tab Navigation | Improved UI/UX**
+
+- improved password list screen, added list & grid layout..
+- fixed tabs layout back navigation issue.
+- added inapp screen shot prevention toggle.
+- improved settings screen and make a consistent UI.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.1){:target="\_blank"}
+[Changelog](changelog.md#v321-stable-aug-2-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.2.0...v3.2.1)
+
+---
+
+## v3.2.0 - Stable (July 25, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 57
+Version Code = 10
+Version Name = "v3.2.0 - Stable"
+Master Database Schema Version = "v2"
+```
+
+**`TL;DR`: Material UI | Support Light/Dark Mode**
+
+- improved UX with modern material UI & modern gestures support.
+- added dark mode for night.
+- better security as we have added screen shot & screen capture prevention.
+- optimize the performance & size of application.
+- added icons for better understanding.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.0){:target="\_blank"}
+[Changelog](changelog.md#v320-stable-july-25-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.1.0...v3.2.0)
+
+---
+
+## v3.1.0 - Stable (June 22, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 56
+Version Code = 9
+Version Name = "v3.1.0-Stable"
+Master Database Schema Version = "v2"
+```
+
+??? question "How To Get Your Data Back"
+
+ When you open the app after upgrading, all your data (passwords) will not be visible/present in just updated app.
+ to get all that previous data, you need to go into `Setting` inside the app. and click on `Data Recovery`, under the troubleshooting section.
+
+ if you encounter any bug during this, don't panic or delete/uninstall the app.. firstly report to us @(telegram/discord) we will get you out of that mess. but if you delete/uninstall the app, we will not be able to help you.
+
+ So, **please never-ever uninstall the passcodes without taking a proper backup of your data**.
+
+**`TL;DR`: In-App Biometrics Lock | Import/Export Passwords To Google Passwords | Intuitive UI/UX**
+
+- added the update password feature that was missing in last update.
+- added in-app lock for better security. you need enable it from app settings. it will lock the app after 2 minutes of inactivity. if, it goes to background.
+- rich troubleshooting options. specifically, this option are much realiable and faster than previous troubleshooting.
+- provided a import & export feature for passwords. the format that we uses is compatible with google passwords.
+- improved UI/UX. added better styling for button & textfields. also thier is a rich password details screen.
+- faster startup times. faster interacion. faster everythings as we have move to expo sdk 56. reduced bundle sizing, even if new features are added.
+- and thier are small security things here and there like, keep my data prompt on android app uninstallion and stuff.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.1.0){:target="\_blank"}
+[Changelog](changelog.md#v310-stable-june-22-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v3.0.0...v3.1.0)
+
+---
+
+## v3.0.0 - Alpha (May 24, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Expo SDK = 55
+Version Code = 8
+Version Name = "v3.0.0-Alpha"
+Master Database Schema Version = "v2"
+```
+
+??? question "How To Get Back Old Data"
+
+ When you open the app after upgrading, all your data (passwords) will not be visible from new app.
+ to get all that old data, you need to go into `Setting` inside the app. and click on `GetBack Passwords From Prior To v3`, under troubleshooting section.
+ then you need to wait utill you see `SUCCESSFULLY MIGRATED` in green color. and that's it. navigate back or close and reopen the app and all your data will be back.
+
+ if you encounter any bug during this, don't panic or delete/uninstall the app.. firstly report to us @(telegram/discord) we will get you out of that mess. but if you delete/uninstall the app, we might not be able to help you.
+
+ So, **please never-ever uninstall the passcodes without taking a proper backup of your data**.
+
+**`TL;DR`: Cross Platform | Expo (React-Native) | Passcodes New Beginning...**
+
+- remaked the app again with expo (react-native).
+- currently, just made a basic password manager app. we are improve it but it first release from react native codebase.
+- added troubleshooting option. specifically, a way to get back all your password from previous versions.
+- we working on get all features avaiable untill now. we will releasing new version(s) soon.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v3.0.0){:target="\_blank"}
+[Changelog](changelog.md#v300-alpha-may-24-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.1.1...v3.0.0)
+
+---
+
+## ----- End Of Android Only -----
+
+We have officially moved of android native and we now use expo react native.
+
+---
+
+## v2.1.1 - Beta (May 19, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 17 (API level 37)
+Version Code = 7
+Version Name = "v2.1.1-Beta"
+Master Database Version = "v2"
+```
+
+???+ failure "Some MIUI Phones Takes Time To Adjust"
+
+ basically, I have heard from some users. specfically, In MIUI (Hyper OS), Material 3 Expressive UI is taking time to load/adjust..
+ like after you install the app.. it takes 5-10 minutes... I don;t why it like that.. maybe cuz, specfic device configuration...
+
+ give it time. cuz, it fix itself,
+ according to what i have hear from users.... I & no one, on development team have testing device. so we wouldn;t be able to detect the bug cause... but the app is in end-of-supprt anyway.
+
+ if is still not fix... then I (as in JeelDobariya38) have release a unofficial update from my part on telegram community...
+ it a unofficial (opt-in) release only for those who are getting the bug...
+ that opt-in release, will not have any support what-so-ever... i have just reverted the changes of Material 3 Expressive UI using git. what-so-ever.
+
+ [v2.1.2 download link](https://t.me/passcodescommunity/236) (idk how much time, this link will be valid for...)
+
+**`TL;DR`: End of Support for v2.x.x | Material 3 Expressive UI...**
+
+- add materail 3 expressive ui to buttons & themes.
+- improve importing & exporting google passwords to support multiline notes & qouted (") fields in csv.
+- improve security, performance updates.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.1){:target="\_blank"}
+[Changelog](changelog.md#v211-beta-may-19-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.1.0...v2.1.1)
+
+---
+
+## v2.1.0 - Beta (May 12, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 17 (API level 37)
+Version Code = 6
+Version Name = "v2.1.0-Beta"
+Master Database Version = "v2"
+```
+
+**`TL;DR`: End of Support for v2.x.x | Expo-React-Native kickstart...**
+
+- added a warning dialog for announcing "end of support".
+- now, android 15, 16 & 17 support offically. utill now we were supporting upto android 14.
+- make importing & exporting passwords as a stable feature.
+- fixed back navigation issues with preview layouts.
+- adjusted & optimized update checking features.
+- improved view password screen & enhanced url field support.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.0){:target="\_blank"}
+[Changelog](changelog.md#v210-beta-may-12-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v2.0.0...v2.1.0)
+
+---
+
+## v2.0.0 - Beta (Apr 16, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 5
+Version Name = "v2.0.0-Beta"
+Master Database Version = "v2"
+```
+
+**`TL;DR`: Added fingerprint lock & fixed autofill feature...**
+
+- improve security. added a fingerpint authentication to open application. its a preview feature for now.
+- fixed issues with autofill features. app doesn't crash anymore with autofill feature. its still a preview feature & under development.
+- added two different screen types for new modern & cool teenages & something easier to work with for elderly peoples. you can access it using in-app preview feature toggle.
+- improved support for switching between old-ui & new-ui. basically it look more like screen change rather than a app crash, which previously was true.
+- we are now a decent app, if looked from google point of view. we are following all best practices & actively keeping up with latest changes, except proper encryption. 😥😥😥
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0){:target="\_blank"}
+[Changelog](changelog.md#v200-beta-apr-16-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.2.1...v2.0.0)
+
+---
+
+## v1.2.1 - Alpha (Jan 31, 2026)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 4
+Version Name = "v1.2.1-Alpha"
+Master Database Version = "v1"
+```
+
+**`TL;DR`: Fix my mistake, by updating the version name that I forget last time...**
+
+- Last time (v1.2.0), I forget to update the version so fix it and re-release instantly... (gotta a real-idea of how dangerous "publish" button on github is.... 😂😂😂😂😂)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1){:target="\_blank"}
+[Changelog](changelog.md#v121-alpha-jan-31-2026)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.2.0...v1.2.1)
+
+## v1.2.0 - Alpha (Jan 31, 2026) [YANKED RELEASE]
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 3
+Version Name = "v1.1.2-Alpha"
+Master Database Version = "v1"
+```
+
+!!! failure
+
+ This is an [yanked release](installing.md#explicitly-yanked-release-pure-trash) and should not be used by any user.
+ The soley purpose of this release is, just for documenation & serves as a part of project's story...
+
+ This release is yanked cuz, I launch the app in hurry and forget to do something that need to be done... (forget to update version number)...
+ Checkout the release on github for full details...
+
+ Don't use this release (v1.2.0) in any case.... always prefer that release (v1.2.1) over this... because it will create confusion in bug reports like if you use this release and a bug occur... you will not be able to tell whether you are on previous release (v1.1.2) or this release (v1.2.0)... due to same version number in two different release....
+
+**`TL;DR`: Design a new jetpack compose preview ui.. | Improved performance...**
+
+- App now has a basic new preview.. jetpack compose ui... that can be used instead of old ui...
+- App provide a toggle to switch between two layouts...
+- Improve file selection menu experience while importing passwords..
+- Perfomance optimization. (due to dependency updates.)
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0){:target="\_blank"}
+[Changelog](changelog.md#v120-alpha-jan-31-2026-yanked-release)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.2...v1.2.0)
+
+## v1.1.2 - Alpha (Dec 15, 2025)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 3
+Version Name = "v1.1.2-Alpha"
+Master Database Version = "v1"
+```
+
+!!! danger
+
+ This is a kind of a breaking release, it will wipe off all your in-app settings..
+ which mean after updating the app, all your previous setting will be reset to defualt.
+
+ This **doesn't** mean that your password data will be lost.. I repeat **your password data will be there as it is, untouched in app**.
+
+ ??? question "You may ask why this is not `v2.0.0`? even if it has breaking changes???"
+ Firstly, the user interaction with app is not change that much in this release that it make sense to make it a major release (`v2.0.0`).
+
+ Secondly & more importantly, It is `v1.1.1` because, setting's data is not than important, core & criticual to app itself.
+
+**`TL;DR`: Improve the internal code quality.. | Clean architecture in codebase...**
+
+- For user side of app.. things might look same.. or even some part of ui, like conformation dialog may seems to disapper completely.
+- App has **changed completely internally in codebase**. The architecture of the app has shifted from something along the lines of MVC..
+ to MVI Flavoured Clean architecture. Which is more **like google's/industry's way of making app in android's world**...
+- This architecture changes in app will give us as developers a better place (codebase) to work in. This means a solid foundation for further features.
+- This release is more like a **shift in direction of passcodes development trajectory, towards becaming a industry/production ready app** rather than just became an another password manager app..
+- This release is also being a major part of—actually, it marks the completion of the phrase 1—biggest refactoring of codebase, we are doing at passcodes.... [#42](https://github.com/PasscodesApp/Passcodes/issues/42)
+- And thus, a part of it contains premature features like **Autofill & Jetpack Compose UI**. Which are served as a preview features in app, but you can also turn them on if you wish...
+- This release also bring with it some performance enhancements—theorically, Because I have not notice it yet—as the app now run on **`JAVA 21`**. it was previously `Java 11`.
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2){:target="\_blank"}
+[Changelog](changelog.md#v112-alpha-dec-15-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.1...v1.1.2)
+
+---
+
+## v1.1.1 - Alpha (Sept 11, 2025)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 2
+Version Name = "v1.1.1-Alpha"
+Master Database Version = "v1"
+```
+
+**`TL;DR`: Sorry for delay, but we have fix import files feature...**
+
+- We are **very sorry for the 10-days delay** for such a small fix.. We have officially fixed the import passwords csv file selection bug...
+- With this fix you can now import the new passwords as expected.....
+- Unlike eariler, **you will now able to select csv file from your device** file picker for importing passwords.
+- In big project, such small mistakes/things happens.. so, ignore it please...
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.1){:target="\_blank"}
+[Changelog](changelog.md#v111-alpha-sept-11-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.1.0...v1.1.1)
+
+---
+
+## v1.1.0 - Alpha (Sept 1, 2025)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 2
+Version Name = "v1.1.0-Alpha"
+Master Database Version = "v1"
+```
+
+??? question "Why "PasscodesApp" as a Github Organization? not Passcodes.."
+
+ Organization is named **PasscodesApp and not Passcodes. Because, passcodes as name is already taken** & not available on github as of _Aug 31, 2025_....
+
+ Stick to watch and observe upcoming changes & progress... [Telegram (@passcodescommunity)](https://t.me/passcodescommunity)
+
+**`TL;DR`: Design Improvements.. | Will work with google passwords.... | We are officially an organization on GitHub from `Aug 31, 2025`....**
+
+- This is our first **official release after migrating to the github organization...**
+- This release has feature like importing & exporting passwords from google password's app...
+- This is an alpha release. So it has unstable features.
+- Also, both the features (copying passwords & importing-exporting passwords) are disable by default. due to security threats... But, they can be turn on if you wish...
+- From this point onwards, app has a mechanism to release feature progressively using **`"feature flags"`**. This means one could opt-into newer unstable features & get earlier access to latest features. As a tradeoff to the stablity of the app itself.. meaning **you are an unoffical earlier tester** of the app/project..
+
+??? note "Became An Offical Tester"
+
+ If you wish to became a offical tester for the app, let us know on our telegram community. [(@passcodescommunity)](https://t.me/passcodescommunity)
+
+ This mean you get credit for your work & some testing responsiblity.. like testing new feature..
+ share you user point of view for a feature. test usablity of the whole app. and basically act as a Q/A Tester.
+
+ You might also ask to test the security and asked to exploit the app. so, that we can discover flaws in our app..
+
+- Also as the passcodes have change from **"just my personal hobby project" to an official github based organization**.. This release mark as a step forward for us towards open source and towards [open to contribute](../references/open-contributing-timeline.md)... and potentailly leading us as a community as a whole.....
+- And more importantly it reflect, my long term vision with passcodes as a project... what it means?...
+- Upcoming things will be more fascinating to watch and to be part of... So stick with us.. [Telegram (@passcodescommunity)](https://t.me/passcodescommunity)
+- And also the app will have more long term support... (if you ignore, the fact that [I am not a verified developer, as of _"1/9/25 by google"_... but will do it in a near time...](https://developer.android.com/developer-verification))
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.0){:target="\_blank"}
+[Changelog](changelog.md#v110-alpha-sept-1-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v1.0.0...v1.1.0)
+
+---
+
+## v1.0.0 - Stable (Aug 16, 2025)
+
+```
+Package Name = "com.jeeldobariya.passcodes"
+Min Android = 8.0 (API level 26)
+Max Android = 14 (API level 34)
+Version Code = 1
+Version Name = "v1.0.0-Stable"
+Master Database Version = "v1"
+```
+
+**`TL;DR`: Our first stable release.. | Not much has change in terms of look and features.. | Name of project has changed to `Passcodes`..**
+
+- This is our first stable release, even though it looks and behaves same as prototype release.
+- It's now more stable and more reliable as the data storage system is now tested, optimized and uses more modern approach (`room library`).
+- Things have change internally also... like app was first builded using java language.. but, now it is in **kotlin** language. which is more **align to google's way of building app**.
+- Now, you also have in-app ablity to switch languages & themes.. (Don;t rely on transalation as they are ai generated for now).
+- App now has an improved UI/UX, It has hint's.. especially, as you all where asking like, **"what is domain?" "what can i write in domain?" and so on.....**
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0){:target="\_blank"}
+[Changelog](changelog.md#v100-stable-aug-16-2025)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/compare/v0.1.0...v1.0.0)
+
+---
+
+## v0.1.0 - Alpha (Aug 26, 2024) [YANKED RELEASE]
+
+!!! danger
+
+ This is an [yanked release](installing.md#explicitly-yanked-release-pure-trash) and should not be used by any user.
+ The soley purpose of this release is, just for documenation & serves as a part of project's story...
+
+ The main cause we have yanked this release is.. not that the release itself is bad by any manner.. but the app name it uses is "password manager".
+ which is an old name, the name we have started our journey with. we have after a year (2024), maded a decision and envisioned project differently, with a name "passcodes".. which is a also an old name. one of mine eariler project, which I have removed from github... but it was the reason I meet [Daniel](https://github.com/kudanilll) in the first place.. and we have started this new project as `password manager` and that eventally became `passcodes`... and now it's in production and in real user's hands... as you read this... 😂😂😂😂😂
+
+ We have yanked this release to show this shift... you can even see in details below that package name has change..
+ So theoretically and practically also, It is an another app/project... an deperacted one in software term's...
+
+ Read more over at github [#12](https://github.com/PasscodesApp/Passcodes/discussions/12){:target="_blank"} & [#14](https://github.com/PasscodesApp/Passcodes/issues/14){:target="_blank"}
+
+```
+Package Name = "com.passwordmanager"
+Min Android = 8.0 (API level 26)
+Max Android = 13 (API level 33)
+Version Code = 1
+Version Name = "0.1.0-Alpha"
+Master Database Version = "v1"
+```
+
+**`TL;DR`: Our first initial release.. | Prototype release..**
+
+- It a prototype release which mean it can have bugs...
+- It has all the core features, like creating, reading, updating and deleting passwords...
+- It has a basic UI that allow you to do things, really intuitively and more structurely...
+- But structure and intuitiveness doesn't necessary means a modern user interface—which is little to less cool, but UI reflect a structure in it...
+
+[Checkout Release](https://github.com/PasscodesApp/Passcodes/releases/tag/v0.1.0){:target="\_blank"}
+[Changelog](changelog.md#v010-alpha-aug-26-2024-yanked-release)
+[Full Changelog](https://github.com/PasscodesApp/Passcodes/commits/v0.1.0)
diff --git a/src/data/raw-releases.json b/src/data/raw-releases.json
new file mode 100644
index 0000000..22f7acc
--- /dev/null
+++ b/src/data/raw-releases.json
@@ -0,0 +1,3510 @@
+[
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/363800392",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/363800392/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/363800392/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.1",
+ "id": 363800392,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084VrydI",
+ "tag_name": "v3.2.1",
+ "target_commitish": "main",
+ "name": "v3.2.1 - Stable",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-08-02T13:51:52Z",
+ "updated_at": "2026-08-02T15:02:40Z",
+ "published_at": "2026-08-02T15:02:40Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/498996180",
+ "id": 498996180,
+ "node_id": "RA_kwDOMffp084dvhPU",
+ "name": "v3.2.1-passcodes-x86_64-app.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 35922426,
+ "digest": "sha256:b8d20f36f9b87dcc31e5ca10ab4b0d1db7f485cf4907bfc39f53e811daa997b8",
+ "download_count": 0,
+ "created_at": "2026-08-02T14:54:35Z",
+ "updated_at": "2026-08-02T15:02:05Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.1/v3.2.1-passcodes-x86_64-app.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/498997803",
+ "id": 498997803,
+ "node_id": "RA_kwDOMffp084dvhor",
+ "name": "v3.2.1-passcodes-x86-app.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 36455085,
+ "digest": "sha256:75efa1becac99053b7e144f9d4a83ca32941ee2f90275ad2707dadee6e44c453",
+ "download_count": 0,
+ "created_at": "2026-08-02T14:56:24Z",
+ "updated_at": "2026-08-02T15:02:05Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.1/v3.2.1-passcodes-x86-app.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/498998852",
+ "id": 498998852,
+ "node_id": "RA_kwDOMffp084dvh5E",
+ "name": "v3.2.1-passcodes-universal-app.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 97593756,
+ "digest": "sha256:bf839ba66057169219d13c9c9fc883548f4eda26075a0df9311f6840f870d6fc",
+ "download_count": 0,
+ "created_at": "2026-08-02T14:57:32Z",
+ "updated_at": "2026-08-02T15:02:05Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.1/v3.2.1-passcodes-universal-app.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/499000911",
+ "id": 499000911,
+ "node_id": "RA_kwDOMffp084dviZP",
+ "name": "v3.2.1-passcodes-armeabi_v7a-app.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 28447625,
+ "digest": "sha256:110e35124036cd19002f3d838f0b559e3840c4b5fd8ec4a087e9fd1862174411",
+ "download_count": 0,
+ "created_at": "2026-08-02T15:00:28Z",
+ "updated_at": "2026-08-02T15:02:05Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.1/v3.2.1-passcodes-armeabi_v7a-app.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/499001230",
+ "id": 499001230,
+ "node_id": "RA_kwDOMffp084dvieO",
+ "name": "v3.2.1-passcodes-arm64_v8a-app.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 35428199,
+ "digest": "sha256:1db1e993f9421007bab6601e16453d90883384608345be3bff351aefc2db7f96",
+ "download_count": 24,
+ "created_at": "2026-08-02T15:00:58Z",
+ "updated_at": "2026-08-02T15:02:05Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.1/v3.2.1-passcodes-arm64_v8a-app.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v3.2.1",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v3.2.1",
+ "body": "# What's Changed\r\n\r\n## 🚀 New Features\r\n- Feat: Explicit Screenshot Prevention by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/217\r\n\r\n## 🐛 Bug Fixes\r\n- Build: Support Split ABIs by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/214\r\n- Fix: Back Navigation With Tabs by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/215\r\n- Feat: Consistent UI/UX & Fix Navigation. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/216\r\n\r\n## 🛠 Code Refactoring\r\n- Chore: improve app.config.ts by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/218\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v3.2.0...v3.2.1",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/359669321",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/359669321/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/359669321/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.0",
+ "id": 359669321,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084VcB5J",
+ "tag_name": "v3.2.0",
+ "target_commitish": "main",
+ "name": "v3.2.0 - Stable",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-07-25T04:43:56Z",
+ "updated_at": "2026-07-25T11:55:04Z",
+ "published_at": "2026-07-25T09:34:06Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/489296201",
+ "id": 489296201,
+ "node_id": "RA_kwDOMffp084dKhFJ",
+ "name": "v3.2.0-passcodes-app-x86_64.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 35973242,
+ "digest": "sha256:2c1a5d89fff4404c8cd23a83dcf8f90cfe03df0d36dffc6745ff158eafcce6d6",
+ "download_count": 3,
+ "created_at": "2026-07-25T08:28:25Z",
+ "updated_at": "2026-07-25T08:30:09Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.0/v3.2.0-passcodes-app-x86_64.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/489297124",
+ "id": 489297124,
+ "node_id": "RA_kwDOMffp084dKhTk",
+ "name": "v3.2.0-passcodes-app-x86.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 36522285,
+ "digest": "sha256:ed625a04b538b1cc7ab96c1d31d271966f58f9ed1614cafe4b6c3b10db74f805",
+ "download_count": 2,
+ "created_at": "2026-07-25T08:30:09Z",
+ "updated_at": "2026-07-25T08:31:54Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.0/v3.2.0-passcodes-app-x86.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/489298056",
+ "id": 489298056,
+ "node_id": "RA_kwDOMffp084dKhiI",
+ "name": "v3.2.0-passcodes-app-armeabi_v7a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 28498441,
+ "digest": "sha256:e89d4627add31fa43b55f31a1a0de7ac79b00043a94bdf080830b7eee8576daa",
+ "download_count": 4,
+ "created_at": "2026-07-25T08:31:54Z",
+ "updated_at": "2026-07-25T08:33:01Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.0/v3.2.0-passcodes-app-armeabi_v7a.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/489298536",
+ "id": 489298536,
+ "node_id": "RA_kwDOMffp084dKhpo",
+ "name": "v3.2.0-passcodes-app-arm64_v8a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 35495399,
+ "digest": "sha256:6f469fd2bd98df14122890adb7bc6c51a4cb2f8961e5758b89ca767be88d9bd8",
+ "download_count": 42,
+ "created_at": "2026-07-25T08:33:01Z",
+ "updated_at": "2026-07-25T08:33:57Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.0/v3.2.0-passcodes-app-arm64_v8a.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/489316936",
+ "id": 489316936,
+ "node_id": "RA_kwDOMffp084dKmJI",
+ "name": "v3.1.0-passcodes-app-universal.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 94028923,
+ "digest": "sha256:fd2ffd3d4f77c2f76242be4208fd454de7ebd3259107690a2adb959bc6fb4cb1",
+ "download_count": 18,
+ "created_at": "2026-07-25T09:06:10Z",
+ "updated_at": "2026-07-25T09:10:27Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.2.0/v3.1.0-passcodes-app-universal.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v3.2.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v3.2.0",
+ "body": "\r\n\r\n> [!WARNING]\r\n> Please don;t universal APK to download from... Select platform specific file universal apk file has bug.\r\n> I by mistakely uploaded a old apk of v3.1.0 in this release.\r\n\r\n# What's Changed\r\n\r\n## 🌟 Highlights\r\n* Feat: Material UI & Improved UX by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/208\r\n\r\n## 🚀 New Features\r\n* Feat: Protect Credentials From Any Sort Of Screen Capture. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/201\r\n* Feat: Dark Mode Support by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/206\r\n* Feat: Pull To Refresh by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/209\r\n* Feat: Improve Navigation With Tabs by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/210\r\n* Chore: v3.2.0 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/212\r\n\r\n## 🐛 Bug Fixes\r\n* Perf: Optimize App. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/211\r\n\r\n## 📚 Documentation\r\n* Fix typos in README by @markoulinoss in https://github.com/PasscodesApp/Passcodes/pull/202\r\n\r\n## 📦 Dependency Updates\r\n* Chore: Upgrade To Expo SDK 57 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/207\r\n\r\n## Other Changes\r\n* Chore: v3.2.0 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/213\r\n\r\n## New Contributors\r\n* @markoulinoss made their first contribution in https://github.com/PasscodesApp/Passcodes/pull/202\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v3.1.0...v3.2.0",
+ "mentions_count": 2
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/343005811",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/343005811/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/343005811/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.1.0",
+ "id": 343005811,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084Ucdpz",
+ "tag_name": "v3.1.0",
+ "target_commitish": "main",
+ "name": "v3.1.0 - Stable",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-06-22T15:34:54Z",
+ "updated_at": "2026-06-22T17:28:16Z",
+ "published_at": "2026-06-22T17:28:16Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/454796901",
+ "id": 454796901,
+ "node_id": "RA_kwDOMffp084bG6Zl",
+ "name": "v3.1.0-passcodes-app-arm64_v8a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 21632993,
+ "digest": "sha256:dec089edb24953302715708d3e2a734606ef9e394324d758509e0c4c5d4af121",
+ "download_count": 20,
+ "created_at": "2026-06-22T17:21:27Z",
+ "updated_at": "2026-06-22T17:22:10Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.1.0/v3.1.0-passcodes-app-arm64_v8a.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/454797403",
+ "id": 454797403,
+ "node_id": "RA_kwDOMffp084bG6hb",
+ "name": "v3.1.0-passcodes-app-armeabi_v7a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 14981133,
+ "digest": "sha256:7b909869b209ddfa5ffadda750bdb5a99e782a525135ed0c48c1caa7f4517748",
+ "download_count": 3,
+ "created_at": "2026-06-22T17:22:11Z",
+ "updated_at": "2026-06-22T17:22:58Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.1.0/v3.1.0-passcodes-app-armeabi_v7a.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/454797905",
+ "id": 454797905,
+ "node_id": "RA_kwDOMffp084bG6pR",
+ "name": "v3.1.0-passcodes-app-universal.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 94028923,
+ "digest": "sha256:fd2ffd3d4f77c2f76242be4208fd454de7ebd3259107690a2adb959bc6fb4cb1",
+ "download_count": 40,
+ "created_at": "2026-06-22T17:22:58Z",
+ "updated_at": "2026-06-22T17:25:13Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.1.0/v3.1.0-passcodes-app-universal.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/454799566",
+ "id": 454799566,
+ "node_id": "RA_kwDOMffp084bG7DO",
+ "name": "v3.1.0-passcodes-app-x86.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 22660957,
+ "digest": "sha256:a1e762a45c53783c0931d96d7b56cf7d19a3993b80c24bd84db8741e5c7889d2",
+ "download_count": 2,
+ "created_at": "2026-06-22T17:25:13Z",
+ "updated_at": "2026-06-22T17:25:31Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.1.0/v3.1.0-passcodes-app-x86.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/454799731",
+ "id": 454799731,
+ "node_id": "RA_kwDOMffp084bG7Fz",
+ "name": "v3.1.0-passcodes-app-x86_64.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 22112159,
+ "digest": "sha256:ddf7fdc95dbe52bc3d8a012d65eb22818af07373fe1d5d5226ded3e809f4e552",
+ "download_count": 2,
+ "created_at": "2026-06-22T17:25:31Z",
+ "updated_at": "2026-06-22T17:25:50Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.1.0/v3.1.0-passcodes-app-x86_64.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v3.1.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v3.1.0",
+ "body": "\r\n\r\n## What's Changed\r\n\r\n## 🌟 Highlights\r\n- Feat: Biometrics Authenication by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/195\r\n- Feat: Import & Export To Google Passwords by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/199\r\n\r\n## 🚀 New Features\r\n- Feat: Add Update Passwords Functionality by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/187\r\n- Feat: Add Password Multi-Purpose Detail Screen by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/189\r\n- Feat: Improve DX by Development Builds & Splash Screen by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/190\r\n- Perf: Optimize Application Size & Performance by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/192\r\n- Feat: Better Screens Layouts by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/193\r\n- Feat: Data Recovery TroubleShooting & Keep Data Uninstall Prompt by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/194\r\n- Feat: Improve In App Lock by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/198\r\n\r\n## 🛠 Code Refactoring\r\n- Refactor: Extract Reusable Components & Improve Consistency by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/188\r\n- Refactor: Optimized towards Expo SDK 56. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/196\r\n\r\n## 📚 Documentation\r\n- Docs: Update Documentation by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/191\r\n- Chore: Prepare To Release `v3.1.0-Stable` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/200\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v3.0.0...v3.1.0\r\n",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/328505430",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/328505430/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/328505430/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.0.0",
+ "id": 328505430,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084TlJhW",
+ "tag_name": "v3.0.0",
+ "target_commitish": "main",
+ "name": "v3.0.0 - Alpha",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-05-24T13:28:54Z",
+ "updated_at": "2026-05-25T00:37:32Z",
+ "published_at": "2026-05-24T15:24:17Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/428618320",
+ "id": 428618320,
+ "node_id": "RA_kwDOMffp084ZjDJQ",
+ "name": "v3.0.0-passcodes-app-x86_64.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 21989282,
+ "digest": "sha256:50b1aa123723c89f1e600c4ea2ca8e5caa099c0aa65803055ac4d69768ef82e6",
+ "download_count": 2,
+ "created_at": "2026-05-24T15:11:15Z",
+ "updated_at": "2026-05-24T15:12:12Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.0.0/v3.0.0-passcodes-app-x86_64.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/428618733",
+ "id": 428618733,
+ "node_id": "RA_kwDOMffp084ZjDPt",
+ "name": "v3.0.0-passcodes-app-x86.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 21751648,
+ "digest": "sha256:a8784a4842a60012a0653bd09fe671bd427fdce1e1f54490f000b3496c571726",
+ "download_count": 2,
+ "created_at": "2026-05-24T15:12:12Z",
+ "updated_at": "2026-05-24T15:13:08Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.0.0/v3.0.0-passcodes-app-x86.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/428619166",
+ "id": 428619166,
+ "node_id": "RA_kwDOMffp084ZjDWe",
+ "name": "v3.0.0-passcodes-app-universal.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 94733651,
+ "digest": "sha256:8efd88f338b37add0320f658a9db6dfe0e8eef8880aa77d799c11aa5505ab14b",
+ "download_count": 53,
+ "created_at": "2026-05-24T15:13:08Z",
+ "updated_at": "2026-05-24T15:16:23Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.0.0/v3.0.0-passcodes-app-universal.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/428620353",
+ "id": 428620353,
+ "node_id": "RA_kwDOMffp084ZjDpB",
+ "name": "v3.0.0-passcodes-app-armeabi_v7a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 14219280,
+ "digest": "sha256:ff07c57d9c2b1421fd32a99fed61a2cc8318fb6d18aef1aab9a154d6c0b20df2",
+ "download_count": 3,
+ "created_at": "2026-05-24T15:16:23Z",
+ "updated_at": "2026-05-24T15:16:33Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.0.0/v3.0.0-passcodes-app-armeabi_v7a.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/428620415",
+ "id": 428620415,
+ "node_id": "RA_kwDOMffp084ZjDp_",
+ "name": "v3.0.0-passcodes-app-arm64_v8a.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 20645860,
+ "digest": "sha256:a51014d0521401568e3ddaac89a1433119a7604af1da21a8cefa5d72306ad8eb",
+ "download_count": 5,
+ "created_at": "2026-05-24T15:16:33Z",
+ "updated_at": "2026-05-24T15:17:18Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v3.0.0/v3.0.0-passcodes-app-arm64_v8a.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v3.0.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v3.0.0",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## 🌟 Highlights\r\n- Feat: Remake / Migrate Expo Ecosystem by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/173\r\n\r\n## 🚀 New Features\r\n- Chore: Update EAS config by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/184\r\n\r\n## 🐛 Bug Fixes\r\n- Fix: Dependencies & Remove CI by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/186\r\n\r\n## 📚 Documentation\r\n- Chore: Clean Up Repository by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/185\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v2.1.1...v3.0.0",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/325010130",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/325010130/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/325010130/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.1",
+ "id": 325010130,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084TX0LS",
+ "tag_name": "v2.1.1",
+ "target_commitish": "main",
+ "name": "v2.1.1 - Beta",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-05-19T13:26:45Z",
+ "updated_at": "2026-05-19T13:33:04Z",
+ "published_at": "2026-05-19T13:33:04Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219129",
+ "id": 424219129,
+ "node_id": "RA_kwDOMffp084ZSRH5",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2303,
+ "digest": "sha256:f803764265be0a37dcceaa2e30603965b7462b526a8a72dc1fc29285eef378fe",
+ "download_count": 2,
+ "created_at": "2026-05-19T13:32:16Z",
+ "updated_at": "2026-05-19T13:32:19Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219156",
+ "id": 424219156,
+ "node_id": "RA_kwDOMffp084ZSRIU",
+ "name": "v2.1.1-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5478132,
+ "digest": "sha256:11751a434edd930a558ef210ae20730793f18447784eba2c622c1b4ecca3430a",
+ "download_count": 6,
+ "created_at": "2026-05-19T13:32:19Z",
+ "updated_at": "2026-05-19T13:32:32Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/v2.1.1-passcodes-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219309",
+ "id": 424219309,
+ "node_id": "RA_kwDOMffp084ZSRKt",
+ "name": "v2.1.1-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5420694,
+ "digest": "sha256:ece89a6282b787b2446e07d991a435f45b8b8fd74cc8455ec028e60e6bdc87de",
+ "download_count": 2,
+ "created_at": "2026-05-19T13:32:32Z",
+ "updated_at": "2026-05-19T13:32:39Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/v2.1.1-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219399",
+ "id": 424219399,
+ "node_id": "RA_kwDOMffp084ZSRMH",
+ "name": "v2.1.1-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 9239174,
+ "digest": "sha256:d21a45f18f27157fa2b6a4b38f2fad3a136de36d1a4f074dc5601b503047a3e0",
+ "download_count": 23,
+ "created_at": "2026-05-19T13:32:39Z",
+ "updated_at": "2026-05-19T13:32:48Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/v2.1.1-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219467",
+ "id": 424219467,
+ "node_id": "RA_kwDOMffp084ZSRNL",
+ "name": "v2.1.1-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5388187,
+ "digest": "sha256:a35a5366a4e47a3e9b75bca7373019f0295e56672d4efad82d18cc5f734b67c7",
+ "download_count": 2,
+ "created_at": "2026-05-19T13:32:48Z",
+ "updated_at": "2026-05-19T13:32:53Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/v2.1.1-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/424219537",
+ "id": 424219537,
+ "node_id": "RA_kwDOMffp084ZSROR",
+ "name": "v2.1.1-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5327234,
+ "digest": "sha256:ca62823281734e0d7dd54bd745a826dbb69d4a0325d65df361dd4ccf0ea22942",
+ "download_count": 2,
+ "created_at": "2026-05-19T13:32:53Z",
+ "updated_at": "2026-05-19T13:32:58Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.1/v2.1.1-passcodes-app-x86-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v2.1.1",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v2.1.1",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## 🚀 New Features\r\n- Feat: Improve Styling With Material 3 Expressive by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/165\r\n- Feat: Improve Import/Export Password Feature by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/166\r\n- Chore: Update Version to v2.1.1 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/167\r\n\r\n## 🐛 Bug Fixes\r\n* Fix: Proguard R8 With Apache CSV Common Library by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/168\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v2.1.0...v2.1.1",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/321180228",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/321180228/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/321180228/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.0",
+ "id": 321180228,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084TJNJE",
+ "tag_name": "v2.1.0",
+ "target_commitish": "main",
+ "name": "v2.1.0 - Beta",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-05-12T13:52:43Z",
+ "updated_at": "2026-05-12T15:39:57Z",
+ "published_at": "2026-05-12T15:39:57Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418492562",
+ "id": 418492562,
+ "node_id": "RA_kwDOMffp084Y8bCS",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2303,
+ "digest": "sha256:eb484d122b49e423ab9353a1e7554094cc67a65b8411394fd6624921578559fe",
+ "download_count": 0,
+ "created_at": "2026-05-12T15:38:44Z",
+ "updated_at": "2026-05-12T15:38:47Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418492578",
+ "id": 418492578,
+ "node_id": "RA_kwDOMffp084Y8bCi",
+ "name": "v2.1.0-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5246990,
+ "digest": "sha256:f91c4f7a95a9eb171d09a5b4d0efa3fa33fbf939c12ca21aaef31a10928b358c",
+ "download_count": 3,
+ "created_at": "2026-05-12T15:38:47Z",
+ "updated_at": "2026-05-12T15:39:04Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/v2.1.0-passcodes-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418492825",
+ "id": 418492825,
+ "node_id": "RA_kwDOMffp084Y8bGZ",
+ "name": "v2.1.0-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5189552,
+ "digest": "sha256:524b3f87f06845f48a037ab59b53cbe2f36db360a3b22cc246a0049367ed6715",
+ "download_count": 2,
+ "created_at": "2026-05-12T15:39:04Z",
+ "updated_at": "2026-05-12T15:39:14Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/v2.1.0-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418492914",
+ "id": 418492914,
+ "node_id": "RA_kwDOMffp084Y8bHy",
+ "name": "v2.1.0-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 9008032,
+ "digest": "sha256:a7f0ffeeea01a25a692fbd8069d35c7d828cb93979287dd23ecf11543ba2afa3",
+ "download_count": 31,
+ "created_at": "2026-05-12T15:39:14Z",
+ "updated_at": "2026-05-12T15:39:26Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/v2.1.0-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418493087",
+ "id": 418493087,
+ "node_id": "RA_kwDOMffp084Y8bKf",
+ "name": "v2.1.0-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5157045,
+ "digest": "sha256:d02f12180702c8be5d69fd3c95da385cb60680f7605c98b541b6b2cc67907a3c",
+ "download_count": 2,
+ "created_at": "2026-05-12T15:39:26Z",
+ "updated_at": "2026-05-12T15:39:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/v2.1.0-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/418493206",
+ "id": 418493206,
+ "node_id": "RA_kwDOMffp084Y8bMW",
+ "name": "v2.1.0-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5096092,
+ "digest": "sha256:e95711a1843f2dd6446293b67cec60aa0a3b2e33fa5cdd19ea0c875b80cbde92",
+ "download_count": 2,
+ "created_at": "2026-05-12T15:39:34Z",
+ "updated_at": "2026-05-12T15:39:45Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.1.0/v2.1.0-passcodes-app-x86-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v2.1.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v2.1.0",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## 🌟 Highlights\r\n- Feat: End Of Support Dialog by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/150\r\n\r\n## 🚀 New Features\r\n- Feat: Improve OldUI View Password Screen by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/132\r\n- Feat: Improve Update Checking by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/133\r\n- Feat: Linking (URL) Features by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/135\r\n- Feat: Supports For Android 17 (API 37). by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/149\r\n- Chore: Ready To Release v2.1.0 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/152\r\n\r\n## 🐛 Bug Fixes\r\n- Fix: Back Navigation Gesture Problems With Preview Layout by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/131\r\n- Fix: Dialog Overseen When Biometrics Are Disabled by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/151\r\n\r\n## 📚 Documentation\r\n- Docs: Update Changelog.md by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/158\r\n\r\n## 📦 Dependency Updates\r\n- chore(deps): bump androidx.biometric:biometric from 1.2.0-alpha05 to 1.4.0-alpha06 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/134\r\n- chore(deps): bump ktor from 3.4.2 to 3.4.3 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/138\r\n- chore(deps): bump kotlin from 2.3.20 to 2.3.21 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/139\r\n- chore(deps): bump androidx.biometric:biometric from 1.4.0-alpha06 to 1.4.0-alpha07 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/140\r\n- chore(deps): bump androidx.compose:compose-bom from 2026.03.01 to 2026.04.01 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/141\r\n- chore(deps): bump nav3Core from 1.1.0 to 1.1.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/137\r\n- Chore(deps): Update Dependencies. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/143\r\n- chore(deps): bump com.google.devtools.ksp from 2.3.6 to 2.3.7 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/147\r\n- chore(deps): bump gradle-wrapper from 9.4.1 to 9.5.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/146\r\n- chore(deps): bump agp from 9.1.1 to 9.2.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/145\r\n- chore(deps): bump com.google.android.gms:play-services-oss-licenses from 17.5.0 to 17.5.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/144\r\n- Chore(deps): Update All Dependency To Latest... by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/148\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v2.0.0...v2.1.0\r\n",
+ "mentions_count": 2
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/309636643",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/309636643/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/309636643/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0",
+ "id": 309636643,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084SdK4j",
+ "tag_name": "v2.0.0",
+ "target_commitish": "main",
+ "name": "v2.0.0 - Beta",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-04-16T02:43:20Z",
+ "updated_at": "2026-04-16T05:31:40Z",
+ "published_at": "2026-04-16T05:31:40Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397544848",
+ "id": 397544848,
+ "node_id": "RA_kwDOMffp084Xsg2Q",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2303,
+ "digest": "sha256:f578a4cdfd373b677fd002b5cb13e45788d3b726f0607c4bcdebbb71a0ab1ce8",
+ "download_count": 0,
+ "created_at": "2026-04-16T05:30:03Z",
+ "updated_at": "2026-04-16T05:30:04Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397544854",
+ "id": 397544854,
+ "node_id": "RA_kwDOMffp084Xsg2W",
+ "name": "v2.0.0-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5135246,
+ "digest": "sha256:2f02e50a975efca89c26ba0ff92f936092f64f272ab1085d3e566360c53d14bb",
+ "download_count": 2,
+ "created_at": "2026-04-16T05:30:04Z",
+ "updated_at": "2026-04-16T05:30:19Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/v2.0.0-passcodes-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397544975",
+ "id": 397544975,
+ "node_id": "RA_kwDOMffp084Xsg4P",
+ "name": "v2.0.0-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5077808,
+ "digest": "sha256:f1e724b00cf3ffa7fe464bdccd4b13fa9d01104468c4da2f0571f72afddf01c3",
+ "download_count": 2,
+ "created_at": "2026-04-16T05:30:19Z",
+ "updated_at": "2026-04-16T05:30:32Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/v2.0.0-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397545068",
+ "id": 397545068,
+ "node_id": "RA_kwDOMffp084Xsg5s",
+ "name": "v2.0.0-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 8896288,
+ "digest": "sha256:dfab49db784b90093f7f97a1df14ca48604434d6da88d369a51dac258de6b67d",
+ "download_count": 34,
+ "created_at": "2026-04-16T05:30:32Z",
+ "updated_at": "2026-04-16T05:30:55Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/v2.0.0-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397545238",
+ "id": 397545238,
+ "node_id": "RA_kwDOMffp084Xsg8W",
+ "name": "v2.0.0-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 5045301,
+ "digest": "sha256:091c566369daa102e29ffc1c17178c2a0e1ef3e8ff04de1d20295601a41820ee",
+ "download_count": 2,
+ "created_at": "2026-04-16T05:30:55Z",
+ "updated_at": "2026-04-16T05:31:10Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/v2.0.0-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/397545338",
+ "id": 397545338,
+ "node_id": "RA_kwDOMffp084Xsg96",
+ "name": "v2.0.0-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4984348,
+ "digest": "sha256:383a20ddd41771f8e65e4456046079732ea041fc9b96a6165b59ed2655f16821",
+ "download_count": 2,
+ "created_at": "2026-04-16T05:31:10Z",
+ "updated_at": "2026-04-16T05:31:23Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v2.0.0/v2.0.0-passcodes-app-x86-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v2.0.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v2.0.0",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## 🌟 Highlights\r\n- Feat: Biometric Authentication by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/123\r\n\r\n## 🚀 New Features\r\n- Feat: Add Scaffolding Code That Support Dual Navigation. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/92\r\n- Fix: Finally... Autofill service. #44 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/99\r\n- Feat: Made Basic Functioning Classical & Modern Layout For All Screens by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/103\r\n- Feat: Streamline Oldui & Newui Exchange. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/106\r\n- Feat: Made a Design System in Compose Multiplatform. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/109\r\n- Feat: Migrate the Database to v2. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/114\r\n- Feat: Improve Autofill Service. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/122\r\n\r\n## 🐛 Bug Fixes\r\n- Fix: Autofill Service. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/97\r\n- Fix: Updating App Losses Data by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/125\r\n\r\n## 🛠 Code Refactoring\r\n- Refactor(Fix): Preview Screens in Android Studio. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/105\r\n- Refactor: Migrate Database Module to KMP Library Module (Finally 😮💨) by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/124\r\n- Refactor: `OkHttp` -> `Ktor` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/126\r\n- Refactor: Settings Screen by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/127\r\n\r\n## 📚 Documentation\r\n- Docs: Update The Presentaion & Documentaion by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/101\r\n- Docs: Update Changelog.md by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/128\r\n- Chore/CI: Improve Release Notes Generation. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/130\r\n\r\n## 📦 Dependency Updates\r\n- Chore: Improve Security by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/89\r\n- chore(deps): bump kotlin from 2.3.0 to 2.3.10 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/90\r\n- chore(deps): bump com.google.android.gms:play-services-oss-licenses from 17.3.0 to 17.4.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/91\r\n- chore(deps): bump androidx.compose:compose-bom from 2026.01.01 to 2026.02.00 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/96\r\n- chore(deps): bump androidx.activity:activity-compose from 1.12.3 to 1.12.4 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/95\r\n- chore(deps): bump nav3Core from 1.0.0 to 1.0.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/94\r\n- chore(deps): bump agp from 9.0.0 to 9.0.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/93\r\n- chore(deps): bump com.google.devtools.ksp from 2.3.5 to 2.3.6 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/102\r\n- chore(deps): bump androidx.compose:compose-bom from 2026.02.00 to 2026.02.01 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/104\r\n- chore(deps): bump agp from 9.0.1 to 9.1.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/108\r\n- chore(deps): bump gradle-wrapper from 9.3.1 to 9.4.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/107\r\n- chore(deps): bump androidx.activity:activity-compose from 1.12.4 to 1.13.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/113\r\n- chore(deps): bump androidx.core:core-ktx from 1.17.0 to 1.18.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/112\r\n- chore(deps): bump androidx.datastore:datastore-preferences from 1.2.0 to 1.2.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/111\r\n- chore(deps): bump androidx.compose:compose-bom from 2026.02.01 to 2026.03.00 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/110\r\n- chore(deps): bump com.google.android.gms.oss-licenses-plugin from 0.10.10 to 0.11.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/116\r\n- chore(deps): bump com.google.android.gms:oss-licenses-plugin from 0.10.10 to 0.11.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/117\r\n- chore(deps): bump koin from 4.1.1 to 4.2.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/119\r\n- chore(deps): bump kotlin from 2.3.10 to 2.3.20 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/115\r\n- chore(deps): bump gradle-wrapper from 9.4.0 to 9.4.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/118\r\n- chore(deps): bump org.jetbrains.compose from 1.10.2 to 1.10.3 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/120\r\n- chore(deps): bump androidx.compose:compose-bom from 2026.03.00 to 2026.03.01 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/121\r\n\r\n## Other Changes\r\n- CI: Improve CI/CD Pipeline & CodeQL. by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/98\r\n- CI(Fix): Improve Workflow @github/codeql-action by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/100\r\n- Chore: Prepare For `v2.0.0-Beta` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/129\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.2.1...v2.0.0",
+ "mentions_count": 2
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/281809735",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/281809735/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/281809735/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1",
+ "id": 281809735,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084QzBNH",
+ "tag_name": "v1.2.1",
+ "target_commitish": "main",
+ "name": "v1.2.1 - Alpha",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2026-01-31T16:54:29Z",
+ "updated_at": "2026-05-26T12:21:37Z",
+ "published_at": "2026-01-31T17:33:10Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348708970",
+ "id": 348708970,
+ "node_id": "RA_kwDOMffp084UyOBq",
+ "name": "v1.2.1-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3580766,
+ "digest": "sha256:7d6d2fda0590d0530b44235f8cac3358a13bc010a4cc3e62351c8f0847327018",
+ "download_count": 1,
+ "created_at": "2026-01-31T17:17:12Z",
+ "updated_at": "2026-01-31T17:17:31Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/v1.2.1-passcodes-app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348709114",
+ "id": 348709114,
+ "node_id": "RA_kwDOMffp084UyOD6",
+ "name": "v1.2.1-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3581760,
+ "digest": "sha256:9a192137949614e777fbeed8edfd789f1609d1b87c7120bce6be7a6ba5374c1f",
+ "download_count": 1,
+ "created_at": "2026-01-31T17:17:31Z",
+ "updated_at": "2026-01-31T17:17:44Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/v1.2.1-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348709214",
+ "id": 348709214,
+ "node_id": "RA_kwDOMffp084UyOFe",
+ "name": "v1.2.1-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3828046,
+ "digest": "sha256:7f38b31305f60379ee15e35f130913c30f6c9e0438d4c22efe86423c054b8319",
+ "download_count": 40,
+ "created_at": "2026-01-31T17:17:44Z",
+ "updated_at": "2026-01-31T17:17:54Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/v1.2.1-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348709376",
+ "id": 348709376,
+ "node_id": "RA_kwDOMffp084UyOIA",
+ "name": "v1.2.1-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3581342,
+ "digest": "sha256:c5c88e2a7c1c0853ad42d7dea68590a24622f76c92da87f8605e8129c49990ff",
+ "download_count": 1,
+ "created_at": "2026-01-31T17:17:54Z",
+ "updated_at": "2026-01-31T17:18:06Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/v1.2.1-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348709520",
+ "id": 348709520,
+ "node_id": "RA_kwDOMffp084UyOKQ",
+ "name": "v1.2.1-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3582230,
+ "digest": "sha256:193bb3e2ac089691cccf31e772b7f44095d392b740bb98a2d257916294440b5a",
+ "download_count": 5,
+ "created_at": "2026-01-31T17:18:06Z",
+ "updated_at": "2026-01-31T17:18:20Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/v1.2.1-passcodes-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348709724",
+ "id": 348709724,
+ "node_id": "RA_kwDOMffp084UyONc",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2308,
+ "digest": "sha256:fe4b8831094e9d95c204ffd7512b21b372af6b29cc4dae1cd435b7cda8c91cc6",
+ "download_count": 0,
+ "created_at": "2026-01-31T17:18:20Z",
+ "updated_at": "2026-01-31T17:18:21Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.1/output-metadata.json"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.2.1",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.2.1",
+ "body": "> [!note]\r\n> SORRY!!!!\r\n> Last time, I forget to update the version name and version number in downloadable app assets...... \r\n> Such silly mistake happens when we try to chase a deadline...\r\n> \r\n> Anyways, here is a new release/patch for it. The last release is still their but it will be a [yanked release](https://passcodesapp.github.io/Passcodes-Docs/user-docs/installing/?h=yank#explicitly-yanked-release-pure-trash) from here on...\r\n>\r\n> Don't use that release ([v1.2.0](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0)) in any case.... always prefer this release over that... because it will create confusion in bug reports like if you use that release and a bug occur... you will not be able to tell whether you are on previous release ([v1.1.2](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2)) or new release ([v1.2.0](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0))... due to same version number in two different release.... I admit it our mistake and I am SORRY!!!!\r\n\r\nChangeLog: https://github.com/PasscodesApp/Passcodes/compare/v1.1.2...v1.2.1\r\n\r\n---\r\n\r\n\r\n\r\n# What's Changed\r\n## 🌟 Highlights\r\n* chore: update the version name & number by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/84\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.2.0...v1.2.1",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/280302128",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/280302128/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/280302128/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0",
+ "id": 280302128,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084QtRIw",
+ "tag_name": "v1.2.0",
+ "target_commitish": "main",
+ "name": "v1.2.0 - Alpha [YANKED RELEASE]",
+ "draft": false,
+ "immutable": true,
+ "prerelease": true,
+ "created_at": "2026-01-30T16:50:16Z",
+ "updated_at": "2026-05-26T12:21:59Z",
+ "published_at": "2026-01-31T16:10:44Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689295",
+ "id": 348689295,
+ "node_id": "RA_kwDOMffp084UyJOP",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2308,
+ "digest": "sha256:80dc141eea32cec0e1fa9d3a2707991a968066728ba3a5e45e9861815979c619",
+ "download_count": 0,
+ "created_at": "2026-01-31T16:08:10Z",
+ "updated_at": "2026-01-31T16:08:13Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689302",
+ "id": 348689302,
+ "node_id": "RA_kwDOMffp084UyJOW",
+ "name": "v1.2.0-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3580766,
+ "digest": "sha256:7b3727abb5123e86c781a90c0e38df887ecfe20910c6e1ddc835b7ff39d261df",
+ "download_count": 3,
+ "created_at": "2026-01-31T16:08:13Z",
+ "updated_at": "2026-01-31T16:10:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/v1.2.0-passcodes-app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689322",
+ "id": 348689322,
+ "node_id": "RA_kwDOMffp084UyJOq",
+ "name": "v1.2.0-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3581342,
+ "digest": "sha256:f2cbff3efc0efe9bd04ebb63558cce77da5a31b988caac0006967cc8e87d210b",
+ "download_count": 1,
+ "created_at": "2026-01-31T16:08:26Z",
+ "updated_at": "2026-01-31T16:10:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/v1.2.0-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689345",
+ "id": 348689345,
+ "node_id": "RA_kwDOMffp084UyJPB",
+ "name": "v1.2.0-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3581760,
+ "digest": "sha256:5d0df9473ad335261df566da4d01d8a457ad14c6385c1ebfeb461c789274d767",
+ "download_count": 1,
+ "created_at": "2026-01-31T16:08:35Z",
+ "updated_at": "2026-01-31T16:10:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/v1.2.0-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689364",
+ "id": 348689364,
+ "node_id": "RA_kwDOMffp084UyJPU",
+ "name": "v1.2.0-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3828046,
+ "digest": "sha256:1e1495d5ba860091f1e322d032222637f3b970e22463fb3ae966862f9f86e583",
+ "download_count": 7,
+ "created_at": "2026-01-31T16:08:44Z",
+ "updated_at": "2026-01-31T16:10:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/v1.2.0-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/348689397",
+ "id": 348689397,
+ "node_id": "RA_kwDOMffp084UyJP1",
+ "name": "v1.2.0-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3582230,
+ "digest": "sha256:1fe1c8afc011c9e880c971ccf8d927f22f2b83cb8bd7b947703aea92e0a9ae26",
+ "download_count": 1,
+ "created_at": "2026-01-31T16:08:52Z",
+ "updated_at": "2026-01-31T16:10:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.2.0/v1.2.0-passcodes-app-arm64-v8a-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.2.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.2.0",
+ "body": "> [!important]\r\n> Sorry, This release must not be use In any cases... always, use [v1.2.1](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1) instead.\r\n> I forget to update the version name and version number in the downloadable assets... so this is an Yanked release...\r\n>\r\n> Don't use this release ([v1.2.0](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0)) in any case.... always prefer [that release (v1.2.1)](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.1) over this... because it will create confusion in bug reports like if you use this release and a bug occur... you will not be able to tell whether you are on previous release ([v1.1.2](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2)) or this release ([v1.2.0](https://github.com/PasscodesApp/Passcodes/releases/tag/v1.2.0))... due to same version number in two different release.... \r\n>\r\n> AGAIN VERY SORRY FOR IT >>> it just happened....\r\n\r\n\r\n\r\n# What's Changed\r\n\r\n## 🌟 Highlights\r\n- Feat: Designing New Jetpack Compose (Preview UI) by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/76\r\n\r\n## 🐛 Bug Fixes\r\n- Fix: Import Mimetypes by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/81\r\n\r\n## 📦 Dependency Updates\r\n- chore(deps): bump org.json:json from 20250517 to 20251224 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/75\r\n- chore(deps): bump androidx.compose:compose-bom from 2025.12.00 to 2025.12.01 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/74\r\n- chore(deps): bump com.google.devtools.ksp from 2.3.3 to 2.3.4 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/73\r\n- chore(deps): bump kotlin from 2.2.21 to 2.3.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/71\r\n- chore(deps): bump androidx.activity:activity-compose from 1.12.1 to 1.12.2 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/72\r\n- chore(deps): bump androidx.compose:compose-bom from 2025.12.01 to 2026.01.00 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/77\r\n- chore(deps): bump org.jetbrains.kotlinx:kotlinx-serialization-json from 1.9.0 to 1.10.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/80\r\n- chore(deps): bump agp from 8.13.2 to 9.0.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/78\r\n- chore(deps): bump gradle-wrapper from 9.2.0 to 9.3.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/79\r\n\r\n## Other Changes\r\n- CI: Optimise The CI/CD (ubuntu-slim) by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/82\r\n- Revert \"CI: Optimise The CI/CD (ubuntu-slim)\" by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/83\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.1.2...v1.2.0\r\n",
+ "mentions_count": 2
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/270362933",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/270362933/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/270362933/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.2",
+ "id": 270362933,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084QHWk1",
+ "tag_name": "v1.1.2",
+ "target_commitish": "main",
+ "name": "v1.1.2 - Alpha",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2025-12-15T06:54:41Z",
+ "updated_at": "2026-05-26T12:22:15Z",
+ "published_at": "2025-12-15T11:40:06Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876161",
+ "id": 328876161,
+ "node_id": "RA_kwDOMffp084TmkCB",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2308,
+ "digest": "sha256:9959a107729ad81c14f44b1ac425aaf36d1d6e221091802f7d328d4edcb6e059",
+ "download_count": 1,
+ "created_at": "2025-12-15T11:36:46Z",
+ "updated_at": "2025-12-15T11:36:48Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876168",
+ "id": 328876168,
+ "node_id": "RA_kwDOMffp084TmkCI",
+ "name": "v1.1.1-passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3559575,
+ "digest": "sha256:df28e78a41000406aef1cedc0c3521c8ec058712d135e0f5078ec41ffee61a43",
+ "download_count": 3,
+ "created_at": "2025-12-15T11:36:48Z",
+ "updated_at": "2025-12-15T11:36:59Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/v1.1.1-passcodes-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876222",
+ "id": 328876222,
+ "node_id": "RA_kwDOMffp084TmkC-",
+ "name": "v1.1.1-passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3558687,
+ "digest": "sha256:65de370ae0ef298236418f34c931e9b9205daf9352f4a787275182c3c3aa7595",
+ "download_count": 3,
+ "created_at": "2025-12-15T11:36:59Z",
+ "updated_at": "2025-12-15T11:37:03Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/v1.1.1-passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876235",
+ "id": 328876235,
+ "node_id": "RA_kwDOMffp084TmkDL",
+ "name": "v1.1.1-passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3805391,
+ "digest": "sha256:c1e84ad16dba00cc8114b42174ba940b402e83b515ddbad822dda3719705a096",
+ "download_count": 34,
+ "created_at": "2025-12-15T11:37:03Z",
+ "updated_at": "2025-12-15T11:37:06Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/v1.1.1-passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876252",
+ "id": 328876252,
+ "node_id": "RA_kwDOMffp084TmkDc",
+ "name": "v1.1.1-passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3559105,
+ "digest": "sha256:e82d72b5580ce8b885c78f1f259c2527eeb98cf73d2028320b76838e36514239",
+ "download_count": 4,
+ "created_at": "2025-12-15T11:37:06Z",
+ "updated_at": "2025-12-15T11:37:09Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/v1.1.1-passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/328876288",
+ "id": 328876288,
+ "node_id": "RA_kwDOMffp084TmkEA",
+ "name": "v1.1.1-passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3558111,
+ "digest": "sha256:c1e91d1d2848c5826f31ad7649b19ea5bb1e9a502585ca6bb5b9afb36ec1fcf5",
+ "download_count": 4,
+ "created_at": "2025-12-15T11:37:09Z",
+ "updated_at": "2025-12-15T11:37:13Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.2/v1.1.1-passcodes-app-x86-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.1.2",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.1.2",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## Highlights 🌟\r\n- ✨✨ Preview: Jetpack Compose ✨✨ by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/51\r\n- Migration: Clean Architecture by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/53\r\n\r\n## New Features 🚀\r\n- Feat: Autofill Service by @hexCode63 in https://github.com/PasscodesApp/Passcodes/pull/41\r\n- Chore/Feat: Disable copy password button based on feature flag by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/50\r\n\r\n## Documentation 📚\r\n- Docs: migrate the docs to the repository `PasscodesApp/Passcodes-Docs` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/39\r\n\r\n## Other Changes\r\n- Refactor: kind of MVC -> `MVVM` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/43\r\n- Refactor: `MVVM` -> `MVI` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/45\r\n- Chore: Update the Entire Project Dependency & Quality by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/46\r\n- Chore: the workflow now run on `Java 21` now... 😏 by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/47\r\n- Chore: Add Java setup for CodeQL workflow by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/48\r\n- Chore: Set package-ecosystem to 'gradle' in dependabot.yml by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/49\r\n- Refactor: Shared-Preference -> DataStore-Preference by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/52\r\n- chore(deps): bump room from 2.8.3 to 2.8.4 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/54\r\n- chore(deps): bump androidx.compose.material3.adaptive:adaptive-navigation3 from 1.3.0-alpha03 to 1.3.0-alpha04 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/55\r\n- chore(deps): bump nav3Core from 1.0.0-rc01 to 1.0.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/60\r\n- chore(deps): bump androidx.activity:activity-compose from 1.11.0 to 1.12.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/58\r\n- chore(deps): bump lifecycle from 2.9.4 to 2.10.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/57\r\n- chore(deps): bump androidx.datastore:datastore-preferences from 1.1.7 to 1.2.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/59\r\n- chore(deps): bump androidx.lifecycle:lifecycle-viewmodel-compose from 2.9.4 to 2.10.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/56\r\n- CI: update dependabot configuration for gradle by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/61\r\n- chore(deps): bump androidx.lifecycle:lifecycle-viewmodel-navigation3 from 2.10.0-rc01 to 2.10.0 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/63\r\n- chore(deps): bump androidx.activity:activity-compose from 1.12.0 to 1.12.1 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/66\r\n- chore(deps): bump com.google.devtools.ksp from 2.3.2 to 2.3.3 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/65\r\n- chore(deps): bump androidx.compose.material3.adaptive:adaptive-navigation3 from 1.3.0-alpha04 to 1.3.0-alpha05 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/62\r\n- chore(deps): bump androidx.compose:compose-bom from 2025.11.00 to 2025.12.00 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/64\r\n- chore(deps): bump agp from 8.13.1 to 8.13.2 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/67\r\n- chore(deps): bump com.google.android.gms:oss-licenses-plugin from 0.10.9 to 0.10.10 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/68\r\n- chore(deps): bump com.google.android.gms.oss-licenses-plugin from 0.10.9 to 0.10.10 by @dependabot[bot] in https://github.com/PasscodesApp/Passcodes/pull/69\r\n- Chore(deps): Update AGP & Oss License Plugin To Thier Latest Version by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/70\r\n\r\n# New Contributors\r\n- @hexCode63 made their first contribution in https://github.com/PasscodesApp/Passcodes/pull/41\r\n- @dependabot[bot] made their first contribution in https://github.com/PasscodesApp/Passcodes/pull/54\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.1.1...v1.1.2",
+ "reactions": {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/270362933/reactions",
+ "total_count": 2,
+ "+1": 0,
+ "-1": 0,
+ "laugh": 0,
+ "hooray": 2,
+ "confused": 0,
+ "heart": 0,
+ "rocket": 0,
+ "eyes": 0
+ },
+ "mentions_count": 3
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/246203171",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/246203171/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/246203171/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.1",
+ "id": 246203171,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084OrMMj",
+ "tag_name": "v1.1.1",
+ "target_commitish": "main",
+ "name": "v1.1.1 - Alpha",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2025-09-11T01:47:20Z",
+ "updated_at": "2026-05-26T12:22:40Z",
+ "published_at": "2025-09-11T01:59:28Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774294",
+ "id": 291774294,
+ "node_id": "RA_kwDOMffp084RZB9W",
+ "name": "app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101486,
+ "digest": "sha256:7ec6fb3c60b6f5b3f7844ba7fa7a386825b9d35faaae7eff833b8f41022c7c7d",
+ "download_count": 3,
+ "created_at": "2025-09-10T14:44:01Z",
+ "updated_at": "2025-09-10T14:44:11Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774326",
+ "id": 291774326,
+ "node_id": "RA_kwDOMffp084RZB92",
+ "name": "app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101486,
+ "digest": "sha256:7ec6fb3c60b6f5b3f7844ba7fa7a386825b9d35faaae7eff833b8f41022c7c7d",
+ "download_count": 3,
+ "created_at": "2025-09-10T14:44:11Z",
+ "updated_at": "2025-09-10T14:44:18Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774366",
+ "id": 291774366,
+ "node_id": "RA_kwDOMffp084RZB-e",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2308,
+ "digest": "sha256:0b3f5afc16c539d04e69879778738de48599201868df66c76027c5ed88c94a93",
+ "download_count": 1,
+ "created_at": "2025-09-10T14:44:18Z",
+ "updated_at": "2025-09-10T14:44:19Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774370",
+ "id": 291774370,
+ "node_id": "RA_kwDOMffp084RZB-i",
+ "name": "app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101486,
+ "digest": "sha256:7ec6fb3c60b6f5b3f7844ba7fa7a386825b9d35faaae7eff833b8f41022c7c7d",
+ "download_count": 6,
+ "created_at": "2025-09-10T14:44:19Z",
+ "updated_at": "2025-09-10T14:44:34Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774424",
+ "id": 291774424,
+ "node_id": "RA_kwDOMffp084RZB_Y",
+ "name": "app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101486,
+ "digest": "sha256:7ec6fb3c60b6f5b3f7844ba7fa7a386825b9d35faaae7eff833b8f41022c7c7d",
+ "download_count": 5,
+ "created_at": "2025-09-10T14:44:34Z",
+ "updated_at": "2025-09-10T14:44:46Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/291774518",
+ "id": 291774518,
+ "node_id": "RA_kwDOMffp084RZCA2",
+ "name": "app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101486,
+ "digest": "sha256:7ec6fb3c60b6f5b3f7844ba7fa7a386825b9d35faaae7eff833b8f41022c7c7d",
+ "download_count": 38,
+ "created_at": "2025-09-10T14:44:46Z",
+ "updated_at": "2025-09-10T14:44:54Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.1/app-universal-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.1.1",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.1.1",
+ "body": "# What's Changed\r\n\r\n## Bug Fixes 🐛\r\n- Fix: Incorrect Mime Type For CSV by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/38\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.1.0...v1.1.1",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/243916870",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/243916870/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/243916870/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.1.0",
+ "id": 243916870,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084OieBG",
+ "tag_name": "v1.1.0",
+ "target_commitish": "main",
+ "name": "v1.1.0 - Alpha",
+ "draft": false,
+ "immutable": true,
+ "prerelease": true,
+ "created_at": "2025-09-01T15:32:45Z",
+ "updated_at": "2026-05-26T12:23:05Z",
+ "published_at": "2025-09-01T15:52:19Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473213",
+ "id": 288473213,
+ "node_id": "RA_kwDOMffp084RMcB9",
+ "name": "app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101478,
+ "digest": "sha256:dd5b773d47dfd54d10777ea7caa327e451d504a2f43e240829b235da726fceb5",
+ "download_count": 16,
+ "created_at": "2025-09-01T15:49:31Z",
+ "updated_at": "2025-09-01T15:51:07Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473626",
+ "id": 288473626,
+ "node_id": "RA_kwDOMffp084RMcIa",
+ "name": "app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101478,
+ "digest": "sha256:dd5b773d47dfd54d10777ea7caa327e451d504a2f43e240829b235da726fceb5",
+ "download_count": 3,
+ "created_at": "2025-09-01T15:51:07Z",
+ "updated_at": "2025-09-01T15:51:32Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473698",
+ "id": 288473698,
+ "node_id": "RA_kwDOMffp084RMcJi",
+ "name": "app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101478,
+ "digest": "sha256:dd5b773d47dfd54d10777ea7caa327e451d504a2f43e240829b235da726fceb5",
+ "download_count": 5,
+ "created_at": "2025-09-01T15:51:32Z",
+ "updated_at": "2025-09-01T15:51:36Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473716",
+ "id": 288473716,
+ "node_id": "RA_kwDOMffp084RMcJ0",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2308,
+ "digest": "sha256:23f8095a1ed6b2249beba53415e1cdba4a38cc17ca00b44e48f8511a00b4d871",
+ "download_count": 1,
+ "created_at": "2025-09-01T15:51:36Z",
+ "updated_at": "2025-09-01T15:51:37Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473719",
+ "id": 288473719,
+ "node_id": "RA_kwDOMffp084RMcJ3",
+ "name": "app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101478,
+ "digest": "sha256:dd5b773d47dfd54d10777ea7caa327e451d504a2f43e240829b235da726fceb5",
+ "download_count": 3,
+ "created_at": "2025-09-01T15:51:37Z",
+ "updated_at": "2025-09-01T15:51:40Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/288473729",
+ "id": 288473729,
+ "node_id": "RA_kwDOMffp084RMcKB",
+ "name": "app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 3101478,
+ "digest": "sha256:dd5b773d47dfd54d10777ea7caa327e451d504a2f43e240829b235da726fceb5",
+ "download_count": 3,
+ "created_at": "2025-09-01T15:51:40Z",
+ "updated_at": "2025-09-01T15:51:42Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.1.0/app-armeabi-v7a-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.1.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.1.0",
+ "body": "\r\n\r\n# What's Changed\r\n\r\n## Highlights 🌟\r\n- Feat: Add Update Checker & Import Export Compatibility With Google Passwords by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/36\r\n\r\n## New Features 🚀\r\n- Feat: Improve UI/UX by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/30\r\n- Feat: Add Copy Password Functionality by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/31\r\n- Feat: Implement Feature Flagging by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/33\r\n- Feat: Import/Export Password Functionality by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/35\r\n\r\n## Documentation 📚\r\n- Feat: Prepare For Release `v1.1.0 - Alpha` by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/37\r\n\r\n## Other Changes\r\n- CI/CD: Fix Issue With Apk Sign Properties by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/32\r\n- Refactor: Made Utils For Common Stuff by @JeelDobariya38 in https://github.com/PasscodesApp/Passcodes/pull/34\r\n\r\n\r\n**Full Changelog**: https://github.com/PasscodesApp/Passcodes/compare/v1.0.0...v1.1.0",
+ "mentions_count": 1
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/240385777",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/240385777/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/240385777/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0",
+ "id": 240385777,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084OU_7x",
+ "tag_name": "v1.0.0",
+ "target_commitish": "main",
+ "name": "v1.0.0 - Stable",
+ "draft": false,
+ "immutable": true,
+ "prerelease": false,
+ "created_at": "2025-08-16T17:23:16Z",
+ "updated_at": "2026-05-26T12:23:49Z",
+ "published_at": "2025-08-16T18:29:16Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166489",
+ "id": 283166489,
+ "node_id": "RA_kwDOMffp084Q4McZ",
+ "name": "passcodes-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 2813036,
+ "digest": "sha256:ddf662d0f738e565602f32d44bc6cc2e0076f702d52e62d17e8613296db44c43",
+ "download_count": 5,
+ "created_at": "2025-08-16T17:36:44Z",
+ "updated_at": "2025-08-16T17:36:55Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/passcodes-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166499",
+ "id": 283166499,
+ "node_id": "RA_kwDOMffp084Q4Mcj",
+ "name": "passcodes-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 2813036,
+ "digest": "sha256:ddf662d0f738e565602f32d44bc6cc2e0076f702d52e62d17e8613296db44c43",
+ "download_count": 40,
+ "created_at": "2025-08-16T17:36:55Z",
+ "updated_at": "2025-08-16T17:37:03Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/passcodes-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166517",
+ "id": 283166517,
+ "node_id": "RA_kwDOMffp084Q4Mc1",
+ "name": "passcodes-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 2813036,
+ "digest": "sha256:ddf662d0f738e565602f32d44bc6cc2e0076f702d52e62d17e8613296db44c43",
+ "download_count": 7,
+ "created_at": "2025-08-16T17:37:03Z",
+ "updated_at": "2025-08-16T17:37:10Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/passcodes-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166536",
+ "id": 283166536,
+ "node_id": "RA_kwDOMffp084Q4MdI",
+ "name": "passcodes-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 2813036,
+ "digest": "sha256:ddf662d0f738e565602f32d44bc6cc2e0076f702d52e62d17e8613296db44c43",
+ "download_count": 6,
+ "created_at": "2025-08-16T17:37:10Z",
+ "updated_at": "2025-08-16T17:37:15Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/passcodes-app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166546",
+ "id": 283166546,
+ "node_id": "RA_kwDOMffp084Q4MdS",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 2313,
+ "digest": "sha256:65e522ecafcb5160dcc3ddbf7eb8b666b017c7bf7324c6007932e11331010c86",
+ "download_count": 1,
+ "created_at": "2025-08-16T17:37:15Z",
+ "updated_at": "2025-08-16T17:37:15Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/output-metadata.json"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/283166547",
+ "id": 283166547,
+ "node_id": "RA_kwDOMffp084Q4MdT",
+ "name": "passcodes-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 2813036,
+ "digest": "sha256:ddf662d0f738e565602f32d44bc6cc2e0076f702d52e62d17e8613296db44c43",
+ "download_count": 7,
+ "created_at": "2025-08-16T17:37:15Z",
+ "updated_at": "2025-08-16T17:37:20Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v1.0.0/passcodes-app-arm64-v8a-release.apk"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v1.0.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v1.0.0",
+ "body": "# What's Changed\r\n\r\n## Highlights 🌟\r\n* Migration: `com.passwordmanager` to `com.jeeldobariya.passcodes` by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/17\r\n* Feat: Improved UI/UX by @JeelDobariya38 & @kudanilll in https://github.com/JeelDobariya38/Passcodes/pull/13\r\n\r\n## New Features 🚀\r\n* Feat: Migrate from `com.passwordmanager` to `com.jeeldobariya.passcodes` by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/15\r\n* Feat: Improve About Page. by @kudanilll in https://github.com/JeelDobariya38/Passcodes/pull/21\r\n* Feat: Add New Icon by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/25\r\n* ✨Preparing For First Stable Release ✨ by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/26\r\n* Feat: Add a Telegram Community Link by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/27\r\n\r\n## Documentation 📚\r\n* Improved Documentation by @JeelDobariya38 & @jainil63 in https://github.com/JeelDobariya38/Passcodes/pull/22\r\n* `Refactor`: Migrated Website Code to `@JeelDobariya38/Passcodes-Website` Repository by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/28\r\n* Docs: Improve Community Standards by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/29\r\n\r\n## Other Changes\r\n* Feat: Streamlining The Building & Installation Process by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/10\r\n* Important: Removed Compatibility With Code Assist Editor & Setup Unit Tests by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/11\r\n* Revert \"Feat: Migrate from `com.passwordmanager` to `com.jeeldobariya.passcodes`\" by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/16\r\n* Chore: Add Community Standards Related Stuff!! by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/18\r\n* CI/CD: Add Build Workflow by @JeelDobariya38 in https://github.com/JeelDobariya38/Passcodes/pull/23\r\n\r\n\r\n**Full Changelog**: https://github.com/JeelDobariya38/Passcodes/compare/v0.1.0...v1.0.0",
+ "mentions_count": 3
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/171838408",
+ "assets_url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/171838408/assets",
+ "upload_url": "https://uploads.github.com/repos/PasscodesApp/Passcodes/releases/171838408/assets{?name,label}",
+ "html_url": "https://github.com/PasscodesApp/Passcodes/releases/tag/v0.1.0",
+ "id": 171838408,
+ "author": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "node_id": "RE_kwDOMffp084KPgvI",
+ "tag_name": "v0.1.0",
+ "target_commitish": "main",
+ "name": "v0.1.0 - Alpha [Yanked Released]",
+ "draft": false,
+ "immutable": true,
+ "prerelease": true,
+ "created_at": "2024-08-25T16:13:32Z",
+ "updated_at": "2026-05-26T12:23:29Z",
+ "published_at": "2024-08-26T03:51:02Z",
+ "assets": [
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205525",
+ "id": 188205525,
+ "node_id": "RA_kwDOMffp084LN8nV",
+ "name": "password-manager-app-arm64-v8a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4448176,
+ "digest": null,
+ "download_count": 23,
+ "created_at": "2024-08-25T16:14:22Z",
+ "updated_at": "2024-08-25T16:14:25Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/password-manager-app-arm64-v8a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205529",
+ "id": 188205529,
+ "node_id": "RA_kwDOMffp084LN8nZ",
+ "name": "password-manager-app-armeabi-v7a-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4448176,
+ "digest": null,
+ "download_count": 5,
+ "created_at": "2024-08-25T16:14:25Z",
+ "updated_at": "2024-08-25T16:14:29Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/password-manager-app-armeabi-v7a-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205532",
+ "id": 188205532,
+ "node_id": "RA_kwDOMffp084LN8nc",
+ "name": "password-manager-app-universal-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4448176,
+ "digest": null,
+ "download_count": 54,
+ "created_at": "2024-08-25T16:14:29Z",
+ "updated_at": "2024-08-25T16:14:32Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/password-manager-app-universal-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205533",
+ "id": 188205533,
+ "node_id": "RA_kwDOMffp084LN8nd",
+ "name": "password-manager-app-x86_64-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4448176,
+ "digest": null,
+ "download_count": 7,
+ "created_at": "2024-08-25T16:14:32Z",
+ "updated_at": "2024-08-25T16:14:35Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/password-manager-app-x86_64-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205537",
+ "id": 188205537,
+ "node_id": "RA_kwDOMffp084LN8nh",
+ "name": "password-manager-app-x86-release.apk",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/vnd.android.package-archive",
+ "state": "uploaded",
+ "size": 4448176,
+ "digest": null,
+ "download_count": 5,
+ "created_at": "2024-08-25T16:14:35Z",
+ "updated_at": "2024-08-25T16:14:38Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/password-manager-app-x86-release.apk"
+ },
+ {
+ "url": "https://api.github.com/repos/PasscodesApp/Passcodes/releases/assets/188205544",
+ "id": 188205544,
+ "node_id": "RA_kwDOMffp084LN8no",
+ "name": "output-metadata.json",
+ "label": null,
+ "uploader": {
+ "login": "JeelDobariya38",
+ "id": 136002730,
+ "node_id": "U_kgDOCBs8qg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/136002730?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/JeelDobariya38",
+ "html_url": "https://github.com/JeelDobariya38",
+ "followers_url": "https://api.github.com/users/JeelDobariya38/followers",
+ "following_url": "https://api.github.com/users/JeelDobariya38/following{/other_user}",
+ "gists_url": "https://api.github.com/users/JeelDobariya38/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/JeelDobariya38/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/JeelDobariya38/subscriptions",
+ "organizations_url": "https://api.github.com/users/JeelDobariya38/orgs",
+ "repos_url": "https://api.github.com/users/JeelDobariya38/repos",
+ "events_url": "https://api.github.com/users/JeelDobariya38/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/JeelDobariya38/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "content_type": "application/json",
+ "state": "uploaded",
+ "size": 1516,
+ "digest": null,
+ "download_count": 4,
+ "created_at": "2024-08-25T16:14:38Z",
+ "updated_at": "2024-08-25T16:14:38Z",
+ "browser_download_url": "https://github.com/PasscodesApp/Passcodes/releases/download/v0.1.0/output-metadata.json"
+ }
+ ],
+ "tarball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/tarball/v0.1.0",
+ "zipball_url": "https://api.github.com/repos/PasscodesApp/Passcodes/zipball/v0.1.0",
+ "body": "> [!important]\r\n> This release is not intended to be used by normal users.. it just here as part of documentation and timeline that project have gone through... there are some **severe major issue/problems with package names..** so, don't use this by any means.... for more info refer to #12 & #14.\r\n\r\n# Deprecated / Yanked Release\r\n\r\n[Read More About Yanked Release](https://passcodesapp.github.io/Passcodes-Docs/user-docs/installing/#explicitly-yanked-release-pure-trash)\r\n \r\n## Overview\r\nThere is no such real issue using this version... this is normal prototype version and is stable in it on pace.... the real problem tough with this is... you won't be able to have support and updates with this app... as we, developers have deprecated the app and password manager project itself. For more info, Read #12 & #14. \r\n\r\nStill If you wanna use the app you can, and if you have any errors, bug or question along the process... report it to [github issue](https://github.com/JeelDobariya38/password-manager/issues/new?template=feedback---question---help-wanted.md). We would try our best to assist.. (if we can.. but, just be sure, it won't be the priority)\r\n\r\n## What's Changed\r\n* Create a Empty Project by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/1\r\n* Refactor: Remove '.idea' folder, because it has the potential to cause conflict & Add dependencies by @kudanilll in https://github.com/JeelDobariya38/password-manager/pull/3\r\n* Base for the UI, Nati dev by @HamadaNative in https://github.com/JeelDobariya38/password-manager/pull/4\r\n* Docs: Documented the Workflow by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/2\r\n* Feat: Create a Basic Prototype App by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/5\r\n* 🐞 Fix: Viewbinding Issue with Codeassist With Improvement in Docs by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/6\r\n* Docs: Add a Security Guidelines. 🔐 by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/7\r\n* Add CI-CD pipeline to the project 🤖 by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/8\r\n* ✨Preparing For First Initial Release ✨ by @JeelDobariya38 in https://github.com/JeelDobariya38/password-manager/pull/9\r\n\r\n## New Contributors\r\n* @JeelDobariya38 made their first contribution in https://github.com/JeelDobariya38/password-manager/pull/1\r\n* @kudanilll made their first contribution in https://github.com/JeelDobariya38/password-manager/pull/3\r\n* @HamadaNative made their first contribution in https://github.com/JeelDobariya38/password-manager/pull/4\r\n\r\n**Full Changelog**: https://github.com/JeelDobariya38/password-manager/commits/v0.1.0",
+ "mentions_count": 2
+ }
+]
\ No newline at end of file
diff --git a/src/lib/changelog.ts b/src/lib/changelog.ts
index 3d3c24d..215d781 100644
--- a/src/lib/changelog.ts
+++ b/src/lib/changelog.ts
@@ -1,11 +1,27 @@
+import rawEntries from "@/data/normalized-releases.json";
+
export type ChangelogCategory =
- "Features" | "Improvements" | "Fixes" | "Security" | "Architecture";
+ | "Features"
+ | "Improvements"
+ | "Fixes"
+ | "Security"
+ | "Architecture";
export interface ChangelogSection {
title: string;
items: string[];
}
+export interface InternalDetails {
+ packageName?: string;
+ expoSdk?: number | string;
+ minAndroid?: string;
+ maxAndroid?: string;
+ versionCode?: number;
+ versionName?: string;
+ masterDbVersion?: string;
+}
+
export interface ChangelogEntry {
slug: string;
version: string;
@@ -16,8 +32,16 @@ export interface ChangelogEntry {
summary: string;
highlights?: string[];
sections?: ChangelogSection[];
+ internalDetails?: InternalDetails;
+ tldr?: string;
githubUrl?: string;
compareUrl?: string;
+ isMajor?: boolean;
+ isYanked?: boolean;
+ yankedReason?: string;
+ isMilestone?: boolean;
+ assetsCount?: number;
+ downloadCount?: number;
}
export const CHANGELOG_CATEGORIES = [
@@ -31,223 +55,8 @@ export const CHANGELOG_CATEGORIES = [
export type CategoryFilter = (typeof CHANGELOG_CATEGORIES)[number];
-export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
- {
- slug: "v3-2-1-stable",
- version: "v3.2.1",
- title: "v3.2.1 — Split ABIs & Screenshot Prevention",
- date: "2026-08-02",
- releaseType: "Stable",
- category: "Improvements",
- summary:
- "Support for split Android ABIs for smaller download sizes, tab navigation back-stack fixes, screenshot prevention toggle, and UI consistency.",
- highlights: [
- "Split ABI architecture builds (arm64-v8a, armeabi-v7a, x86_64, x86, universal) reducing APK size significantly.",
- "Explicit screenshot and screen recording prevention for credential protection.",
- "Fixed tab layout back navigation behavior across nested views.",
- "Refined settings screen styling and responsive component alignments.",
- ],
- sections: [
- {
- title: "New Features & Security",
- items: [
- "Explicit in-app screenshot prevention toggle in security settings.",
- "Enhanced secure window flags during biometric authentication prompts.",
- ],
- },
- {
- title: "Bug Fixes & Architecture",
- items: [
- "Support for split ABIs in release packaging to reduce disk footprint.",
- "Resolved tab bar back navigation issue when switching tabs.",
- "UI consistency improvements across light and dark themes.",
- "Cleaned and optimized Expo configuration (app.config.ts).",
- ],
- },
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.1",
- compareUrl:
- "https://github.com/PasscodesApp/Passcodes/compare/v3.2.0...v3.2.1",
- },
- {
- slug: "v3-2-0-stable",
- version: "v3.2.0",
- title: "v3.2.0 — Modern Material UI & Dark Mode",
- date: "2026-07-25",
- releaseType: "Stable",
- category: "Features",
- summary:
- "Complete Material 3 UI overhaul, system dark mode support, gesture navigation, and screen capture prevention.",
- highlights: [
- "Modern Material UI design system with fluid animations and responsive layout.",
- "Comprehensive dark theme support with true black and low-contrast palettes.",
- "Screen capture and screenshot protection across all credential views.",
- "Pull-to-refresh password list and tab navigation improvements.",
- "Upgraded underlying foundation to Expo SDK 57.",
- ],
- sections: [
- {
- title: "New Features",
- items: [
- "Material 3 design system implementation across all screens.",
- "System dark mode and manual theme toggle support.",
- "Pull-to-refresh gesture support on the password list.",
- "Enhanced tab navigation and smooth screen transitions.",
- ],
- },
- {
- title: "Performance & Maintenance",
- items: [
- "Reduced memory consumption when loading large credential lists.",
- "Optimized bundle size and startup latency.",
- "Dependency bump to Expo SDK 57.",
- ],
- },
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.2.0",
- compareUrl:
- "https://github.com/PasscodesApp/Passcodes/compare/v3.1.0...v3.2.0",
- },
- {
- slug: "v3-1-0-stable",
- version: "v3.1.0",
- title: "v3.1.0 — Biometric Auth & Google Passwords Import/Export",
- date: "2026-06-22",
- releaseType: "Stable",
- category: "Features",
- summary:
- "Biometric authentication (fingerprint/face unlock), Google Passwords CSV import & export, password detail viewer, and data recovery safeguards.",
- highlights: [
- "Native biometric authentication for unlocking app access.",
- "Seamless import and export compatibility with Google Passwords CSV.",
- "Multi-purpose password detail screen with quick copy actions.",
- "Data recovery troubleshooting tools and uninstall data preservation prompt.",
- ],
- sections: [
- {
- title: "Security & Auth",
- items: [
- "Fingerprint and biometric prompt integration via Android BiometricPrompt.",
- "In-app auto-lock locking the app after 2 minutes of background inactivity.",
- ],
- },
- {
- title: "Credential Management",
- items: [
- "Full import & export pipeline compatible with standard password formats.",
- "Inline password updating and credential editing.",
- "Search and filtering across stored credentials.",
- ],
- },
- {
- title: "Developer Experience",
- items: [
- "Development builds and customized splash screens.",
- "Modularized reusable component library.",
- "Optimized towards Expo SDK 56.",
- ],
- },
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.1.0",
- compareUrl:
- "https://github.com/PasscodesApp/Passcodes/compare/v3.0.0...v3.1.0",
- },
- {
- slug: "v3-0-0-alpha",
- version: "v3.0.0",
- title: "v3.0.0 — Complete Architecture Rewrite (Expo / React Native)",
- date: "2026-05-24",
- releaseType: "Alpha",
- category: "Architecture",
- summary:
- "Major from-scratch architectural rewrite transitioning Passcodes from the legacy native Android codebase to Expo and React Native, establishing a clean foundation for core password management.",
- highlights: [
- "Complete from-scratch rewrite replacing the retired native Android architecture with Expo and React Native.",
- "New local persistent storage architecture built on SQLite and Drizzle ORM.",
- "Initial baseline release providing core password storage and basic manager functionality.",
- "Data recovery tools provided to migrate stored credentials from pre-v3 releases.",
- ],
- sections: [
- {
- title: "Architecture Rewrite",
- items: [
- "Replaced the previous native Kotlin/Compose architecture with Expo (React Native).",
- "Transitioned local database layer to expo-sqlite with Drizzle ORM.",
- "Setup modern build configurations and streamlined module tree.",
- ],
- },
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v3.0.0",
- compareUrl:
- "https://github.com/PasscodesApp/Passcodes/compare/v2.1.1...v3.0.0",
- },
- {
- slug: "v2-1-1-beta",
- version: "v2.1.1",
- title: "v2.1.1 — Biometric Auth & Navigation Scaffolding",
- date: "2026-05-19",
- releaseType: "Beta",
- category: "Improvements",
- summary:
- "Biometric authentication integration, dual navigation scaffolding, and autofill service adjustments in the pre-rewrite native architecture.",
- highlights: [
- "Biometric authentication in Compose Multiplatform (pre-rewrite architecture).",
- "Autofill service framework enhancements (preview/experimental).",
- "End of support announcement for v2.x codebase ahead of architecture rewrite.",
- ],
- sections: [
- {
- title: "Enhancements",
- items: [
- "Dual navigation support (classical & modern screen layouts).",
- "Experimental autofill adjustments in the native Android module.",
- "Migrated network client from OkHttp to Ktor.",
- ],
- },
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.1.1",
- },
- {
- slug: "v2-0-0-beta",
- version: "v2.0.0",
- title: "v2.0.0 — Compose Multiplatform Design System",
- date: "2026-04-16",
- releaseType: "Beta",
- category: "Features",
- summary:
- "Introduction of a unified design system in Compose Multiplatform, SQLite database v2 migration, and preview Android autofill service in the native codebase.",
- highlights: [
- "Brand new Compose Multiplatform design system (prior native architecture).",
- "Preview Android Autofill framework integration (experimental).",
- "Database module migrated to Kotlin Multiplatform library module.",
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v2.0.0",
- },
- {
- slug: "v1-0-0-stable",
- version: "v1.0.0",
- title: "v1.0.0 — First Official Stable Release",
- date: "2025-08-16",
- releaseType: "Stable",
- category: "Features",
- summary:
- "The inaugural stable release of the original native Android application. Offline-first local password storage on device with zero cloud dependencies.",
- highlights: [
- "Local SQLite password storage on device via Android Room database.",
- "Migrated core application codebase from Java to Kotlin.",
- "In-app language and theme switching support with introductory onboarding hints.",
- "Full open-source release under the MIT License.",
- ],
- githubUrl:
- "https://github.com/PasscodesApp/Passcodes/releases/tag/v1.0.0",
- },
-];
+export const CHANGELOG_ENTRIES: ChangelogEntry[] =
+ rawEntries as ChangelogEntry[];
export function getAllChangelogEntries(): ChangelogEntry[] {
return CHANGELOG_ENTRIES;
@@ -260,7 +69,9 @@ export function getChangelogEntryBySlug(
}
export function getLatestChangelogEntry(): ChangelogEntry {
- return CHANGELOG_ENTRIES[0];
+ return (
+ CHANGELOG_ENTRIES.find((e) => !e.isMilestone) || CHANGELOG_ENTRIES[0]
+ );
}
export function getAdjacentEntries(currentSlug: string): {
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 7e78851..080493e 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -3,15 +3,15 @@
@tailwind utilities;
/* ========================================================= */
-/* ===== PASSCODES DESIGN SYSTEM — GRAPHITE & VIOLET ======= */
+/* ===== PASSCODES DESIGN SYSTEM — GRAPHITE & SAPPHIRE ===== */
/* ========================================================= */
:root {
/* Surface and Background (Graphite / Near-Black Foundation) */
--bg-base: #080b12;
--bg-gradient: radial-gradient(
ellipse 90% 70% at 50% -10%,
- rgba(124, 58, 237, 0.09) 0%,
- rgba(10, 14, 24, 0.98) 55%,
+ rgba(37, 99, 235, 0.08) 0%,
+ rgba(10, 15, 28, 0.98) 55%,
#080b12 100%
);
--nav-bg: rgba(10, 14, 24, 0.82);
@@ -22,14 +22,14 @@
--text-muted: #94a3b8;
--text-dim: #64748b;
- /* Restrained Violet Accent */
- --primary: #8b5cf6;
+ /* Refined Sapphire / Azure Accent (Dark Mode) */
+ --primary: #3b82f6;
--primary-dark: #080b12;
- --accent: #7c3aed;
- --accent-light: #a78bfa;
- --accent-subtle: rgba(139, 92, 246, 0.1);
- --accent-border: rgba(139, 92, 246, 0.22);
- --accent-gradient: linear-gradient(135deg, #7c3aed 0%, #6366f1 100%);
+ --accent: #2563eb;
+ --accent-light: #60a5fa;
+ --accent-subtle: rgba(37, 99, 235, 0.12);
+ --accent-border: rgba(59, 130, 246, 0.24);
+ --accent-gradient: linear-gradient(135deg, #2563eb 0%, #0284c7 100%);
/* Unified Surface Language */
--card-bg: rgba(255, 255, 255, 0.025);
@@ -46,14 +46,14 @@
--footer-muted: #94a3b8;
--dialog-bg: linear-gradient(
145deg,
- rgba(12, 16, 28, 0.98),
- rgba(16, 21, 36, 0.98)
+ rgba(12, 18, 32, 0.98),
+ rgba(15, 23, 42, 0.98)
);
/* Shadows & Depth */
--shadow-hover: rgba(0, 0, 0, 0.4);
- --shadow-primary: rgba(124, 58, 237, 0.16);
- --shadow-accent: rgba(139, 92, 246, 0.2);
+ --shadow-primary: rgba(37, 99, 235, 0.18);
+ --shadow-accent: rgba(2, 132, 199, 0.22);
/* Code & Tags */
--code-bg: rgba(255, 255, 255, 0.06);
@@ -77,7 +77,7 @@ html.light {
--bg-base: #f8fafc;
--bg-gradient: radial-gradient(
ellipse 90% 70% at 50% -10%,
- rgba(237, 233, 254, 0.55) 0%,
+ rgba(224, 242, 254, 0.55) 0%,
#f8fafc 65%
);
--nav-bg: rgba(255, 255, 255, 0.88);
@@ -87,13 +87,14 @@ html.light {
--text-muted: #475569;
--text-dim: #94a3b8;
- --primary: #7c3aed;
- --primary-dark: #f8f7ff;
- --accent: #6d28d9;
- --accent-light: #7c3aed;
- --accent-subtle: rgba(124, 58, 237, 0.08);
- --accent-border: rgba(124, 58, 237, 0.18);
- --accent-gradient: linear-gradient(135deg, #7c3aed 0%, #6366f1 100%);
+ /* Refined Sapphire / Azure Accent (Light Mode) */
+ --primary: #2563eb;
+ --primary-dark: #f0f7ff;
+ --accent: #1d4ed8;
+ --accent-light: #1d4ed8;
+ --accent-subtle: rgba(37, 99, 235, 0.08);
+ --accent-border: rgba(37, 99, 235, 0.18);
+ --accent-gradient: linear-gradient(135deg, #1d4ed8 0%, #0284c7 100%);
--card-bg: rgba(255, 255, 255, 0.9);
--card-bg-hover: #ffffff;
@@ -109,12 +110,12 @@ html.light {
--dialog-bg: linear-gradient(
145deg,
rgba(255, 255, 255, 0.99),
- rgba(245, 243, 255, 0.99)
+ rgba(240, 249, 255, 0.99)
);
--shadow-hover: rgba(15, 23, 42, 0.06);
- --shadow-primary: rgba(124, 58, 237, 0.1);
- --shadow-accent: rgba(99, 102, 241, 0.12);
+ --shadow-primary: rgba(37, 99, 235, 0.1);
+ --shadow-accent: rgba(2, 132, 199, 0.14);
--code-bg: rgba(15, 23, 42, 0.05);
--code-fg: #0f172a;
@@ -525,7 +526,7 @@ html.light .active-nav {
margin-bottom: 14px;
}
.release-search input {
- width: min(400px, 100%);
+ width: 100%;
padding: 8px 36px 8px 38px;
border-radius: 10px;
border: 1px solid var(--border-light);
@@ -537,6 +538,12 @@ html.light .active-nav {
border-color var(--transition-micro),
background-color var(--transition-micro);
}
+.release-search input::-webkit-search-cancel-button,
+.release-search input::-webkit-search-decoration {
+ -webkit-appearance: none;
+ appearance: none;
+ display: none;
+}
.release-search input::placeholder {
color: var(--text-dim);
}
@@ -593,7 +600,7 @@ html.light .active-nav {
border-color: var(--accent-border);
background: linear-gradient(
180deg,
- rgba(139, 92, 246, 0.03) 0%,
+ rgba(37, 99, 235, 0.035) 0%,
var(--card-bg) 100%
);
}
@@ -657,10 +664,27 @@ html.light .active-nav {
color: #f87171;
}
+/* Light mode high-contrast tag tuning */
+html.light .tag.stable {
+ background: rgba(22, 163, 74, 0.1);
+ border-color: rgba(22, 163, 74, 0.28);
+ color: #15803d;
+}
+html.light .tag.beta {
+ background: rgba(217, 119, 6, 0.1);
+ border-color: rgba(217, 119, 6, 0.28);
+ color: #b45309;
+}
+html.light .tag.alpha {
+ background: rgba(220, 38, 38, 0.1);
+ border-color: rgba(220, 38, 38, 0.28);
+ color: #b91c1c;
+}
+
/* Alert Boxes */
.alert-info {
- border: 1px solid rgba(139, 92, 246, 0.3);
- background: rgba(139, 92, 246, 0.06);
+ border: 1px solid var(--accent-border);
+ background: var(--accent-subtle);
}
.alert-danger {
border: 1px solid rgba(239, 68, 68, 0.3);
From 0c7c84af74947383f7f1c3dc94d4cb2808e88077 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Sat, 12 Sep 2026 11:52:27 +0530
Subject: [PATCH 06/11] feat(community): add community manager profile
Signed-off-by: harsha-vardhan-burra
---
src/lib/contributors.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/lib/contributors.ts b/src/lib/contributors.ts
index dee056d..2985951 100644
--- a/src/lib/contributors.ts
+++ b/src/lib/contributors.ts
@@ -42,6 +42,10 @@ export const FEATURED_CONTRIBUTORS: ContributorProfile[] = [
github: "https://github.com/kudanilll",
avatar: "https://github.com/kudanilll.png",
},
+ {
+ name: "A Guy",
+ role: "Community Manager",
+ },
{
name: "hexCode",
role: "Contributor",
From 3d5bfa5ddb464001eb83f5938178ec46ab8b4f25 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Sat, 12 Sep 2026 12:36:04 +0530
Subject: [PATCH 07/11] feat(releases): mark v1 and v2 releases as deprecated
Signed-off-by: harsha-vardhan-burra
---
scripts/sync-releases.mjs | 10 ++++++
src/app/changelog/[slug]/page.tsx | 30 ++++++++++++++++-
src/app/changelog/page.tsx | 40 +++++++++++++++++++++--
src/components/downloads/DownloadCard.tsx | 20 ++++++++++--
src/components/downloads/ReleaseList.tsx | 29 +++++++++++++---
src/data/normalized-releases.json | 23 +++++++++++++
src/hooks/useGithubRelease.ts | 3 +-
src/lib/changelog.ts | 16 +++++++++
src/lib/github.ts | 16 +++++++--
src/styles/globals.css | 35 ++++++++++++++++++++
10 files changed, 208 insertions(+), 14 deletions(-)
diff --git a/scripts/sync-releases.mjs b/scripts/sync-releases.mjs
index 93ad41a..a95aa2d 100644
--- a/scripts/sync-releases.mjs
+++ b/scripts/sync-releases.mjs
@@ -433,6 +433,14 @@ async function main() {
const category = editorial.category || inferCategory(parsedSections);
const isMajor = editorial.isMajor ?? (version.endsWith(".0.0") || releaseType === "Stable");
+ // Deprecation rule: v1.x and v2.x releases are deprecated (superseded by newer database architecture in later releases).
+ const majorMatch = version.match(/^v?(\d+)\./i);
+ const majorVersion = majorMatch ? parseInt(majorMatch[1], 10) : undefined;
+ const isDeprecated = majorVersion === 1 || majorVersion === 2;
+ const deprecatedReason = isDeprecated
+ ? "Superseded by the newer database architecture introduced in later releases."
+ : undefined;
+
const entry = {
slug,
version,
@@ -450,6 +458,8 @@ async function main() {
isMajor,
isYanked: isYanked || false,
yankedReason: editorial.yankedReason || undefined,
+ isDeprecated,
+ deprecatedReason,
assetsCount: assetsCount > 0 ? assetsCount : undefined,
downloadCount: downloadCount > 0 ? downloadCount : undefined,
};
diff --git a/src/app/changelog/[slug]/page.tsx b/src/app/changelog/[slug]/page.tsx
index dfd861b..f0c0335 100644
--- a/src/app/changelog/[slug]/page.tsx
+++ b/src/app/changelog/[slug]/page.tsx
@@ -15,6 +15,7 @@ import {
CHANGELOG_ENTRIES,
getChangelogEntryBySlug,
getAdjacentEntries,
+ isDeprecatedEntry,
} from "@/lib/changelog";
import { SITE_META } from "@/lib/constants";
import { ReleaseVisual } from "@/components/visuals/ReleaseVisual";
@@ -59,6 +60,7 @@ export default function ChangelogEntryPage({
if (!entry) notFound();
const { prev, next } = getAdjacentEntries(params.slug);
+ const isDeprecated = isDeprecatedEntry(entry);
return (
@@ -76,6 +78,11 @@ export default function ChangelogEntryPage({
+ {isDeprecated && (
+
+ Deprecated Release
+
+ )}
{entry.isYanked ? (
Yanked Release
@@ -111,7 +118,14 @@ export default function ChangelogEntryPage({
-
+
{entry.version}
@@ -162,6 +176,20 @@ export default function ChangelogEntryPage({
+ {/* Deprecated Notice */}
+ {isDeprecated && (
+
+
+
+
Deprecated Release Notice
+
+
+ {entry.deprecatedReason ||
+ "This release is no longer supported. Superseded by the newer database architecture introduced in later releases. Please use a current release instead."}
+
+
+ )}
+
{/* Yanked Notice */}
{entry.isYanked && (
diff --git a/src/app/changelog/page.tsx b/src/app/changelog/page.tsx
index 40dc3f1..cc38ac0 100644
--- a/src/app/changelog/page.tsx
+++ b/src/app/changelog/page.tsx
@@ -9,10 +9,12 @@ import {
ArrowRight,
Calendar,
GitCommit,
+ AlertTriangle,
} from "lucide-react";
import {
CHANGELOG_ENTRIES,
CHANGELOG_CATEGORIES,
+ isDeprecatedEntry,
type CategoryFilter,
} from "@/lib/changelog";
import { GITHUB_RELEASES_URL, DOCS_RELEASE_NOTES_URL } from "@/lib/constants";
@@ -248,17 +250,29 @@ export default function ChangelogPage() {
);
}
+ const isDeprecated = isDeprecatedEntry(entry);
+
return (
-
+
{/* Left Column: Metadata & Category Node */}
+ {isDeprecated && (
+
+ Deprecated
+
+ )}
{entry.isYanked ? (
Yanked
@@ -294,7 +308,14 @@ export default function ChangelogPage() {
-
+
{entry.version}
@@ -319,7 +340,7 @@ export default function ChangelogPage() {
@@ -369,6 +390,19 @@ export default function ChangelogPage() {
+ {isDeprecated && (
+
+
+
+ {entry.deprecatedReason ||
+ "This release is no longer supported. Superseded by the newer database architecture introduced in later releases. Please use a current release instead."}
+
+
+ )}
+
{entry.isYanked && entry.yankedReason && (
Release Notice:
diff --git a/src/components/downloads/DownloadCard.tsx b/src/components/downloads/DownloadCard.tsx
index 7c2690c..6b0f38c 100644
--- a/src/components/downloads/DownloadCard.tsx
+++ b/src/components/downloads/DownloadCard.tsx
@@ -1,12 +1,12 @@
"use client";
import { useState } from "react";
-import { Download, Calendar, Tag } from "lucide-react";
+import { Download, Calendar, Tag, AlertTriangle } from "lucide-react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { ArchDownload } from "@/components/downloads/ArchDownload";
import { formatNumber, formatDate, cn } from "@/lib/utils";
-import { classifyRelease, isYankedRelease } from "@/hooks/useGithubRelease";
+import { classifyRelease, isYankedRelease, isDeprecatedRelease } from "@/hooks/useGithubRelease";
import type { GithubRelease } from "@/types/github";
export function DownloadCard({
@@ -23,13 +23,15 @@ export function DownloadCard({
);
const channel = classifyRelease(release);
const isYanked = isYankedRelease(release);
+ const isDeprecated = isDeprecatedRelease(release);
return (
-
+
{release.name || release.tag_name}
{isLatest && Latest }
+ {isDeprecated && Deprecated }
{isYanked && Yanked }
{channel === "beta" && (
Beta
@@ -61,6 +63,18 @@ export function DownloadCard({
+ {isDeprecated && (
+
+
+
+ This release is no longer supported. Superseded by the newer database architecture introduced in later releases. Please use a current release instead.
+
+
+ )}
+
{release.body && (
+
-
+
{release.name || release.tag_name}
+ {isDeprecated && (
+
+ deprecated
+
+ )}
{isYanked && (
yanked
@@ -82,6 +91,18 @@ export function ReleaseList({
+ {isDeprecated && (
+
+
+
+ This release is no longer supported. Superseded by the newer database architecture introduced in later releases. Please use a current release instead.
+
+
+ )}
+
0 ? CHANGELOG_ENTRIES[index - 1] : null,
};
}
+
+/**
+ * Check if a changelog entry is deprecated.
+ * v1.x and v2.x releases are deprecated (superseded by newer database architecture).
+ */
+export function isDeprecatedEntry(entry: ChangelogEntry): boolean {
+ if (typeof entry.isDeprecated === "boolean") {
+ return entry.isDeprecated;
+ }
+ const match = entry.version.match(/^v?(\d+)\./i);
+ if (!match) return false;
+ const major = parseInt(match[1], 10);
+ return major === 1 || major === 2;
+}
diff --git a/src/lib/github.ts b/src/lib/github.ts
index f6fb979..248ef9f 100644
--- a/src/lib/github.ts
+++ b/src/lib/github.ts
@@ -88,6 +88,18 @@ export function isYankedRelease(release: GithubRelease): boolean {
return text.includes("yanked");
}
+/**
+ * Check if a release is deprecated.
+ * v1.x and v2.x releases are deprecated (superseded by newer database architecture).
+ */
+export function isDeprecatedRelease(release: GithubRelease): boolean {
+ const text = release.tag_name || release.name || "";
+ const match = text.match(/v?(\d+)\./i);
+ if (!match) return false;
+ const major = parseInt(match[1], 10);
+ return major === 1 || major === 2;
+}
+
/**
* Classify a release into Stable, Beta, or Alpha channels based on metadata and naming conventions.
* Primary classification:
@@ -127,7 +139,7 @@ export function classifyRelease(release: GithubRelease): ReleaseChannel {
* Find the latest stable release from a list of releases.
* Follows GitHub's /releases/latest semantics:
* - not a draft
- * - classified as stable (not prerelease, not alpha/beta, not yanked)
+ * - classified as stable (not prerelease, not alpha/beta, not yanked, not deprecated)
* - newest according to created_at
* Pure function that does not mutate the source array.
*/
@@ -135,7 +147,7 @@ export function getLatestStableRelease(
releases: GithubRelease[]
): GithubRelease | undefined {
return releases.reduce((latest, release) => {
- if (release.draft || isYankedRelease(release)) return latest;
+ if (release.draft || isYankedRelease(release) || isDeprecatedRelease(release)) return latest;
if (classifyRelease(release) !== "stable") return latest;
if (!latest) return release;
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 080493e..cb1bd0d 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -604,6 +604,31 @@ html.light .active-nav {
var(--card-bg) 100%
);
}
+.release-card.deprecated {
+ border: 1px solid rgba(239, 68, 68, 0.42);
+ background: linear-gradient(
+ 180deg,
+ rgba(239, 68, 68, 0.045) 0%,
+ var(--card-bg) 100%
+ );
+ opacity: 0.94;
+}
+.release-card.deprecated:hover {
+ border-color: rgba(239, 68, 68, 0.65);
+ box-shadow: 0 4px 16px rgba(239, 68, 68, 0.12);
+}
+html.light .release-card.deprecated {
+ border: 1px solid rgba(220, 38, 38, 0.38);
+ background: linear-gradient(
+ 180deg,
+ rgba(220, 38, 38, 0.035) 0%,
+ var(--card-bg) 100%
+ );
+}
+html.light .release-card.deprecated:hover {
+ border-color: rgba(220, 38, 38, 0.58);
+ box-shadow: 0 4px 16px rgba(220, 38, 38, 0.1);
+}
.release-top {
display: flex;
@@ -663,6 +688,11 @@ html.light .active-nav {
border: 1px solid rgba(239, 68, 68, 0.3);
color: #f87171;
}
+.tag.deprecated {
+ background: rgba(239, 68, 68, 0.14);
+ border: 1px solid rgba(239, 68, 68, 0.4);
+ color: #f87171;
+}
/* Light mode high-contrast tag tuning */
html.light .tag.stable {
@@ -680,6 +710,11 @@ html.light .tag.alpha {
border-color: rgba(220, 38, 38, 0.28);
color: #b91c1c;
}
+html.light .tag.deprecated {
+ background: rgba(220, 38, 38, 0.1);
+ border-color: rgba(220, 38, 38, 0.32);
+ color: #b91c1c;
+}
/* Alert Boxes */
.alert-info {
From 7de8b95e42d65da69278b71662d0e894a476c4ae Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Sat, 12 Sep 2026 12:50:50 +0530
Subject: [PATCH 08/11] feat(footer): add contributor design credit
Signed-off-by: harsha-vardhan-burra
---
src/components/layout/Footer.tsx | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx
index 689545f..f063c3d 100644
--- a/src/components/layout/Footer.tsx
+++ b/src/components/layout/Footer.tsx
@@ -145,10 +145,25 @@ export function Footer() {
-
- Copyright © Jeel Dobariya 2025–2026. All rights
- reserved.
-
+
+
+ Copyright © Jeel Dobariya 2025–2026. All rights
+ reserved.
+
+
+ Design by{" "}
+
+ @harsha-vardhan-burra
+
+
+
Crafted for privacy and local control.
From a23ad00b629b6224ac7b4192ea64dd970183d06a Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Sat, 12 Sep 2026 13:32:48 +0530
Subject: [PATCH 09/11] test(e2e): add automated Playwright regression suite
Signed-off-by: harsha-vardhan-burra
---
.github/workflows/playwright.yml | 54 ++++++++++++
.gitignore | 2 +
TESTING.md | 102 ++++++++++++++++++++++
package-lock.json | 46 ++++++++++
package.json | 6 +-
playwright.config.ts | 43 +++++++++
tests/fixtures/base-test.ts | 75 ++++++++++++++++
tests/functional/changelog-search.spec.ts | 62 +++++++++++++
tests/functional/release-filters.spec.ts | 70 +++++++++++++++
tests/functional/theme.spec.ts | 48 ++++++++++
tests/smoke/changelog.spec.ts | 60 +++++++++++++
tests/smoke/community.spec.ts | 39 +++++++++
tests/smoke/downloads.spec.ts | 52 +++++++++++
tests/smoke/footer.spec.ts | 42 +++++++++
tests/smoke/homepage.spec.ts | 48 ++++++++++
tests/smoke/mobile.spec.ts | 50 +++++++++++
16 files changed, 798 insertions(+), 1 deletion(-)
create mode 100644 .github/workflows/playwright.yml
create mode 100644 TESTING.md
create mode 100644 playwright.config.ts
create mode 100644 tests/fixtures/base-test.ts
create mode 100644 tests/functional/changelog-search.spec.ts
create mode 100644 tests/functional/release-filters.spec.ts
create mode 100644 tests/functional/theme.spec.ts
create mode 100644 tests/smoke/changelog.spec.ts
create mode 100644 tests/smoke/community.spec.ts
create mode 100644 tests/smoke/downloads.spec.ts
create mode 100644 tests/smoke/footer.spec.ts
create mode 100644 tests/smoke/homepage.spec.ts
create mode 100644 tests/smoke/mobile.spec.ts
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
new file mode 100644
index 0000000..267bb06
--- /dev/null
+++ b/.github/workflows/playwright.yml
@@ -0,0 +1,54 @@
+name: 🎭 Playwright E2E & Regression Tests
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ branches: ["main"]
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ name: 🧪 Run Playwright E2E Tests
+ timeout-minutes: 15
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: ⬇️ Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: 🟢 Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: "package.json"
+ cache: npm
+ cache-dependency-path: "package-lock.json"
+
+ - name: 📦 Install Dependencies
+ run: npm ci
+
+ - name: 🎭 Install Playwright Browsers (Chromium)
+ run: npx playwright install --with-deps chromium
+
+ - name: 🔎 Type Check & Lint
+ run: |
+ npm run type-check
+ npm run lint
+
+ - name: 🛠️ Build Static Site Export
+ run: npm run build
+
+ - name: 🚀 Run Playwright End-to-End Tests
+ run: npm run test:e2e
+
+ - name: 📊 Upload Playwright Test Report Artifact
+ uses: actions/upload-artifact@v4
+ if: ${{ !cancelled() }}
+ with:
+ name: playwright-report
+ path: playwright-report/
+ retention-days: 14
diff --git a/.gitignore b/.gitignore
index 00bfcec..e7eae05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,8 @@
# testing
/coverage
+/test-results/
+/playwright-report/
# next.js
/.next/
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..18209d7
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,102 @@
+# 🎭 End-to-End & Regression Testing with Playwright
+
+This repository maintains an automated end-to-end (E2E) and regression test suite powered by [Playwright](https://playwright.dev/). The test suite guards user-facing flows and critical business logic against unintended regressions.
+
+---
+
+## 🏗️ Architecture & Design Principles
+
+1. **Production-Faithful Static Export Testing**
+ Next.js static site generation (`next build` / `npm run build`) generates static HTML/JS output in the `out/` directory. Tests run against this production export served locally via `npx serve out -l 3000 -L` to ensure tests evaluate exact client-side runtime behavior without development-mode artifacts.
+
+2. **Deterministic Offline Testing (Zero Rate Limits)**
+ The website client-side queries the GitHub API for releases (`https://api.github.com/**`). In the custom test fixture (`tests/fixtures/base-test.ts`), all GitHub API requests are routed and answered with local snapshots (`src/data/raw-releases.json`). This ensures:
+ - Zero dependency on live internet access during test runs.
+ - Zero risk of hitting GitHub's unauthenticated IP rate limit (60 requests/hour).
+ - High speed and 100% deterministic test outcomes.
+
+3. **No Flaky Arbitrary Timeouts**
+ Tests use Playwright web assertions (`expect(...).toBeVisible()`, `expect(...).toHaveClass(...)`) and locator auto-waiting. Explicit calls to `page.waitForTimeout()` are avoided.
+
+4. **Cross-Platform Device Coverage**
+ Configured for both Desktop Chrome (`1280x720`) and Mobile Chrome (`Pixel 5` viewport) to validate responsive layouts, desktop navigation, and mobile hamburger drawer interactions.
+
+5. **Visual Regression Policy**
+ Pixel-by-pixel screenshot comparisons (`toMatchSnapshot`) are intentionally **deferred** to prevent brittle test failures caused by font rendering variations across operating systems (e.g., Linux CI runners vs. Windows/macOS local machines). Instead, tests focus on structural DOM, role-based semantics, ARIA states, and CSS class assertions.
+
+---
+
+## 🚀 Running Tests Locally
+
+### Prerequisites
+
+Ensure project dependencies and Playwright Chromium binaries are installed:
+
+```bash
+npm install
+npx playwright install chromium
+```
+
+Before running tests, ensure the static production export is built:
+
+```bash
+npm run build
+```
+
+### Test Commands
+
+| Command | Purpose |
+| :--- | :--- |
+| `npm run test:e2e` | Runs all end-to-end tests headlessly across Desktop and Mobile projects. |
+| `npm run test:e2e:ui` | Launches Playwright's interactive UI mode with time-travel debugging and locator inspection. |
+| `npm run test:e2e:report` | Opens the generated HTML test results report in your browser. |
+
+You can also run specific test files or projects directly:
+
+```bash
+# Run only smoke tests
+npx playwright test tests/smoke/
+
+# Run only on Desktop Chrome
+npx playwright test --project=chromium
+
+# Run a specific test in debug mode
+npx playwright test tests/smoke/homepage.spec.ts --debug
+```
+
+---
+
+## 📁 Test Suite Structure
+
+```text
+tests/
+├── fixtures/
+│ └── base-test.ts # Custom Playwright fixture intercepting GitHub API requests & checking console errors
+├── functional/
+│ ├── changelog-search.spec.ts # Changelog search filter, debouncing, & clear interactions
+│ ├── release-filters.spec.ts # Downloads channel tabs (Stable/Beta/Alpha) & release search
+│ └── theme.spec.ts # Dark/light theme toggle, html class mutation, & localStorage persistence
+└── smoke/
+ ├── changelog.spec.ts # Changelog timeline, v1/v2 deprecation badges, yanked notices, & detail pages
+ ├── community.spec.ts # Community page, contributor cards, "A Guy" Community Manager card integrity
+ ├── downloads.spec.ts # Downloads page, recommended build card, split ABIs, & deprecated/yanked releases
+ ├── footer.spec.ts # Footer design credit (@harsha-vardhan-burra) & navigation links
+ ├── homepage.spec.ts # Homepage hero, tagline, primary CTAs, & section landmarks
+ └── mobile.spec.ts # Mobile viewport hamburger button, drawer menu, and mobile navigation
+```
+
+---
+
+## 🤖 Continuous Integration (CI)
+
+The GitHub Actions workflow (`.github/workflows/playwright.yml`) executes automatically on:
+- Every push to `main`
+- Every pull request targeting `main`
+- Manual workflow dispatch
+
+The CI pipeline runs:
+1. `npm run type-check` (TypeScript type integrity)
+2. `npm run lint` (ESLint code standards)
+3. `npm run build` (Static export generation)
+4. `npm run test:e2e` (Playwright test suite execution)
+5. Test report upload on failure for artifact inspection
diff --git a/package-lock.json b/package-lock.json
index 8264eb8..13d449c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"tailwind-merge": "^2.4.0"
},
"devDependencies": {
+ "@playwright/test": "^1.63.0",
"@types/node": "^20.14.0",
"@types/react": "^18.3.31",
"@types/react-dom": "^18.3.7",
@@ -518,6 +519,22 @@
"node": ">=14"
}
},
+ "node_modules/@playwright/test": {
+ "version": "1.63.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.63.0.tgz",
+ "integrity": "sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.63.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -6354,6 +6371,35 @@
"node": ">= 6"
}
},
+ "node_modules/playwright": {
+ "version": "1.63.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.63.0.tgz",
+ "integrity": "sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.63.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.63.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.63.0.tgz",
+ "integrity": "sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
diff --git a/package.json b/package.json
index 5dd0e66..2106949 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,10 @@
"lint": "next lint",
"preview": "npm run build && serve out",
"format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
- "type-check": "tsc --noEmit"
+ "type-check": "tsc --noEmit",
+ "test:e2e": "playwright test",
+ "test:e2e:ui": "playwright test --ui",
+ "test:e2e:report": "playwright show-report"
},
"dependencies": {
"@tanstack/react-query": "^5.50.0",
@@ -26,6 +29,7 @@
"tailwind-merge": "^2.4.0"
},
"devDependencies": {
+ "@playwright/test": "^1.63.0",
"@types/node": "^20.14.0",
"@types/react": "^18.3.31",
"@types/react-dom": "^18.3.7",
diff --git a/playwright.config.ts b/playwright.config.ts
new file mode 100644
index 0000000..a70bfd3
--- /dev/null
+++ b/playwright.config.ts
@@ -0,0 +1,43 @@
+import { defineConfig, devices } from "@playwright/test";
+
+/**
+ * Playwright E2E testing configuration for Passcodes website.
+ * Tests the locally built static export for deterministic, network-independent execution.
+ */
+export default defineConfig({
+ testDir: "./tests",
+ timeout: 30 * 1000,
+ expect: {
+ timeout: 5000,
+ },
+ fullyParallel: true,
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 2 : 0,
+ workers: process.env.CI ? 2 : undefined,
+ reporter: [
+ ["html", { open: "never" }],
+ ["list"],
+ ],
+ use: {
+ baseURL: "http://localhost:3000",
+ trace: "retain-on-failure",
+ screenshot: "only-on-failure",
+ video: "retain-on-failure",
+ },
+ projects: [
+ {
+ name: "chromium",
+ use: { ...devices["Desktop Chrome"] },
+ },
+ {
+ name: "mobile-chrome",
+ use: { ...devices["Pixel 5"] },
+ },
+ ],
+ webServer: {
+ command: "npx serve out -l 3000 -L",
+ url: "http://localhost:3000",
+ reuseExistingServer: !process.env.CI,
+ timeout: 120 * 1000,
+ },
+});
diff --git a/tests/fixtures/base-test.ts b/tests/fixtures/base-test.ts
new file mode 100644
index 0000000..0226abd
--- /dev/null
+++ b/tests/fixtures/base-test.ts
@@ -0,0 +1,75 @@
+import { test as base, expect } from "@playwright/test";
+import rawReleases from "../../src/data/raw-releases.json";
+
+/**
+ * Custom test fixture that:
+ * 1. Intercepts external GitHub API requests and responds with local snapshots (deterministic, offline).
+ * 2. Monitors uncaught page errors and console.error events, failing tests if fatal JS crashes occur.
+ */
+export const test = base.extend({
+ page: async ({ page }, use) => {
+ const pageErrors: Error[] = [];
+ const consoleErrors: string[] = [];
+
+ page.on("pageerror", (err) => {
+ pageErrors.push(err);
+ });
+
+ page.on("console", (msg) => {
+ if (msg.type() === "error") {
+ const text = msg.text();
+ // Filter out non-actionable external icon 404 noise if any
+ if (!text.includes("favicon.ico")) {
+ consoleErrors.push(text);
+ }
+ }
+ });
+
+ // Deterministic GitHub API routing with local repository snapshots
+ await page.route("https://api.github.com/**", async (route) => {
+ const url = route.request().url();
+ if (url.includes("/releases")) {
+ await route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify(rawReleases),
+ });
+ } else if (url.includes("/contributors")) {
+ await route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify([]),
+ });
+ } else if (url.includes("/repos/PasscodesApp/Passcodes")) {
+ await route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify({
+ stargazers_count: 150,
+ forks_count: 20,
+ }),
+ });
+ } else {
+ await route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify({}),
+ });
+ }
+ });
+
+ await use(page);
+
+ expect(
+ pageErrors,
+ `Uncaught page errors detected: ${pageErrors.map((e) => e.message).join("; ")}`
+ ).toHaveLength(0);
+
+ expect(
+ consoleErrors,
+ `Console errors detected: ${consoleErrors.join("; ")}`
+ ).toHaveLength(0);
+ },
+});
+
+export { expect };
diff --git a/tests/functional/changelog-search.spec.ts b/tests/functional/changelog-search.spec.ts
new file mode 100644
index 0000000..e9ca501
--- /dev/null
+++ b/tests/functional/changelog-search.spec.ts
@@ -0,0 +1,62 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Changelog Search Functional Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/changelog/");
+ });
+
+ test("searching by version filters changelog entries", async ({ page }) => {
+ const searchInput = page.getByLabel("Search changelog entries");
+ await expect(searchInput).toBeVisible();
+
+ // Search for specific version
+ await searchInput.fill("v3.2.1");
+
+ // The matching article should be visible
+ const matchingArticles = page.locator("article").filter({ hasText: /v3\.2\.1/i });
+ await expect(matchingArticles.first()).toBeVisible();
+
+ // Articles should be filtered down
+ const totalVisible = await page.locator("article").count();
+ expect(totalVisible).toBeLessThanOrEqual(2);
+ });
+
+ test("searching by keyword filters results and clear button restores list", async ({ page }) => {
+ const searchInput = page.getByLabel("Search changelog entries");
+
+ // Search for a keyword like "Biometric" or "Material"
+ await searchInput.fill("Material");
+
+ const matchingArticles = page.locator("article").filter({ hasText: /Material/i });
+ await expect(matchingArticles.first()).toBeVisible();
+
+ // Exactly one clear button appears
+ const clearBtn = page.getByRole("button", { name: "Clear search" });
+ await expect(clearBtn).toBeVisible();
+ await expect(clearBtn).toHaveCount(1);
+
+ // Click clear and ensure search is reset
+ await clearBtn.click();
+ await expect(searchInput).toHaveValue("");
+
+ // All entries restored
+ const restoredCount = await page.locator("article").count();
+ expect(restoredCount).toBeGreaterThan(5);
+ });
+
+ test("no results message appears on unmatched query and reset works", async ({ page }) => {
+ const searchInput = page.getByLabel("Search changelog entries");
+ await searchInput.fill("nonexistent-release-query-xyz");
+
+ // "No updates match your filter"
+ await expect(page.getByText(/No updates match your filter/i)).toBeVisible();
+
+ // Reset Filters button restores list
+ const resetBtn = page.getByRole("button", { name: /Reset Filters/i });
+ await expect(resetBtn).toBeVisible();
+ await resetBtn.click();
+
+ await expect(searchInput).toHaveValue("");
+ await expect(page.locator("article").first()).toBeVisible();
+ });
+});
diff --git a/tests/functional/release-filters.spec.ts b/tests/functional/release-filters.spec.ts
new file mode 100644
index 0000000..02904fd
--- /dev/null
+++ b/tests/functional/release-filters.spec.ts
@@ -0,0 +1,70 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Downloads Channel Filter & Search Functional Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/downloads/");
+ // Wait for release cards to be rendered
+ await expect(page.locator(".release-card").first()).toBeVisible();
+ });
+
+ test("release channel filter buttons update the visible release list", async ({ page }) => {
+ const stableFilterBtn = page.getByRole("button", { name: "Stable", exact: true });
+ const betaFilterBtn = page.getByRole("button", { name: "Beta", exact: true });
+ const alphaFilterBtn = page.getByRole("button", { name: "Alpha", exact: true });
+ const allFilterBtn = page.getByRole("button", { name: "All Releases", exact: true });
+
+ const archiveCards = page.locator(".release-card:not(.latest)");
+
+ // Filter by Stable
+ await stableFilterBtn.click();
+ await expect(stableFilterBtn).toHaveClass(/active/);
+ await expect(archiveCards.first()).toBeVisible();
+
+ // Stable releases should include v3.2.1
+ await expect(archiveCards.filter({ hasText: /v3\.2\.1/i })).toBeVisible();
+ // Should not show Beta releases in stable filter
+ await expect(archiveCards.locator(".tag.beta")).toHaveCount(0);
+
+ // Filter by Beta
+ await betaFilterBtn.click();
+ await expect(betaFilterBtn).toHaveClass(/active/);
+ await expect(archiveCards.first()).toBeVisible();
+ await expect(archiveCards.locator(".tag.beta").first()).toBeVisible();
+ await expect(archiveCards.locator(".tag.stable")).toHaveCount(0);
+
+ // Filter by Alpha
+ await alphaFilterBtn.click();
+ await expect(alphaFilterBtn).toHaveClass(/active/);
+ await expect(archiveCards.first()).toBeVisible();
+ await expect(archiveCards.locator(".tag.alpha").first()).toBeVisible();
+ await expect(archiveCards.locator(".tag.stable")).toHaveCount(0);
+
+ // Reset to All
+ await allFilterBtn.click();
+ await expect(allFilterBtn).toHaveClass(/active/);
+ await expect(archiveCards.count()).resolves.toBeGreaterThan(5);
+ });
+
+ test("downloads search filters releases and clear button restores list", async ({ page }) => {
+ const searchInput = page.getByLabel("Search releases");
+ await expect(searchInput).toBeVisible();
+
+ // Enter search term
+ await searchInput.fill("v3.2.1");
+
+ // Release list should filter to v3.2.1
+ const archiveCards = page.locator(".release-card:not(.latest)");
+ await expect(archiveCards).toHaveCount(1);
+ await expect(archiveCards.first()).toContainText("v3.2.1");
+
+ // Clear button should be visible (only one clear button inside search input container)
+ const clearBtn = page.getByRole("button", { name: "Clear search" });
+ await expect(clearBtn).toBeVisible();
+ await expect(clearBtn).toHaveCount(1);
+
+ // Click clear and verify list is restored
+ await clearBtn.click();
+ await expect(searchInput).toHaveValue("");
+ await expect(archiveCards.count()).resolves.toBeGreaterThan(1);
+ });
+});
diff --git a/tests/functional/theme.spec.ts b/tests/functional/theme.spec.ts
new file mode 100644
index 0000000..4cb5ff1
--- /dev/null
+++ b/tests/functional/theme.spec.ts
@@ -0,0 +1,48 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Theme Toggle Functional Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/");
+ });
+
+ test("theme toggle switches between dark and light modes and updates DOM", async ({ page }) => {
+ // Visible theme button (handles desktop vs mobile header)
+ const themeBtn = page.getByRole("button", { name: /Switch to (light|dark) mode/i }).and(page.locator(":visible"));
+ await expect(themeBtn).toBeVisible();
+
+ const initialLabel = await themeBtn.getAttribute("aria-label");
+ const isInitialDark = initialLabel?.includes("light");
+
+ // Toggle theme
+ await themeBtn.click();
+
+ // Verify HTML element received appropriate class
+ const html = page.locator("html");
+ if (isInitialDark) {
+ await expect(html).toHaveClass(/light/);
+ await expect(themeBtn).toHaveAttribute("aria-label", /Switch to dark mode/i);
+ } else {
+ await expect(html).toHaveClass(/dark/);
+ await expect(themeBtn).toHaveAttribute("aria-label", /Switch to light mode/i);
+ }
+
+ // Toggle back
+ await themeBtn.click();
+ if (isInitialDark) {
+ await expect(html).toHaveClass(/dark/);
+ } else {
+ await expect(html).toHaveClass(/light/);
+ }
+ });
+
+ test("theme preference persists across reload", async ({ page }) => {
+ const themeBtn = page.getByRole("button", { name: /Switch to (light|dark) mode/i }).and(page.locator(":visible"));
+ await themeBtn.click();
+
+ // Reload page
+ await page.reload();
+
+ // Ensure page is still functional
+ await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
+ });
+});
diff --git a/tests/smoke/changelog.spec.ts b/tests/smoke/changelog.spec.ts
new file mode 100644
index 0000000..f3085b7
--- /dev/null
+++ b/tests/smoke/changelog.spec.ts
@@ -0,0 +1,60 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Changelog Smoke & Detail Page Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/changelog/");
+ });
+
+ test("changelog index loads and displays timeline stream", async ({ page }) => {
+ await expect(page).toHaveTitle(/Passcodes/i);
+ await expect(page.getByRole("heading", { name: "Release Highlights & Milestones", level: 1 })).toBeVisible();
+
+ // Articles/timeline entries render
+ const articles = page.locator("article");
+ await expect(articles.first()).toBeVisible();
+
+ // Latest release (v3.2.1) is present
+ await expect(page.getByText("v3.2.1").first()).toBeVisible();
+ });
+
+ test("historical releases display deprecated and yanked indicators appropriately", async ({ page }) => {
+ // v2.1.1 should have Deprecated tag
+ const v2Entry = page.locator("article").filter({ hasText: /v2\.1\.1/i }).first();
+ await expect(v2Entry).toBeVisible();
+ await expect(v2Entry.locator(".tag.deprecated")).toBeVisible();
+
+ // v1.2.0 should display Yanked tag and Deprecated tag
+ const v120Entry = page.locator("article").filter({ has: page.getByRole("heading", { name: /v1\.2\.0/i }) }).first();
+ await expect(v120Entry).toBeVisible();
+ await expect(v120Entry.locator(".tag.deprecated")).toBeVisible();
+ await expect(v120Entry.locator(".tag").filter({ hasText: /yanked/i })).toBeVisible();
+ });
+
+ test("release detail page loads with metadata and navigates back", async ({ page }) => {
+ // Navigate to v3.2.1 detail page
+ await page.goto("/changelog/v3-2-1-stable/");
+
+ await expect(page).toHaveTitle(/v3\.2\.1.*Passcodes Changelog/i);
+ const titleHeading = page.getByRole("heading", { level: 1 });
+ await expect(titleHeading).toBeVisible();
+ await expect(titleHeading).toContainText("v3.2.1");
+
+ // Release Highlights or sections are visible
+ await expect(page.getByText(/Release Highlights/i)).toBeVisible();
+
+ // Back link works
+ const backLink = page.getByRole("link", { name: /Back to all updates/i });
+ await expect(backLink).toBeVisible();
+ await backLink.click();
+ await expect(page).toHaveURL(/\/changelog\/?$/);
+ });
+
+ test("deprecated release detail page displays deprecation notice banner", async ({ page }) => {
+ // Navigate to deprecated release detail page
+ await page.goto("/changelog/v2-1-1-beta/");
+
+ await expect(page).toHaveTitle(/v2\.1\.1.*Passcodes Changelog/i);
+ await expect(page.locator(".tag.deprecated")).toContainText(/Deprecated Release/i);
+ await expect(page.getByText(/Deprecated Release Notice/i)).toBeVisible();
+ });
+});
diff --git a/tests/smoke/community.spec.ts b/tests/smoke/community.spec.ts
new file mode 100644
index 0000000..2ca1f83
--- /dev/null
+++ b/tests/smoke/community.spec.ts
@@ -0,0 +1,39 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Community Page Smoke Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/community/");
+ });
+
+ test("community page loads and displays contributors", async ({ page }) => {
+ await expect(page).toHaveTitle(/Community/i);
+ await expect(page.getByRole("heading", { name: "Community", level: 1 })).toBeVisible();
+
+ // Established contributors appear
+ await expect(page.getByRole("heading", { name: "Jeel Dobariya" })).toBeVisible();
+ await expect(page.getByRole("heading", { name: "Harsha Vardhan Burra" })).toBeVisible();
+ });
+
+ test("A Guy community manager card renders without misleading links", async ({ page }) => {
+ // Find "A Guy" contributor card
+ const guyCard = page.locator(".card").filter({ hasText: "A Guy" });
+ await expect(guyCard).toBeVisible();
+ await expect(guyCard).toHaveCount(1);
+
+ // Role should be Community Manager
+ await expect(guyCard.locator(".role")).toHaveText("Community Manager");
+
+ // The card must not have empty or misleading external links
+ const externalLinks = guyCard.locator("a");
+ await expect(externalLinks).toHaveCount(0);
+ });
+
+ test("established contributors have appropriate social/GitHub links", async ({ page }) => {
+ const harshaCard = page.locator(".card").filter({ hasText: "Harsha Vardhan Burra" });
+ await expect(harshaCard).toBeVisible();
+
+ // Verify GitHub link
+ const githubLink = harshaCard.locator("a[href*='github.com/harsha-vardhan-burra']");
+ await expect(githubLink).toBeVisible();
+ });
+});
diff --git a/tests/smoke/downloads.spec.ts b/tests/smoke/downloads.spec.ts
new file mode 100644
index 0000000..ec41e53
--- /dev/null
+++ b/tests/smoke/downloads.spec.ts
@@ -0,0 +1,52 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Downloads Page Smoke & Regression Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/downloads/");
+ });
+
+ test("downloads page loads and displays release archive", async ({ page }) => {
+ await expect(page).toHaveTitle(/Downloads/i);
+ await expect(page.getByRole("heading", { name: "Downloads & Releases", level: 1 })).toBeVisible();
+
+ // Release list container
+ const releaseCards = page.locator(".release-card");
+ await expect(releaseCards.first()).toBeVisible();
+ });
+
+ test("recommended production build displays architecture download options", async ({ page }) => {
+ // Recommended production build section
+ await expect(page.getByText("Recommended Production Build")).toBeVisible();
+
+ // Download controls are rendered
+ const downloadOptions = page.locator(".arch-download-btn, .arch-dropdown, a[href*='.apk']");
+ await expect(downloadOptions.first()).toBeVisible();
+ });
+
+ test("deprecated v1.x and v2.x releases display deprecation indicators while v3.x does not", async ({ page }) => {
+ // v3.2.1 is current/stable and must NOT be marked deprecated
+ const v3Card = page.locator(".release-card").filter({ hasText: /v3\.2\.1/i }).first();
+ await expect(v3Card).toBeVisible();
+ await expect(v3Card.locator(".tag.deprecated")).toHaveCount(0);
+
+ // v2.1.1 is an older major version and MUST display deprecated badge
+ const v2Card = page.locator(".release-card").filter({ hasText: /v2\.1\.1/i }).first();
+ await expect(v2Card).toBeVisible();
+ await expect(v2Card.locator(".tag.deprecated")).toBeVisible();
+ await expect(v2Card.getByText(/Deprecated Release/i)).toBeVisible();
+
+ // v1.0.0 is an older major version and MUST display deprecated badge
+ const v1Card = page.locator(".release-card").filter({ hasText: /v1\.0\.0/i }).first();
+ await expect(v1Card).toBeVisible();
+ await expect(v1Card.locator(".tag.deprecated")).toBeVisible();
+ });
+
+ test("yanked release v1.2.0 displays both yanked and deprecated statuses cleanly", async ({ page }) => {
+ const v120Card = page.locator(".release-card").filter({ hasText: /v1\.2\.0/i }).first();
+ await expect(v120Card).toBeVisible();
+
+ // Both distinct statuses coexist
+ await expect(v120Card.locator(".tag.deprecated")).toBeVisible();
+ await expect(v120Card.locator(".tag").filter({ hasText: /yanked/i })).toBeVisible();
+ });
+});
diff --git a/tests/smoke/footer.spec.ts b/tests/smoke/footer.spec.ts
new file mode 100644
index 0000000..11ecf28
--- /dev/null
+++ b/tests/smoke/footer.spec.ts
@@ -0,0 +1,42 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Footer Contributor Credit & Integrity Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/");
+ });
+
+ test("footer contains Design by @harsha-vardhan-burra credit pointing to GitHub", async ({ page }) => {
+ const footer = page.locator("footer.site-footer");
+ await expect(footer).toBeVisible();
+
+ // The attribution text "Design by" is visible in footer
+ await expect(footer.getByText(/Design by/i)).toBeVisible();
+
+ // The link with handle @harsha-vardhan-burra
+ const creditLink = footer.getByRole("link", { name: /@harsha-vardhan-burra/i });
+ await expect(creditLink).toBeVisible();
+ await expect(creditLink).toHaveCount(1);
+ await expect(creditLink).toHaveAttribute("href", "https://github.com/harsha-vardhan-burra");
+ await expect(creditLink).toHaveAttribute("target", "_blank");
+ await expect(creditLink).toHaveAttribute("rel", /noopener/);
+
+ // Accessible label / title includes full name
+ const accessibleName = await creditLink.getAttribute("aria-label");
+ const titleAttr = await creditLink.getAttribute("title");
+ const hasAccessibleIdentity =
+ (accessibleName && accessibleName.includes("Harsha Vardhan Burra")) ||
+ (titleAttr && titleAttr.includes("Harsha Vardhan Burra"));
+ expect(hasAccessibleIdentity).toBe(true);
+ });
+
+ test("footer preserves privacy/security and copyright messaging", async ({ page }) => {
+ const footer = page.locator("footer.site-footer");
+
+ // Copyright message
+ await expect(footer.getByText(/Copyright © Jeel Dobariya/i)).toBeVisible();
+
+ // Privacy messaging
+ await expect(footer.getByText(/Crafted for privacy and local control/i)).toBeVisible();
+ await expect(footer.getByText(/zero cloud, zero trackers/i)).toBeVisible();
+ });
+});
diff --git a/tests/smoke/homepage.spec.ts b/tests/smoke/homepage.spec.ts
new file mode 100644
index 0000000..734128d
--- /dev/null
+++ b/tests/smoke/homepage.spec.ts
@@ -0,0 +1,48 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Homepage Smoke Tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto("/");
+ });
+
+ test("homepage loads successfully and displays core branding", async ({ page }) => {
+ await expect(page).toHaveTitle(/Passcodes/i);
+ const heading = page.getByRole("heading", { level: 1 });
+ await expect(heading).toBeVisible();
+ await expect(heading).toContainText("passwords");
+ });
+
+ test("hero section contains primary CTAs and release info", async ({ page }) => {
+ // Primary Call to Action
+ const downloadCTA = page.getByRole("link", { name: /Download for Android/i });
+ await expect(downloadCTA).toBeVisible();
+ await expect(downloadCTA).toHaveAttribute("href", "/downloads/");
+
+ // GitHub Repository Link
+ const githubCTA = page.getByRole("link", { name: /View on GitHub/i });
+ await expect(githubCTA).toBeVisible();
+ await expect(githubCTA).toHaveAttribute("href", /github\.com\/PasscodesApp\/Passcodes/);
+
+ // Current release announcement badge
+ const releasePill = page.getByRole("link", { name: /v3\.\d+\.\d+.*is live/i });
+ await expect(releasePill).toBeVisible();
+ });
+
+ test("primary navigation links are functional", async ({ page }) => {
+ const nav = page.getByRole("navigation", { name: "Main navigation" });
+
+ // Downloads navigation
+ const downloadsLink = nav.getByRole("link", { name: "Downloads" });
+ if (await downloadsLink.isVisible()) {
+ await downloadsLink.click();
+ await expect(page).toHaveURL(/\/downloads\/?$/);
+ await expect(page.getByRole("heading", { name: /Downloads/i, level: 1 })).toBeVisible();
+ }
+ });
+
+ test("core trust features are presented", async ({ page }) => {
+ await expect(page.getByRole("heading", { name: "On-Device Storage" })).toBeVisible();
+ await expect(page.getByRole("heading", { name: "Designed for Offline Privacy" })).toBeVisible();
+ await expect(page.getByRole("heading", { name: "100% Open Source" })).toBeVisible();
+ });
+});
diff --git a/tests/smoke/mobile.spec.ts b/tests/smoke/mobile.spec.ts
new file mode 100644
index 0000000..8ea8988
--- /dev/null
+++ b/tests/smoke/mobile.spec.ts
@@ -0,0 +1,50 @@
+import { test, expect } from "../fixtures/base-test";
+
+test.describe("Mobile Responsive Usability Tests", () => {
+ test("mobile navigation drawer opens and navigates", async ({ page, isMobile }) => {
+ // Run mobile menu tests on mobile projects
+ test.skip(!isMobile, "Mobile-specific drawer test only applies to mobile viewports");
+
+ await page.goto("/");
+
+ // Open menu button
+ const menuBtn = page.getByRole("button", { name: "Open menu" });
+ await expect(menuBtn).toBeVisible();
+ await menuBtn.click();
+
+ // Drawer should be open
+ const mobileDrawer = page.locator("#mobile-menu");
+ await expect(mobileDrawer).toBeVisible();
+
+ // Navigation links visible inside drawer
+ const downloadsLink = mobileDrawer.getByRole("link", { name: "Downloads" });
+ await expect(downloadsLink).toBeVisible();
+ await downloadsLink.click();
+
+ await expect(page).toHaveURL(/\/downloads\/?$/);
+ });
+
+ test("downloads page does not horizontally overflow viewport on mobile", async ({ page, isMobile }) => {
+ test.skip(!isMobile, "Horizontal overflow check targeted for mobile viewports");
+
+ await page.goto("/downloads/");
+
+ const hasHorizontalOverflow = await page.evaluate(() => {
+ return document.documentElement.scrollWidth > window.innerWidth;
+ });
+
+ expect(hasHorizontalOverflow, "Page has unexpected horizontal overflow").toBe(false);
+ });
+
+ test("changelog page does not horizontally overflow viewport on mobile", async ({ page, isMobile }) => {
+ test.skip(!isMobile, "Horizontal overflow check targeted for mobile viewports");
+
+ await page.goto("/changelog/");
+
+ const hasHorizontalOverflow = await page.evaluate(() => {
+ return document.documentElement.scrollWidth > window.innerWidth;
+ });
+
+ expect(hasHorizontalOverflow, "Changelog has unexpected horizontal overflow").toBe(false);
+ });
+});
From ad00168694d03c42ceee6da37999ca6b4fe01ca8 Mon Sep 17 00:00:00 2001
From: harsha-vardhan-burra
Date: Sat, 12 Sep 2026 14:00:17 +0530
Subject: [PATCH 10/11] perf(site): optimize Lighthouse performance and
accessibility
Signed-off-by: harsha-vardhan-burra
---
next.config.mjs | 2 ++
package.json | 9 ++++-
public/komi-store-badge.png | Bin 607812 -> 83329 bytes
public/komi-store-badge.webp | Bin 0 -> 8598 bytes
public/logo.png | Bin 45169 -> 9404 bytes
public/logo.webp | Bin 0 -> 2068 bytes
src/app/layout.tsx | 32 ++++++++++++++++--
src/components/downloads/ArchDownload.tsx | 4 ---
src/components/downloads/DownloadsContent.tsx | 31 +++++++++++------
src/components/layout/Logo.tsx | 25 +++++++++-----
src/components/layout/Navbar.tsx | 2 +-
src/data/normalized-releases.json | 2 +-
src/data/raw-releases.json | 8 ++---
src/lib/constants.ts | 2 ++
src/styles/globals.css | 12 ++++---
15 files changed, 91 insertions(+), 38 deletions(-)
create mode 100644 public/komi-store-badge.webp
create mode 100644 public/logo.webp
diff --git a/next.config.mjs b/next.config.mjs
index 8a90a44..07adf8d 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -22,6 +22,8 @@ const nextConfig = {
{ protocol: 'https', hostname: 'raw.githubusercontent.com' },
],
},
+
+ productionBrowserSourceMaps: true,
};
export default nextConfig;
diff --git a/package.json b/package.json
index 2106949..07e838d 100644
--- a/package.json
+++ b/package.json
@@ -42,5 +42,12 @@
"serve": "^14.2.6",
"tailwindcss": "^3.4.0",
"typescript": "^5.5.0"
- }
+ },
+ "browserslist": [
+ "last 2 Chrome versions",
+ "last 2 Firefox versions",
+ "last 2 Safari versions",
+ "last 2 Edge versions",
+ "not dead"
+ ]
}
diff --git a/public/komi-store-badge.png b/public/komi-store-badge.png
index d0b5c0716d0758c4d3836960eecf3bc74b75035d..503640ac4072b7d6102392b5866c172d7d903f2d 100644
GIT binary patch
literal 83329
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