Skip to content

thinktwiceco/thinktwice-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

97 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Lint and Format

ThinkTwice πŸ€”

A Chrome browser extension that helps users make more thoughtful purchasing decisions on Amazon by providing behavioral nudges, delayed gratification tools, and purchase alternatives.

πŸ“‘ Table of Contents


🎯 Project Idea & Goal

ThinkTwice intervenes at the moment of purchase to help users pause and reconsider whether they truly need an item. The extension appears on Amazon product pages and presents users with:

  • Behavioral nudges - Thoughtful prompts to reconsider the purchase
  • "Sleep on it" reminders - Set timed reminders to reconsider purchases after 24 hours (or custom durations)
  • Alternative considerations - Explore DIY, refurbished, or rental options
  • Investment opportunities - Learn about investing the money you save

Core Philosophy

The extension is designed around behavioral economics principles:

  • Delayed gratification: Research shows 3 out of 4 people change their mind within 24 hours
  • Conscious consumption: Make intentional decisions rather than impulse purchases
  • Financial wellness: Redirect saved money toward long-term goals

πŸ“Š Project Status

βœ… Implemented Features

Core Functionality

  • Product page intervention - Overlay appears on Amazon product pages with decision options
  • Behavioral nudges - Random nudges displayed to encourage thoughtful consideration
  • Three decision paths:
    • "I don't really need it" β†’ Investment options view
    • "Sleep on it" β†’ Reminder system with browser notifications
    • "I need it" β†’ Confirmation and proceed to purchase

Sleep On It System (Fully Implemented)

  • Reminder scheduling with customizable durations:
    • 1 minute (debug/testing)
    • 1 hour, 6 hours, 24 hours
    • 3 days, 1 week
  • Product data extraction - Automatically captures product name, price, image, and URL
  • Chrome Alarms API integration - Reliable scheduled notifications
  • Browser notifications - Alerts when it's time to reconsider
  • Extension badge count - Shows number of pending due reminders
  • Popup interface - View all pending reminders with actions:
    • "Still interested" β†’ Opens product page
    • "Not interested" β†’ Dismisses reminder

Data Persistence

  • Chrome Storage API integration - All data stored locally
  • Storage abstraction layer with TypeScript interfaces
  • Message passing architecture for content scripts
  • Normalized data structure - Products stored separately from reminders

⚠️ Partially Implemented

  • Investment options flow - UI exists but handlers are basic (console logs only)
  • Close/dismiss behavior - Handler exists but needs refinement

πŸ“‹ Planned Features (Not Yet Implemented)

  • Alternative purchase options - DIY, Refurbished, Rent/Borrow flows
  • Settings page - Customize notification preferences and reminder durations
  • Statistics dashboard - Track money saved, purchases avoided
  • Enhanced nudges system - Context-aware, personalized nudges
  • Multi-marketplace support - Expand beyond Amazon (eBay, Walmart, etc.)
  • Social features - Share decisions, group savings challenges

See test flow documentation in tests/flows/ for detailed user flow testing scenarios.


πŸ› οΈ Technology Stack

  • Framework: Plasmo - Modern Chrome Extension framework
  • UI Library: React 19 with TypeScript
  • Storage: Chrome Storage API (local persistence)
  • Notifications: Chrome Alarms & Notifications APIs
  • Build Tool: Parcel (via Plasmo)
  • Linting: ESLint with TypeScript and React plugins
  • Formatting: Prettier with import sorting

πŸš€ Local Development Setup

Prerequisites

  • Node.js: Version 22.18.0 (exact version specified in package.json)
    node --version  # Should output v22.18.0
  • npm: Comes with Node.js
  • Google Chrome: Latest version

Installation

  1. Clone the repository

    cd /home/verte/Desktop/Thinktwice/plugin-3
  2. Install dependencies

    npm install
  3. Start development server

    npm run dev

    This will:

    • Start Plasmo development server
    • Watch for file changes
    • Build extension to build/chrome-mv3-dev/
    • Hot reload changes automatically

