Building and Debugging the 'Ah-Ha! Capture' Chrome Extension: A Summary
May 24, 2025
I. Planning & Initial Setup:
- Initial Task: Build a Chrome extension to capture information from websites.
-
Planning Phase:
- Recognized the need for a detailed plan before coding, especially considering backend integration, OAuth, etc.
-
Used the
sequential-thinkingMCP tool to create a comprehensive development plan, covering:- Core functionalities (snippet extraction).
- UI/UX (popup, context menu, auth flow).
- Technical architecture (manifest, background/content scripts, storage).
- API interactions and security.
- Phased development approach.
- Testing strategy.
- Wrote this plan to
AH_HA_CHROME_EXTENSION_PLAN.md.
- Mode Switch: Switched from “Architect” to “Code” mode to begin implementation.
-
Basic File Structure & Manifest:
- Created the
ah-ha-chrome-extensiondirectory. - Created
manifest.jsondefining version 3, name, description, initial permissions (activeTab,storage,scripting,contextMenus), popup, icons, background service worker, and content script.
- Created the
-
Popup UI Skeleton:
- Created
popup/popup.htmlwith basic structure for auth status and actions. - Created
popup/popup.cssfor styling. - Created
popup/popup.jswith placeholder logic for UI updates and button clicks.
- Created
-
Core Scripts:
- Created
background.js(service worker) with initial setup for the context menu (“Save to Ah-Ha!”). - Created
content_scripts/content.jswith basic logging.
- Created
- Placeholder Icons: Confirmed user added placeholder icons to
ah-ha-chrome-extension/icons/.
II. Implementing Authentication (OAuth 2.0 with Google):
-
Refined Popup-Background Communication:
- Updated
popup.jsto sendGET_AUTH_STATUS,LOGIN,LOGOUTmessages tobackground.js. - Updated
background.jsto handle these messages, initially with simulated auth logic usingchrome.storage.localfor anahHaUserLoggedInflag.
- Updated
-
OAuth Flow Implementation (
background.js):- Added the
identitypermission tomanifest.json. - Defined OAuth 2.0 configuration constants (Client ID, Auth URL, Scopes, Redirect URI). User updated these with actual Google provider details.
- Implemented
initiateOAuthFlowusingchrome.identity.launchWebAuthFlow. - Modified the
LOGINmessage handler to callinitiateOAuthFlow.
- Added the
-
Token Extraction & Storage (
background.js):- Updated
initiateOAuthFlow’s callback to parse the redirect URL from Google to extractaccess_token,id_token, andexpires_in. - Stored these tokens (and
ahHaUserLoggedIn: true) inchrome.storage.local.
- Updated
-
Nonce Implementation for OIDC Security (
background.js):- Addressed Google’s “Nonce required” error.
- Generated a unique
noncebeforelaunchWebAuthFlow. - Stored the
nonceinchrome.storage.local. - Added the
nonceto the authentication request URL. - Implemented basic JWT parsing (
parseJwtfunction) to extract the nonce from the returnedid_token. - Verified the received nonce against the stored nonce.
- Ensured the stored
oauthNonceis cleared after the flow.
-
Debugging Auth State Synchronization:
- Addressed an issue where the auth state (tokens in storage, in-memory flags) wasn’t consistently updated or read immediately after login, leading to “User not authenticated” errors during snippet saving.
- Introduced in-memory variables (
currentAuthToken,currentUserLoggedIn) inbackground.js. - Refined
checkAuthenticationStatusto prioritize in-memory state, then fall back tochrome.storage.local, and to update in-memory state from storage if necessary. - Ensured the
initiateOAuthFlowcallback updates in-memory variables afterchrome.storage.local.setsuccessfully completes (using its callback). - Added extensive logging to trace state changes and storage operations, which was crucial for diagnosing the timing/asynchronicity issues.
III. Implementing Snippet Saving & Backend Integration:
-
Backend Endpoint Correction:
- Identified a
404 Not Founderror because the extension was calling/api/v1/snippets, but the FastAPI backend (ah-ha-backend/main.py) had the route defined as/ah-has/. - Corrected the route in
ah-ha-backend/main.pyto@app.post("/api/v1/snippets", ...).
- Identified a
-
Backend Dependency Management:
- Addressed Pylance import errors (
uvicorn,fastapi,pydantic) by creatingah-ha-backend/requirements.txtand guiding the user to install dependencies into their virtual environment and set the VS Code Python interpreter.
- Addressed Pylance import errors (
-
Backend Payload Validation (
422 Error):- Diagnosed a
422 Unprocessable Entityerror: the backend’sAhHaSnippetPydantic model required atitle, but the extension wasn’t sending one. - Modified
ah-ha-chrome-extension/background.js(withinsaveSnippet) to include a defaulttitle(first 70 chars of content) in the payload sent to the backend.
- Diagnosed a
-
Using Real Auth Token for API Calls (
background.js):- Updated the
saveSnippetfunction to retrieve the storedauthTokenfromchrome.storage.local(and prioritize the in-memorycurrentAuthToken) and include it in theAuthorization: Bearer <token>header of the API request. - Added basic token expiry checks and 401 error handling.
- Updated the
-
Backend Port Correction:
- Updated
AH_HA_API_BASE_URLinah-ha-chrome-extension/background.jsto use port8010as specified by the user.
- Updated
IV. Implementing Pre-Save Enrichment UI:
-
Capture UI Creation:
- Created
capture_ui/capture.htmlwith form fields for title, content, and tags. - Created
capture_ui/capture.cssfor styling. -
Created
capture_ui/capture.jsto:- Receive initial data (selected text, URL, auto-title) via URL parameters.
- Populate the form.
- Send enriched data (edited title, content, tags, URL) back to
background.jsvia aSAVE_ENRICHED_SNIPPETmessage. - Handle save/cancel actions.
- Created
-
Modifying Context Menu Flow (
background.js):- Updated
handleContextMenuClickto opencapture_ui/capture.htmlin a new window, passing initial data as URL parameters. - Added a message listener for
SAVE_ENRICHED_SNIPPETto receive data from the capture UI and then callsaveSnippet.
- Updated
V. User Feedback (Notifications):
-
Enhanced Save Confirmation:
- Added the
"notifications"permission tomanifest.json. - Updated the
chrome.notifications.createcall inbackground.js(for successful saves viaSAVE_ENRICHED_SNIPPET) to includepriority: 2andrequireInteraction: trueto make the success notification more prominent.
- Added the
Throughout this process, we iteratively tested, examined logs, diagnosed issues, and applied fixes to both the extension and (by instruction) the backend configuration.