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-thinking
MCP 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-extension
directory. - Created
manifest.json
defining 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.html
with basic structure for auth status and actions. - Created
popup/popup.css
for styling. - Created
popup/popup.js
with 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.js
with 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.js
to sendGET_AUTH_STATUS
,LOGIN
,LOGOUT
messages tobackground.js
. - Updated
background.js
to handle these messages, initially with simulated auth logic usingchrome.storage.local
for anahHaUserLoggedIn
flag.
- Updated
-
OAuth Flow Implementation (
background.js
):- Added the
identity
permission tomanifest.json
. - Defined OAuth 2.0 configuration constants (Client ID, Auth URL, Scopes, Redirect URI). User updated these with actual Google provider details.
- Implemented
initiateOAuthFlow
usingchrome.identity.launchWebAuthFlow
. - Modified the
LOGIN
message 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
nonce
beforelaunchWebAuthFlow
. - Stored the
nonce
inchrome.storage.local
. - Added the
nonce
to the authentication request URL. - Implemented basic JWT parsing (
parseJwt
function) to extract the nonce from the returnedid_token
. - Verified the received nonce against the stored nonce.
- Ensured the stored
oauthNonce
is 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
checkAuthenticationStatus
to prioritize in-memory state, then fall back tochrome.storage.local
, and to update in-memory state from storage if necessary. - Ensured the
initiateOAuthFlow
callback updates in-memory variables afterchrome.storage.local.set
successfully 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 Found
error 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.py
to@app.post("/api/v1/snippets", ...)
.
- Identified a
-
Backend Dependency Management:
- Addressed Pylance import errors (
uvicorn
,fastapi
,pydantic
) by creatingah-ha-backend/requirements.txt
and 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 Entity
error: the backend’sAhHaSnippet
Pydantic 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
saveSnippet
function to retrieve the storedauthToken
fromchrome.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_URL
inah-ha-chrome-extension/background.js
to use port8010
as specified by the user.
- Updated
IV. Implementing Pre-Save Enrichment UI:
-
Capture UI Creation:
- Created
capture_ui/capture.html
with form fields for title, content, and tags. - Created
capture_ui/capture.css
for styling. -
Created
capture_ui/capture.js
to:- 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.js
via aSAVE_ENRICHED_SNIPPET
message. - Handle save/cancel actions.
- Created
-
Modifying Context Menu Flow (
background.js
):- Updated
handleContextMenuClick
to opencapture_ui/capture.html
in a new window, passing initial data as URL parameters. - Added a message listener for
SAVE_ENRICHED_SNIPPET
to 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.create
call inbackground.js
(for successful saves viaSAVE_ENRICHED_SNIPPET
) to includepriority: 2
andrequireInteraction: true
to 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.