Loading Extension in Chrome

  1. Open Chrome and navigate to chrome://extensions/
  2. Enable Developer mode (toggle in top-right corner)
  3. Click "Load unpacked"
  4. Select the build/chrome-mv3-dev/ directory
  5. The ThinkTwice extension should now appear in your extensions list

Development Workflow

  1. Make changes to source files (.tsx, .ts, .css)
  2. Plasmo will automatically rebuild
  3. Reload the extension in Chrome:
    • Click the refresh icon on the extension card in chrome://extensions/
    • Or use the keyboard shortcut: Ctrl+R (Windows/Linux) or Cmd+R (Mac) while focused on the extension

Testing the Extension

  1. Visit an Amazon product page

    https://www.amazon.com/dp/B0XXXXXXX
    
  2. Test the intervention flow

    • ThinkTwice overlay should appear
    • Click "Sleep on it" button
    • Select a reminder duration (try "1 minute" for quick testing)
    • Click "Set Reminder"
  3. Test reminder notifications

    • Wait for the reminder duration to elapse
    • Browser notification should appear
    • Extension badge should show "1"
    • Click extension icon to see reminder in popup
  4. Test reminder actions

    • "Still interested" β†’ Opens product page
    • "Not interested" β†’ Removes reminder

Available Scripts

# Development
npm run dev              # Start development server with hot reload

# Production
npm run build            # Build production-ready extension
npm run package          # Package extension for distribution

# Testing
npm run test:e2e         # Run end-to-end tests with Playwright

# Code Quality
npm run lint             # Run ESLint
npm run lint:fix         # Fix ESLint errors automatically
npm run format           # Format code with Prettier
npm run format:check     # Check code formatting

πŸ“ Project Structure

