Files
seedpgp-web/GEMINI.md
2026-01-30 17:33:08 +08:00

10 KiB

SeedPGP - Gemini Code Assist Project Brief

Project Overview

SeedPGP v1.4.2: Client-side BIP39 mnemonic encryption webapp
Stack: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS
Deploy: GitHub Pages (public repo: seedpgp-web-app, private source: seedpgp-web)
Live URL: https://kccleoc.github.io/seedpgp-web-app/

Core Constraints

  1. Security-first: Never persist secrets (mnemonic/passphrase/private keys) to localStorage/sessionStorage/IndexedDB
  2. Small PRs: Max 1-5 files per feature; propose plan before coding
  3. Client-side only: No backend; all crypto runs in browser (Web Crypto API + OpenPGP.js)
  4. GitHub Pages deploy: Base path /seedpgp-web-app/ configured in vite.config.ts
  5. Honest security claims: Don't overclaim what client-side JS can guarantee

Non-Negotiables

  • Small diffs only: one feature slice per PR (1-5 files if possible)
  • No big code dumps; propose plan first, then implement
  • Never persist secrets to browser storage
  • Prefer "explain what you found in the repo" over guessing
  • TypeScript strict mode; no any types without justification

Architecture Map

Entry Points

  • src/main.tsxsrc/App.tsx (main application)
  • Build output: dist/ (separate git repo for GitHub Pages deployment)

Directory Structure

src/
├── components/        # React UI components
│   ├── PgpKeyInput.tsx
│   ├── QrDisplay.tsx
│   ├── QrScanner.tsx
│   ├── ReadOnly.tsx
│   ├── StorageIndicator.tsx
│   ├── SecurityWarnings.tsx
│   └── ClipboardTracker.tsx
├── lib/              # Core logic & crypto utilities
│   ├── seedpgp.ts    # Main encrypt/decrypt functions
│   ├── sessionCrypto.ts  # Ephemeral AES-GCM session keys
│   ├── types.ts      # TypeScript interfaces
│   └── qr.ts         # QR code utilities
├── App.tsx           # Main app component
└── main.tsx          # React entry point

Key Modules

src/lib/seedpgp.ts

Core encryption/decryption:

  • encryptToSeedPgp() - Encrypts mnemonic with PGP public key + optional password
  • decryptFromSeedPgp() - Decrypts with PGP private key + optional password
  • Uses OpenPGP.js for PGP operations
  • Output format: SEEDPGP1:version:base64data:fingerprint

src/lib/sessionCrypto.ts (v1.3.0+)

Ephemeral session-key encryption:

  • getSessionKey() - Generates/returns non-exportable AES-GCM-256 key (idempotent)
  • encryptJsonToBlob(obj) - Encrypts to {v, alg, iv_b64, ct_b64}
  • decryptBlobToJson(blob) - Decrypts back to original object
  • destroySessionKey() - Drops key reference for garbage collection
  • Test: await window.runSessionCryptoTest() (DEV only)

src/lib/types.ts

Core interfaces:

  • SeedPgpPlaintext - Decrypted mnemonic data structure
  • SeedPgpCiphertext - Encrypted payload structure
  • EncryptedBlob - Session-key encrypted cache format

Key Features

v1.0 - Core Functionality

  • Backup: Encrypt mnemonic with PGP public key + optional password → QR display
  • Restore: Scan/paste QR → decrypt with private key → show mnemonic
  • PGP support: Import public/private keys (.asc files or paste)

v1.1 - QR Features

  • QR Display: Generate QR codes from encrypted data
  • QR Scanner: Camera + file upload (uses html5-qrcode library)

v1.2 - Security Monitoring

  • Storage Indicator: Real-time display of localStorage/sessionStorage contents
  • Security Warnings: Context-aware alerts about browser memory limitations
  • Clipboard Tracker: Monitor clipboard operations on sensitive fields
  • Read-only Mode: Toggle to clear state + show CSP/build info

v1.3-v1.4 - Session-Key Encryption

  • Ephemeral encryption: AES-GCM-256 session key (non-exportable) encrypts sensitive state
  • Backup flow (v1.3): Mnemonic auto-clears immediately after QR generation
  • Restore flow (v1.4): Decrypted mnemonic auto-clears after 10 seconds + manual Hide button
  • Encrypted cache: Only ciphertext stored in React state; key lives in memory only
  • Lock/Clear: Manual cleanup destroys session key + clears all state
  • Lifecycle: Session key auto-destroyed on page close/refresh

Development Workflow

Commands

bun install           # Install dependencies
bun run dev           # Dev server (localhost:5173)
bun run build         # Build to dist/
bun run typecheck     # TypeScript validation (tsc --noEmit)
bun run preview       # Preview production build
./scripts/deploy.sh v1.x.x  # Build + push to public repo

Deployment Process

  1. Private repo (seedpgp-web): Source code, development
  2. Public repo (seedpgp-web-app): Built files for GitHub Pages
  3. Deploy script (scripts/deploy.sh): Builds + copies to dist/ + pushes to public repo

Git Workflow

# Commit feature
git add src/
git commit -m "feat(v1.x): description"

