Distinguish natural human composition from AI-generated content through behavioral analysis
π Live Demo: https://interproject-client.vercel.app
π API Backend: https://interproject-3.onrender.com
Vi-Notes is built on a simple yet powerful principle: authenticity is stronger when content and behavior agree.
Human writing naturally includes:
- βΈοΈ Pauses and hesitations
- βοΈ Rewrites and corrections
- β‘ Bursts of typing activity
- π Natural editing patterns
AI-assisted or pasted content often shows mismatches between the text and how it was produced. Vi-Notes captures behavioral metadata in real-time and pairs it with session analytics to provide verifiable authorship evidence.
- Email/password registration and login
- JWT access tokens with HTTP-only refresh cookies
- Automatic token refresh during active sessions
- Refresh token rotation with server-side revocation
- Rate limiting on auth endpoints
- Hashed refresh token persistence (SHA-256)
- Distraction-free writing environment
- Full formatting support (bold, italic, underline, headings)
- Multiple font families and sizes
- Text and highlight color customization
- List support (ordered and unordered)
- Text alignment options
- Per-file formatting persistence
- Auto-save scroll position
- Keystroke timing capture (down/up timestamps, press duration)
- Paste detection with length and selection metadata
- Edit tracking for pasted content modifications
- Pause detection (3-second inactivity threshold)
- WPM (Words Per Minute) real-time calculation
- Privacy-first: Only metadata stored, never actual keystrokes
- Create and incrementally update writing sessions
- Automatic session analytics on close
- Session history with detailed metrics
- Resume previous sessions
- Offline-first architecture with IndexedDB buffering
- Advanced WPM profiling - Rolling velocity analysis with 10-keystroke windows
- WPM variance & coefficient of variation - Typing rhythm consistency detection
- Intelligent pause modeling - Micro-pause (300-2000ms) vs macro-pause (β₯2000ms) classification
- Pause entropy calculation - Natural vs robotic pattern detection
- Edit ratio - Revision behavior analysis
- Paste ratio - External content detection
- Character statistics - Insertions, deletions, final count
- Duration tracking - Total writing time
- Behavioral consistency scoring - Multi-factor authenticity analysis
- Distribution-based stability metrics - Inter-keystroke interval analysis
- Durable client-side keystroke queue in IndexedDB
- Automatic replay on reconnect
- Exponential backoff retry logic
- User-facing error notifications
- Deferred session close when unsynced data remains
- Light and dark theme support
- Responsive design (mobile, tablet, desktop)
- Real-time status badges
- Session visualization with charts
- Overview dashboard with key metrics
- Protected and guest route guards
Vi-Notes is built as a TypeScript monorepo with three main packages:
vi-notes/
βββ client/ # React frontend (Vite)
βββ server/ # Express backend (Node.js)
βββ shared/ # Shared TypeScript types
| Layer | Technologies | Purpose |
|---|---|---|
| Frontend | React 19, TypeScript, Vite, Axios, Tailwind CSS | Editor UI, event capture, auth, sync scheduling |
| Backend | Node.js, Express, TypeScript, Mongoose, Zod | Auth, session APIs, validation, analytics |
| Shared | TypeScript workspace package | Cross-package type contracts |
| Database | MongoDB | Users, refresh tokens, documents, sessions |
| Security | bcrypt, JWT, express-rate-limit | Password hashing, token management, rate limiting |
- Node.js 20+ and npm 10+
- MongoDB (local or cloud instance)
-
Clone the repository
git clone <repository-url> cd vi-notes
-
Install dependencies
npm install
-
Configure environment variables
Create
server/.envfrom the example:cp server/.env.example server/.env
Update the following required variables:
MONGODB_URI=mongodb://localhost:27017/vi-notes JWT_SECRET=your_super_secret_key_here JWT_REFRESH_SECRET=your_refresh_secret_key_here
Optional variables (with defaults):
JWT_ACCESS_EXPIRES_IN=15m REFRESH_TOKEN_TTL_DAYS=7 REFRESH_COOKIE_NAME=refreshToken CLIENT_ORIGIN=http://127.0.0.1:5173 NODE_ENV=development PORT=5000
-
Start development servers
npm run dev
This starts:
- Client: http://127.0.0.1:5173 (Vite dev server)
- Server: http://127.0.0.1:5000 (Express API)
http://127.0.0.1:5000
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/auth/register |
None | Create user account |
POST |
/api/auth/login |
None | Login and issue tokens |
POST |
/api/auth/refresh |
Refresh cookie | Rotate refresh token and issue new access token |
POST |
/api/auth/logout |
Optional refresh cookie | Revoke token and clear cookie |
All require Authorization: Bearer <accessToken>
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/documents |
List user's documents |
POST |
/api/documents |
Create new document |
GET |
/api/documents/:id |
Get document details |
PATCH |
/api/documents/:id |
Rename document |
PATCH |
/api/documents/:id/content |
Update document content |
DELETE |
/api/documents/:id |
Delete document |
All require Authorization: Bearer <accessToken>
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/sessions |
Create new session |
PATCH |
/api/sessions/:id |
Append keystrokes to session |
GET |
/api/sessions |
List sessions (with optional documentId filter) |
GET |
/api/sessions/:id |
Get session details |
POST |
/api/sessions/:id/close |
Close session and compute analytics |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/analytics/:documentId |
Bearer token | Get document analytics |
down- Key press startup- Key releasepaste- Paste operationedit- Text modification
{
version: number;
approximateWpmVariance: number; // Average WPM
pauseFrequency: number; // Macro-pause count
editRatio: number; // Deletions / final chars
pasteRatio: number; // Pasted / total inserted
totalInsertedChars: number;
totalDeletedChars: number;
finalChars: number;
totalPastedChars: number;
pauseCount: number; // Macro-pauses (β₯2000ms)
microPauseCount: number; // Micro-pauses (300-2000ms)
durationMs: number;
wpm: number; // Rolling window WPM
wpmVariance: number; // WPM standard deviation
coefficientOfVariation: number; // Normalized typing consistency
textAnalysis: {
avgSentenceLength: number;
sentenceVariance: number;
lexicalDiversity: number;
totalWords: number;
totalSentences: number;
};
authenticity: {
score: number;
label: string;
behavioralScore: number;
textualScore: number;
crossCheckScore: number;
};
flags: string[]; // Anomaly detection flags
}# Run both client and server in development mode
npm run dev
# Type-check all packages
npm run typecheck
# Build client for production
npm run build
# Lint client code
npm run lint -w clientvi-notes/
βββ client/
β βββ src/
β β βββ components/ # Reusable UI components
β β βββ contexts/ # React context providers
β β βββ hooks/ # Custom React hooks
β β βββ lib/ # Utility functions
β β βββ offline/ # IndexedDB queue management
β β βββ pages/ # Route pages
β β βββ routes/ # Route guards
β β βββ api.ts # Axios instance & auth helpers
β β βββ App.tsx # Main app component
β β βββ styles.css # Global styles
β βββ package.json
β βββ vite.config.ts
βββ server/
β βββ src/
β β βββ controllers/ # Request handlers
β β βββ middleware/ # Express middleware
β β βββ models/ # Mongoose schemas
β β βββ routes/ # API routes
β β βββ services/ # Business logic
β β βββ types/ # TypeScript definitions
β β βββ app.ts # Express app setup
β β βββ config.ts # Environment config
β β βββ server.ts # Server entry point
β βββ .env.example
β βββ package.json
βββ shared/
β βββ src/
β β βββ auth.ts # Auth types
β β βββ document.ts # Document types
β β βββ keystroke.ts # Keystroke types
β β βββ session.ts # Session types
β β βββ index.ts # Barrel export
β βββ package.json
βββ package.json # Root workspace config
- Keystroke sanitization middleware strips content fields from payloads
- Event model stores structural and timing metadata only, not raw text
- Cookie security defaults:
httpOnly,sameSiteprotections - Access tokens stored in
sessionStorage(tab-scoped, cleared on close)
- Passwords hashed with bcrypt (10 rounds)
- JWT tokens with short expiration (15 minutes default)
- Refresh token rotation prevents token reuse
- Server-side token revocation tracking
- Rate limiting on login/register endpoints
- 3-Layer NaN Protection:
- Layer 1: Safe math functions (
safeNumber,safeDivide,safeLog) - Layer 2: Protected calculations in all analytics services
- Layer 3: Deep sanitization before MongoDB persistence
- Layer 1: Safe math functions (
- All numeric fields have default values (0) in database schema
- Division-by-zero prevention across all calculations
- Automatic fallback to safe values for invalid inputs
- Base background:
#F8F8F6 - Clean, minimal aesthetic
- High contrast for readability
- Base background:
#22221F - Reduced eye strain
- Modern, professional appearance
Theme preference persists across sessions.
- No automated test suite configured
- Root build script targets client only
- Web-first implementation (no native desktop capture)
- β Advanced velocity profiling with rolling WPM windows
- β Intelligent pause modeling (micro/macro + entropy)
- β Distribution-based behavioral consistency analysis
- β Enhanced authenticity scoring with multi-factor analysis
- β NaN Protection System - 3-layer validation preventing invalid numeric values in analytics
- π§ͺ Comprehensive test suite (unit, integration, e2e)
- π Richer authenticity reports with visual evidence
- π€ Machine learning-based anomaly detection
- π Progressive adaptation to evolving AI patterns
- π» Native desktop packaging with OS-level telemetry
- π± Mobile app with native keyboard tracking
- π Multi-language support
- π Integration with learning management systems (LMS)
Mentor: Jinal Gupta
This project is proprietary software. No license file is currently present.
This is a private project. Contributions are currently not accepted.
For questions or issues, please contact the project maintainer.
Built with β€οΈ for authentic writing