plugin-3/
β”œβ”€β”€ .github/             # GitHub configuration
β”‚   β”œβ”€β”€ workflows/       # CI/CD workflows
β”‚   β”‚   β”œβ”€β”€ lint-and-format.yml    # Code quality checks
β”‚   β”‚   β”œβ”€β”€ update-version.yml     # Release validation
β”‚   β”‚   └── submit.yml             # Chrome Web Store submission
β”‚   └── CODEOWNERS       # Code ownership configuration
β”œβ”€β”€ assets/              # Static assets (icons, images)
β”‚   └── icons/           # Extension icons and UI icons (7 files)
β”œβ”€β”€ components/          # Reusable React components
β”‚   β”œβ”€β”€ Nudge.tsx        # Behavioral nudge display
β”‚   └── ui/              # UI component library (10 components)
β”‚       β”œβ”€β”€ Button.tsx
β”‚       β”œβ”€β”€ Card.tsx
β”‚       β”œβ”€β”€ Header.tsx
β”‚       β”œβ”€β”€ Loading.tsx
β”‚       β”œβ”€β”€ Skeleton.tsx
β”‚       └── ... (5 more)
β”œβ”€β”€ contents/            # Content scripts (injected into web pages)
β”‚   └── amazon.tsx       # Main Amazon product page content script
β”œβ”€β”€ docs/                # Documentation (6 files)
β”‚   β”œβ”€β”€ ARCHITECTURE.md        # System architecture overview
β”‚   β”œβ”€β”€ VERSIONING-CHEATSHEET.md  # Version management quick reference
β”‚   β”œβ”€β”€ VERSIONING-WORKFLOW.md    # Release workflow guide
β”‚   β”œβ”€β”€ chrome-runtime-messages.md  # Message passing documentation
β”‚   β”œβ”€β”€ sleep-on-it-implementation.md  # Feature implementation details
β”‚   └── desktop-app-integration-plan.md  # Desktop app integration plan
β”œβ”€β”€ hooks/               # Custom React hooks (4 files)
β”‚   β”œβ”€β”€ useStorage.ts           # Chrome storage reactive hook
β”‚   β”œβ”€β”€ usePendingReminder.ts   # Reminder state management
β”‚   β”œβ”€β”€ useProductPageState.ts  # Product page state management
β”‚   └── useGoogleFonts.ts       # Google Fonts loading hook
β”œβ”€β”€ managers/            # Business logic managers (2 files)
β”‚   β”œβ”€β”€ index.ts                # Manager exports
β”‚   └── ProductActionManager.ts # Product action orchestration
β”œβ”€β”€ scripts/             # Build and utility scripts
β”‚   └── validate-tag.sh  # Git tag validation script
β”œβ”€β”€ services/            # Core services (6 files)
β”‚   β”œβ”€β”€ AlarmService.ts          # Chrome alarms management
β”‚   β”œβ”€β”€ BadgeService.ts          # Extension badge updates
β”‚   β”œβ”€β”€ ChromeMessaging.ts       # Message passing utilities
β”‚   β”œβ”€β”€ NotificationService.ts   # Browser notifications
β”‚   β”œβ”€β”€ StorageProxyService.ts   # Storage proxy for content scripts
β”‚   └── TabService.ts            # Tab management operations
β”œβ”€β”€ storage/             # Storage abstraction layer (4 files)
β”‚   β”œβ”€β”€ IStorage.ts      # Storage interface definition
β”‚   β”œβ”€β”€ BrowserStorage.ts  # Chrome storage implementation
β”‚   β”œβ”€β”€ types.ts         # Data models (Product, Reminder, Settings)
β”‚   └── index.ts         # Storage singleton export
β”œβ”€β”€ types/               # TypeScript type definitions
β”‚   └── messages.ts      # Message type definitions
β”œβ”€β”€ utils/               # Utility functions
β”‚   β”œβ”€β”€ productExtractor.ts  # Extract product data from Amazon DOM
β”‚   └── time.ts              # Time formatting utilities
β”œβ”€β”€ views/               # View components (screen-level, 8 files)
β”‚   β”œβ”€β”€ ProductView.tsx              # Main decision screen
β”‚   β”œβ”€β”€ IDontNeedIt.tsx              # Investment options screen
β”‚   β”œβ”€β”€ SleepOnIt.tsx                # Reminder duration selection
β”‚   β”œβ”€β”€ INeedIt.tsx                  # Confirmation screen
β”‚   β”œβ”€β”€ Celebration.tsx              # Success/celebration screen
β”‚   β”œβ”€β”€ CelebrateThoughtfulPurchase.tsx
β”‚   β”œβ”€β”€ EarlyReturnFromSleep.tsx     # Early return flow
β”‚   └── BackToAnOldFlame.tsx         # Revisit product flow
β”œβ”€β”€ tests/               # Test files
β”‚   β”œβ”€β”€ e2e/             # End-to-end tests with Playwright (16 files)
β”‚   β”‚   β”œβ”€β”€ *.spec.ts    # Test specifications
β”‚   β”‚   β”œβ”€β”€ fixtures.ts  # Test fixtures
β”‚   β”‚   β”œβ”€β”€ setup.ts     # Test setup
β”‚   β”‚   β”œβ”€β”€ page-objects/ # Page object models
β”‚   β”‚   └── utils/       # Test utilities
β”‚   └── flows/           # User flow documentation (4 files)
β”œβ”€β”€ background.ts        # Background service worker (295 lines)
β”œβ”€β”€ popup.tsx            # Extension popup (332 lines)
β”œβ”€β”€ style.css            # Global styles
β”œβ”€β”€ design-system.ts     # Design tokens and theme
β”œβ”€β”€ playwright.config.ts # Playwright test configuration
β”œβ”€β”€ package.json         # Dependencies and scripts
β”œβ”€β”€ tsconfig.json        # TypeScript configuration
β”œβ”€β”€ .versionrc.json      # Changelog generation config
β”œβ”€β”€ .prettierrc.mjs      # Prettier formatting config
└── eslint.config.mts    # ESLint configuration

πŸ—οΈ Architecture Overview

Data Flow

Amazon Product Page
       ↓
  ProductView (Content Script)
       ↓
  User clicks "Sleep on it"
       ↓
  SleepOnIt View (Duration Selection)
       ↓
  productExtractor.ts (Extract product data)
       ↓
  BrowserStorage (Save product + reminder)
       ↓
  Message to Background Service Worker
       ↓
  Chrome Alarms API (Schedule notification)
       ↓
  [Time elapses...]
       ↓
  Alarm fires β†’ Browser Notification
       ↓
  User opens popup β†’ View reminders
       ↓
  User takes action β†’ Update reminder status