# Tag version
git tag v1.x.x
git push origin main --tags

# Deploy to GitHub Pages
./scripts/deploy.sh v1.x.x

Required Workflow for AI Agents

1. Study First

Before implementing any feature:

  • Read relevant files
  • Explain current architecture + entry points
  • List files that will be touched
  • Identify potential conflicts or dependencies

2. Plan

  • Propose smallest vertical slice (1-5 files)
  • Show API signatures or interface changes first
  • Get approval before generating full implementation

3. Implement

  • Generate code with TypeScript strict mode
  • Include JSDoc comments for public APIs
  • Show unified diffs, not full file rewrites (when possible)
  • Keep changes under 50-100 lines per file when feasible

4. Verify

  • Run bun run typecheck - no errors
  • Run bun run build - successful dist/ output
  • Provide manual test steps for browser verification
  • Show build output / console logs / DevTools screenshots

Common Patterns

State Management

  • React useState + useEffect (no Redux/Zustand/external store)
  • Ephemeral state only; avoid persistent storage for secrets

Styling

  • Tailwind utility classes (configured in tailwind.config.js)
  • Responsive design: mobile-first with md: breakpoints
  • Dark theme primary: slate-900 background, blue-400 accents

Icons

  • lucide-react library
  • Common: Shield, QrCode, Lock, Eye, AlertCircle

Crypto Operations

  • PGP: OpenPGP.js (openpgp package)
  • Session keys: Web Crypto API (crypto.subtle)
  • Key generation: crypto.subtle.generateKey() with extractable: false
  • Encryption: AES-GCM with random 12-byte IV per operation

Type Safety

  • Strict TypeScript (tsconfig.json: strict: true)
  • Check src/lib/types.ts for core interfaces
  • Avoid any; use unknown + type guards when necessary

Security Architecture

Threat Model (Honest)

What we protect against:

  • Accidental persistence to localStorage/sessionStorage
  • Plaintext secrets lingering in React state after use
  • Clipboard history exposure (with warnings)

What we DON'T protect against (and must not claim to):

  • Active XSS or malicious browser extensions
  • Memory dumps or browser crash reports
  • JavaScript garbage collection timing (non-deterministic)

Memory Handling

  • Session keys: Non-exportable CryptoKey objects (Web Crypto API)
  • Plaintext clearing: Set to empty string + drop references (but GC timing is non-deterministic)
  • No guarantees: Cannot force immediate memory wiping in JavaScript

Storage Policy

  • NEVER write to: localStorage, sessionStorage, IndexedDB, cookies
  • Exception: Non-sensitive UI state only (theme preferences, etc.) - NOT IMPLEMENTED YET
  • Verification: StorageIndicator component monitors all storage APIs

What NOT to Do

Code Generation

  • Don't generate full file rewrites unless necessary
  • Don't add dependencies without discussing bundle size impact
  • Don't use any types without explicit justification
  • Don't skip TypeScript strict mode checks

Security Claims

  • Don't claim "RAM is wiped" (JavaScript can't force GC)
  • Don't claim "offline mode" without real CSP headers (GitHub Pages can't set custom headers)
  • Don't promise protection against active browser compromise (XSS/extensions)

Storage

  • Don't write secrets to storage without explicit approval
  • Don't cache decrypted data beyond immediate use
  • Don't assume browser storage is secure

Testing & Verification

Manual Test Checklist (Before Marking Feature Complete)

  1. bun run typecheck passes (no TypeScript errors)
  2. bun run build succeeds (dist/ generated)
  3. Browser test: Feature works as described
  4. DevTools Console: No runtime errors
  5. DevTools Application tab: No plaintext secrets in storage
  6. DevTools Network tab: No unexpected network calls (if Read-only Mode)

Session-Key Encryption Test (v1.3+)

// In browser DevTools console:
await window.runSessionCryptoTest()
// Expected: ✅ Success: Data integrity verified.

Current Version: v1.4.2

Please update the "Recent Changes", "Known Limitations", and "Next Priorities" sections to reflect the current state of the project.


Quick Reference

File a Bug/Feature

  1. Describe expected vs actual behavior
  2. Include browser console errors (if any)
  3. Specify which flow (Backup/Restore/QR Scanner)

Roll Over to Next Session

Always provide:

  • Current version number
  • What was implemented this session
  • Files modified
  • What still needs work
  • Any gotchas or edge cases discovered

Example Prompts for Gemini

Exploration

Read GEMINI.md, then explain:
1. Where is the mnemonic textarea and how is its value managed?
2. List all places localStorage/sessionStorage are used
3. Show data flow from "Backup" button to QR display

Feature Request

Task: [Feature description]

Requirements:
1. [Specific requirement]
2. [Another requirement]

Files to touch:
- [List files]

Plan first: show proposed API/changes before generating code.

Verification

Audit the codebase to verify [feature] is fully implemented.
Check:
1. [Requirement 1]
2. [Requirement 2]
Output: ✅ or ❌ for each item + suggest fixes for failures.

Last Updated: 2026-01-29
Maintained by: @kccleoc
AI Agent: Optimized for Gemini Code Assist