Storage Layer

  • Context-aware: Automatically detects execution context (content script vs popup)
  • Message passing: Content scripts communicate with background worker for storage operations
  • Normalized data: Products stored separately from reminders to avoid duplication
  • Type-safe: Full TypeScript interfaces for all data structures

See docs/ARCHITECTURE.md for detailed architecture documentation.


πŸ”’ Privacy & Security

  • Local storage only - No data sent to external servers
  • No tracking - No analytics or telemetry
  • User control - Users can dismiss reminders and clear data
  • Minimal data collection - Only stores what's necessary for functionality

πŸ”„ CI/CD & Workflows

GitHub Actions Workflows

The project has three automated workflows:

1. Lint and Format (lint-and-format.yml)

Runs on every push and pull request to master:

  • βœ“ Checks code with ESLint
  • βœ“ Validates formatting with Prettier
  • βœ“ Uses Node.js 22.18.0
# Run locally before committing
npm run lint        # Check for linting errors
npm run lint:fix    # Auto-fix linting errors
npm run format:check  # Check formatting
npm run format      # Auto-format code

2. Validate Release (update-version.yml)

Runs when a new version tag is pushed (e.g., v0.0.5):

  • βœ“ Verifies tag is on master branch
  • βœ“ Validates tag format (semantic versioning: vX.Y.Z)
  • βœ“ Confirms package.json version matches tag version

3. Submit to Web Store (submit.yml)

Manual workflow for publishing to Chrome Web Store:

  • Builds production extension
  • Packages as .zip file
  • Submits to Chrome Web Store using secrets

πŸ“¦ Versioning & Release Management

Version Scheme

This project follows Semantic Versioning (SemVer):

  • MAJOR version (X.0.0): Breaking changes
  • MINOR version (0.X.0): New features (backwards compatible)
  • PATCH version (0.0.X): Bug fixes

Current version: 0.1.0

Creating a New Release

The project uses standard-version for automated versioning and changelog generation.

Quick Release Commands

# Patch release (0.0.4 β†’ 0.0.5) - Bug fixes only
npm run release:patch

# Minor release (0.0.4 β†’ 0.1.0) - New features
npm run release:minor

# Major release (0.0.4 β†’ 1.0.0) - Breaking changes
npm run release:major

# Auto-detect version bump based on commits
npm run release

Release Workflow

  1. Make your changes and commit using Conventional Commits

  2. Run release script:

    npm run release:patch  # or minor/major

    This will:

    • Bump version in package.json
    • Update CHANGELOG.md based on commits
    • Create a git commit with message chore(release): vX.Y.Z
    • Create a git tag vX.Y.Z
  3. Push to GitHub:

    git push --follow-tags origin master
  4. GitHub Actions will validate the release automatically

See docs/VERSIONING-WORKFLOW.md for detailed release procedures.

Commit Message Convention

This project follows Conventional Commits specification:

<type>(<scope>): <subject>

[optional body]

[optional footer]

Types:

  • feat: New features β†’ appears in changelog
  • fix: Bug fixes β†’ appears in changelog
  • docs: Documentation changes β†’ appears in changelog
  • refactor: Code refactoring β†’ appears in changelog
  • perf: Performance improvements β†’ appears in changelog
  • chore: Maintenance tasks β†’ appears in changelog
  • style: Formatting, no code change β†’ hidden
  • test: Test changes β†’ hidden
  • ci: CI/CD changes β†’ appears in changelog
  • build: Build system changes β†’ appears in changelog

Examples:

# Feature commit
git commit -m "feat(sleep-on-it): add custom reminder duration input"

# Bug fix commit
git commit -m "fix(notifications): correct badge count calculation"

# Breaking change commit
git commit -m "feat(storage)!: change reminder data model

BREAKING CHANGE: Reminder schema now requires productId field"

Changelog configuration is in .versionrc.json.


🀝 Contributing

Development Workflow

  1. Create a feature branch:

    git checkout -b feat/your-feature-name
  2. Make changes following the code style

  3. Test your changes:

    npm run dev  # Start dev server
    # Load extension in Chrome and test manually
  4. Lint and format:

    npm run lint:fix
    npm run format
  5. Commit using Conventional Commits:

    git commit -m "feat(scope): description"
  6. Push and create Pull Request

Code Quality Standards

  • TypeScript: All code must be typed (no any unless absolutely necessary)
  • ESLint: Must pass npm run lint with no errors
  • Prettier: Code must be formatted (run npm run format)
  • React Best Practices: Use hooks, functional components, proper prop types

Testing Checklist

Before submitting a PR, test:

  • βœ“ Extension loads without errors
  • βœ“ Product page overlay appears on Amazon
  • βœ“ All three decision flows work (I don't need it, Sleep on it, I need it)
  • βœ“ Reminders save and alarms fire correctly
  • βœ“ Notifications appear at scheduled times
  • βœ“ Extension popup displays reminders properly
  • βœ“ No console errors in any context (content script, background, popup)

Automated Testing

This project uses Playwright for end-to-end testing:

# Run all E2E tests
npm run test:e2e

# Run specific test file
npx playwright test tests/e2e/sleeponit.spec.ts

# Run tests in headed mode (see browser)
npx playwright test --headed

# Run tests in debug mode
npx playwright test --debug

Test Coverage:

  • Close flow (closing overlay)
  • "I don't need it" flow
  • "I need it" flow
  • "Sleep on it" flow with reminders
  • Extension initialization
  • Storage operations
  • Product extraction

See automated E2E tests in tests/e2e/ and flow documentation in tests/flows/ for comprehensive testing procedures.


πŸ—„οΈ Data Models

Product

enum ProductState {
  SLEEPING_ON_IT = "sleepingOnIt"
  I_NEED_THIS = "iNeedThis"
  DONT_NEED_IT = "dontNeedIt"
}

{
  id: string // Amazon product ID (e.g., "B0XXXXXXX")
  name: string // Product title
  price: string | null // Price string (e.g., "$99.99")
  image: string | null // Product image URL
  url: string // Full Amazon product URL
  timestamp: number // When saved (Date.now())
  marketplace: string // Marketplace identifier (e.g., "amazon.com")
  state?: ProductState | null // Product decision state
}

Reminder

{
  id: string // UUID for reminder
  productId: string // References Product.id
  reminderTime: number // When to remind (Date.now() + duration)
  duration: number // Duration in milliseconds
  status: "pending" | "completed" | "dismissed"
}

Settings

{
  reminderDurations: number[]  // Available duration options in ms
  defaultDuration: number      // Default selected duration in ms
}

StorageData

{
  reminders: Reminder[]  // Array of all reminders
  products: { [productId: string]: Product }  // Product map by ID
  settings: Settings  // User settings
}

TabSessionState

{
  tabId: number | null  // Current tab ID
  justCreatedReminderId?: string | null  // Recently created reminder ID
}

πŸ“– Documentation

Core Documentation

Quick Links


πŸ› οΈ Troubleshooting

Common Issues

Extension doesn't load:

  • Ensure Node.js version is exactly 22.18.0
  • Delete node_modules and build directories, reinstall: npm install
  • Check for errors in chrome://extensions/ console

Overlay doesn't appear on Amazon:

  • Verify you're on a product page (URL contains /dp/ or /gp/product/)
  • Check content script console in DevTools (F12)
  • Ensure extension permissions are granted

Reminders don't trigger:

  • Check background service worker console for alarm events
  • Verify browser notifications are enabled
  • Ensure Chrome is running (service worker may sleep but will wake for alarms)

Build fails:

  • Ensure you're using exact Node.js version: nvm use 22.18.0
  • Clear Plasmo cache: rm -rf .plasmo
  • Reinstall dependencies: npm ci

πŸ™ Acknowledgments

Built with Plasmo - The browser extension framework


πŸ“„ License

Copyright Β© 2025 Thinktwiceco


Last Updated: January 28, 2026

About

Plugin version 3

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages