ATlast โ€” you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

Compare changes

Choose any two refs to compare.

Changed files
+281 -200
docs
packages
extension
src
functions
src
core
middleware
-165
EXTENSION_STATUS.md
··· 1 - # Extension Implementation Status 2 - 3 - ## Current State: โœ… COMPLETE - Ready for Production Testing 4 - 5 - ### What's Complete โœ… 6 - 7 - 1. **Environment Configuration** 8 - - Dev/prod builds with correct API URLs 9 - - Build: `npm run build` (dev) or `npm run build:prod` 10 - - Dev: `http://127.0.0.1:8888` 11 - - Prod: `https://atlast.byarielm.fyi` 12 - 13 - 2. **Server Health Check** 14 - - Extension checks if dev server is running (dev mode only) 15 - - Shows "Server offline" state with instructions 16 - - "Check Again" button to retry 17 - 18 - 3. **Authentication Flow** 19 - - Extension checks `/session` endpoint on init 20 - - Shows "Not logged in" state if no session 21 - - "Open ATlast" button to log in 22 - - "Check Again" to retry after login 23 - - **User must be logged in to ATlast BEFORE using extension** 24 - 25 - 4. **Upload Flow** (matches file upload) 26 - - Scan Twitter Following page 27 - - POST to `/extension-import` (requires auth) 28 - - Backend: 29 - - Gets DID from session 30 - - Creates `user_upload` entry 31 - - Saves to `source_accounts` table 32 - - Returns `uploadId` 33 - - Opens `/results?uploadId={id}` 34 - - Frontend searches and displays (same as file upload) 35 - 36 - 5. **CORS Permissions** 37 - - Extension has host_permissions for: 38 - - `http://127.0.0.1:8888/*` 39 - - `http://localhost:8888/*` 40 - - `https://atlast.byarielm.fyi/*` 41 - 42 - 6. **Cleanup Complete** 43 - - โŒ Removed `extension_imports` table 44 - - โŒ Removed `get-extension-import` function 45 - - โŒ Removed `ExtensionImport.tsx` page 46 - - โŒ Removed `/import/:id` route 47 - - โŒ Removed `utils/import-store.ts` 48 - 49 - ### What Needs Testing ๐Ÿงช 50 - 51 - 1. **Full Flow Test** 52 - ```bash 53 - # 1. Start dev server 54 - npx netlify-cli dev --filter @atlast/web 55 - 56 - # 2. Build extension 57 - cd packages/extension 58 - npm run build 59 - 60 - # 3. Load extension in Chrome 61 - chrome://extensions/ โ†’ Load unpacked โ†’ packages/extension/dist/chrome/ 62 - 63 - # 4. Log in to ATlast 64 - Open http://127.0.0.1:8888 โ†’ Log in 65 - 66 - # 5. Go to Twitter 67 - https://twitter.com/justadev_atlast/following 68 - 69 - # 6. Open extension popup 70 - - Should show "Ready to scan Twitter/X" 71 - - Click "Start Scan" 72 - - Wait for completion 73 - - Click "Open in ATlast" 74 - - Should open /results?uploadId={id} 75 - - Results should load and search automatically 76 - ``` 77 - 78 - 2. **Error Cases to Test** 79 - - Not logged in โ†’ should show login prompt 80 - - Server offline โ†’ should show offline state 81 - - Empty results โ†’ should show appropriate message 82 - - Network errors โ†’ should handle gracefully 83 - 84 - ### Recently Completed (Dec 2024 - Jan 2025) ๐ŸŽ‰ 85 - 86 - **Extension Flow Fixes:** 87 - - โœ… NaN database error - Fixed missing `matchedUsers` parameter in `extension-import.ts` (node #287) 88 - - โœ… Database initialized successfully (node #288) 89 - - โœ… API response unwrapping - Fixed api-client to access ApiResponse.data field (nodes #290-295) 90 - - โœ… Loading screen during extension upload search (node #325) 91 - - โœ… Timezone fixes - All timestamp columns use TIMESTAMPTZ (node #326) 92 - - โœ… Vite dev server optimization - Pre-bundling dependencies for faster startup (node #327) 93 - 94 - **Decision Graph Documentation:** 95 - - โœ… Fixed 18 orphan nodes and linked to parent goals (nodes #328-331) 96 - - โœ… Improved decision graph workflow with lifecycle management (node #332) 97 - - โœ… Updated CLAUDE.md with node status transitions and common mistakes 98 - 99 - ### Current Status ๐Ÿ“Š 100 - 101 - **All extension bugs resolved!** The extension is fully functional and ready for production testing and deployment. 102 - 103 - ### Next Steps ๐Ÿ“‹ 104 - 105 - 1. โœ… Build extension: `cd packages/extension && pnpm run build` 106 - 2. โœ… Reload extension in Chrome 107 - 3. โœ… Test login flow 108 - 4. โœ… Test scan and upload 109 - 5. โœ… Verify results page works 110 - 6. โœ… All bugs fixed 111 - 7. ๐Ÿ”œ Test production build: `pnpm run build:prod` 112 - 8. ๐Ÿ”œ Chrome Web Store submission 113 - 9. ๐Ÿ”œ Firefox Add-ons support and submission 114 - 115 - ### Architecture Notes ๐Ÿ“ 116 - 117 - **Removed temporary import storage approach:** 118 - - Previously tried in-memory storage (doesn't work in serverless) 119 - - Then tried database storage with temp table (overkill) 120 - 121 - **Current approach:** 122 - - User logs in to ATlast FIRST 123 - - Extension requires authentication 124 - - Upload creates permanent records immediately 125 - - No temporary storage needed 126 - - Matches file upload behavior exactly 127 - 128 - **Why this is better:** 129 - - Simpler architecture 130 - - No temporary storage to expire 131 - - Proper user association from the start 132 - - Reuses existing upload/search infrastructure 133 - - Same flow as file uploads (consistency) 134 - 135 - ### Files Modified in Latest Refactor 136 - 137 - **Deleted:** 138 - - `packages/functions/src/get-extension-import.ts` 139 - - `packages/functions/src/utils/import-store.ts` 140 - - `packages/web/src/pages/ExtensionImport.tsx` 141 - 142 - **Modified:** 143 - - `packages/functions/src/extension-import.ts` - Now requires auth, creates upload 144 - - `packages/functions/src/infrastructure/database/DatabaseService.ts` - Removed extension_imports table 145 - - `packages/functions/src/core/types/database.types.ts` - Removed ExtensionImportRow 146 - - `packages/web/src/Router.tsx` - Removed /import/:id route 147 - - `packages/extension/src/popup/popup.ts` - Added session check, login state 148 - - `packages/extension/src/popup/popup.html` - Added not-logged-in state 149 - - `packages/extension/src/lib/api-client.ts` - Added checkSession(), credentials: 'include' 150 - 151 - ### Decision Graph Summary 152 - 153 - **Total nodes:** 332 nodes, 333 edges 154 - **Key decisions tracked:** 155 - - Environment configuration approach (#261-269) 156 - - Port 8888 conflict resolution (#270-274) 157 - - CORS permissions fix (#275-277) 158 - - Storage approach: in-memory โ†’ database โ†’ proper auth flow (#278-284) 159 - - Refactor and build (#285-286) 160 - - Bug fixes: NaN parameter error (#287), database initialization (#288) 161 - - API response unwrapping fix (#290-295) 162 - - Extension upload flow fixes (#296-327) 163 - - Decision graph integrity fixes (#328-332) 164 - 165 - **Live graph:** https://notactuallytreyanastasio.github.io/deciduous/
+19 -19
docs/git-history.json
··· 1 1 [ 2 2 { 3 - "hash": "603cf0a187850664336a12c9e5cbb49038906f53", 4 - "short_hash": "603cf0a", 3 + "hash": "15b67054a684ebb2a21761a1774ba15f9b1c29e2", 4 + "short_hash": "15b6705", 5 5 "author": "Ariel M. Lighty", 6 - "date": "2025-12-27T22:42:43-05:00", 7 - "message": "fix: CORS for extension credentialed requests\n\nUpdated CORS headers to support credentials from Chrome extensions:\n- Added getCorsHeaders() to detect chrome-extension:// origins\n- Changed from wildcard Access-Control-Allow-Origin to specific origin\n- Added Access-Control-Allow-Credentials: true for credentialed requests\n- Updated session endpoint to pass event for CORS header detection", 8 - "files_changed": 4 6 + "date": "2025-12-28T20:38:38-05:00", 7 + "message": "fix: add health check function for extension server detection\n\n- Created /health function endpoint with CORS support\n- Updated checkServerHealth to use function endpoint instead of root URL\n- Fixes Firefox extension server detection with proper CORS headers", 8 + "files_changed": 5 9 9 }, 10 10 { 11 11 "hash": "603cf0a187850664336a12c9e5cbb49038906f53", ··· 24 24 "files_changed": 5 25 25 }, 26 26 { 27 + "hash": "bd3aabb75abb1875aef125610fcdccb14967a8e3", 28 + "short_hash": "bd3aabb", 29 + "author": "Ariel M. Lighty", 30 + "date": "2025-12-27T22:10:11-05:00", 31 + "message": "fix: extension dark mode and build mode messaging\n\n- Changed darkMode from 'class' to 'media' for automatic system preference detection\n- Made server offline message conditional on build mode (dev vs prod)\n- Hide dev server instructions in production builds", 32 + "files_changed": 5 33 + }, 34 + { 27 35 "hash": "d07180cd3a19328b82b35118e525b59d4e2e060b", 28 36 "short_hash": "d07180c", 29 37 "author": "Ariel M. Lighty", 30 38 "date": "2025-12-27T18:38:39-05:00", 31 39 "message": "feat: add Tailwind CSS to extension\n\nReplaced 299 lines of vanilla CSS with Tailwind for design consistency with web app. Production build minified to 13KB.", 32 40 "files_changed": 9 33 - }, 34 - { 35 - "hash": "fe29bb3e5faa0151f63c14724f7509af669860de", 36 - "short_hash": "fe29bb3", 37 - "author": "Ariel M. Lighty", 38 - "date": "2025-12-27T16:02:10-05:00", 39 - "message": "docs: update all .md files to reflect current project status\n\nUpdated 4 markdown files with current state:\n\nEXTENSION_STATUS.md:\n- Changed status from DEBUGGING to COMPLETE\n- Updated decision graph count (295 โ†’ 332 nodes)\n- Added recently completed section (nodes 296-332)\n- Marked all extension bugs as resolved\n\nCONTRIBUTING.md:\n- Replaced npm with pnpm throughout\n- Added monorepo structure documentation\n- Updated development commands (netlify-cli dev --filter)\n- Added extension development workflow\n\nPLAN.md:\n- Updated status to Phase 1 COMPLETE\n- Added all recent fixes to completion list\n- Updated decision graph count to 332 nodes\n- Added changelog entries for latest work\n\npackages/extension/README.md:\n- Added prerequisites section (dev server + login required)\n- Updated build commands with dev/prod distinction\n- Added Step 0: Start ATlast Dev Server\n- Added common issues for auth and server states\n\nAll files now accurately reflect completion status and use pnpm.", 40 - "files_changed": 6 41 41 }, 42 42 { 43 43 "hash": "fe29bb3e5faa0151f63c14724f7509af669860de", ··· 160 160 "files_changed": 3 161 161 }, 162 162 { 163 - "hash": "32cdee3aeac7ef986df47e0fff786b5f7471e55b", 164 - "short_hash": "32cdee3", 163 + "hash": "ba29fd68872913ba0a587aa7f29f97b3d373a732", 164 + "short_hash": "ba29fd6", 165 165 "author": "Ariel M. Lighty", 166 166 "date": "2025-12-25T13:22:32-05:00", 167 167 "message": "configure Netlify dev for monorepo with --filter flag\n\nFixed Netlify CLI monorepo detection issue by using --filter flag:\n- Updated root package.json scripts to use 'npx netlify-cli dev --filter @atlast/web'\n- Updated netlify.toml [dev] section to use npm with --prefix for framework command\n- Added monorepo development instructions to CLAUDE.md\n- Documented Windows Git Bash compatibility issue with netlify command\n\nSolution: Use 'npx netlify-cli dev --filter @atlast/web' to bypass monorepo\nproject selection prompt and specify which workspace package to run.\n\nDev server now runs successfully at http://localhost:8888 with all backend\nfunctions loaded.", 168 - "files_changed": 4 168 + "files_changed": 5 169 169 }, 170 170 { 171 - "hash": "ba29fd68872913ba0a587aa7f29f97b3d373a732", 172 - "short_hash": "ba29fd6", 171 + "hash": "32cdee3aeac7ef986df47e0fff786b5f7471e55b", 172 + "short_hash": "32cdee3", 173 173 "author": "Ariel M. Lighty", 174 174 "date": "2025-12-25T13:22:32-05:00", 175 175 "message": "configure Netlify dev for monorepo with --filter flag\n\nFixed Netlify CLI monorepo detection issue by using --filter flag:\n- Updated root package.json scripts to use 'npx netlify-cli dev --filter @atlast/web'\n- Updated netlify.toml [dev] section to use npm with --prefix for framework command\n- Added monorepo development instructions to CLAUDE.md\n- Documented Windows Git Bash compatibility issue with netlify command\n\nSolution: Use 'npx netlify-cli dev --filter @atlast/web' to bypass monorepo\nproject selection prompt and specify which workspace package to run.\n\nDev server now runs successfully at http://localhost:8888 with all backend\nfunctions loaded.", 176 - "files_changed": 5 176 + "files_changed": 4 177 177 }, 178 178 { 179 179 "hash": "c3e7afad396d130791d801a85cbfc9643bcd6309",
+204 -6
docs/graph-data.json
··· 4142 4142 "node_type": "goal", 4143 4143 "title": "Fix Firefox extension server detection and login check", 4144 4144 "description": null, 4145 - "status": "pending", 4145 + "status": "completed", 4146 4146 "created_at": "2025-12-28T20:14:51.646204800-05:00", 4147 - "updated_at": "2025-12-28T20:14:51.646204800-05:00", 4147 + "updated_at": "2025-12-28T20:32:19.249555-05:00", 4148 4148 "metadata_json": "{\"branch\":\"master\",\"confidence\":85,\"prompt\":\"The extension works in chrome. In firefox, it's failing to detect that the dev server is running and open + logged in on firefox. There's no right-click to inspect on the popup either.\"}" 4149 4149 }, 4150 4150 { ··· 4241 4241 "node_type": "action", 4242 4242 "title": "Adding moz-extension:// origin detection to CORS handler for Firefox extension support", 4243 4243 "description": null, 4244 - "status": "pending", 4244 + "status": "completed", 4245 4245 "created_at": "2025-12-28T20:28:31.661326900-05:00", 4246 - "updated_at": "2025-12-28T20:28:31.661326900-05:00", 4246 + "updated_at": "2025-12-28T20:32:19.367968600-05:00", 4247 4247 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4248 4248 }, 4249 4249 { ··· 4252 4252 "node_type": "outcome", 4253 4253 "title": "Fixed Firefox extension CORS by adding moz-extension:// origin detection to response.utils.ts. Reverted netlify.toml changes as functions handle CORS correctly. User needs to restart dev server.", 4254 4254 "description": null, 4255 + "status": "completed", 4256 + "created_at": "2025-12-28T20:29:39.856303800-05:00", 4257 + "updated_at": "2025-12-28T20:32:19.494690-05:00", 4258 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4259 + }, 4260 + { 4261 + "id": 388, 4262 + "change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 4263 + "node_type": "observation", 4264 + "title": "Health check uses HEAD request to root URL (Vite server), not a Netlify function. Doesn't get CORS headers from getCorsHeaders. Need dedicated health endpoint or change check to use existing function.", 4265 + "description": null, 4266 + "status": "completed", 4267 + "created_at": "2025-12-28T20:37:22.132717600-05:00", 4268 + "updated_at": "2025-12-28T20:38:41.630020900-05:00", 4269 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4270 + }, 4271 + { 4272 + "id": 389, 4273 + "change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 4274 + "node_type": "outcome", 4275 + "title": "Created /health function endpoint with CORS support. Updated checkServerHealth to use /.netlify/functions/health instead of root URL. Extension rebuilt successfully.", 4276 + "description": null, 4277 + "status": "completed", 4278 + "created_at": "2025-12-28T20:38:19.981309500-05:00", 4279 + "updated_at": "2025-12-28T20:38:41.780183300-05:00", 4280 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4281 + }, 4282 + { 4283 + "id": 390, 4284 + "change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 4285 + "node_type": "observation", 4286 + "title": "Server receives session request but returns CORS wildcard (*) instead of extension origin. No session cookie received. Origin header might not be sent by Firefox extension or not detected correctly.", 4287 + "description": null, 4255 4288 "status": "pending", 4256 - "created_at": "2025-12-28T20:29:39.856303800-05:00", 4257 - "updated_at": "2025-12-28T20:29:39.856303800-05:00", 4289 + "created_at": "2025-12-28T20:48:12.770638500-05:00", 4290 + "updated_at": "2025-12-28T20:48:12.770638500-05:00", 4291 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4292 + }, 4293 + { 4294 + "id": 391, 4295 + "change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 4296 + "node_type": "observation", 4297 + "title": "Health endpoint gets CORS headers correctly (moz-extension detected). Session endpoint error middleware doesn't pass event to errorResponse, returns wildcard CORS. Need to fix error middleware to pass event.", 4298 + "description": null, 4299 + "status": "completed", 4300 + "created_at": "2025-12-28T20:55:32.024834200-05:00", 4301 + "updated_at": "2025-12-28T21:38:14.729731500-05:00", 4302 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4303 + }, 4304 + { 4305 + "id": 392, 4306 + "change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 4307 + "node_type": "action", 4308 + "title": "Fixed error middleware to pass event to errorResponse for proper CORS headers on errors", 4309 + "description": null, 4310 + "status": "completed", 4311 + "created_at": "2025-12-28T20:56:38.876266200-05:00", 4312 + "updated_at": "2025-12-28T21:38:14.888627800-05:00", 4313 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4314 + }, 4315 + { 4316 + "id": 393, 4317 + "change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 4318 + "node_type": "outcome", 4319 + "title": "Fixed Firefox extension CORS completely. Error middleware now passes event to errorResponse so Firefox extension origin is properly reflected in error responses with credentials. Debug logging removed.", 4320 + "description": null, 4321 + "status": "completed", 4322 + "created_at": "2025-12-28T21:37:22.780953600-05:00", 4323 + "updated_at": "2025-12-28T21:38:15.071425500-05:00", 4324 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4325 + }, 4326 + { 4327 + "id": 394, 4328 + "change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 4329 + "node_type": "observation", 4330 + "title": "CORS fully working - Firefox extension origin properly reflected with credentials. But cookies not sent from extension despite credentials:include. Cookie set in web context not accessible from extension context due to Firefox cookie partitioning.", 4331 + "description": null, 4332 + "status": "pending", 4333 + "created_at": "2025-12-28T21:46:45.822343200-05:00", 4334 + "updated_at": "2025-12-28T21:46:45.822343200-05:00", 4335 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4336 + }, 4337 + { 4338 + "id": 395, 4339 + "change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 4340 + "node_type": "action", 4341 + "title": "Updated extension checkSession to read cookie via browser.cookies API and pass as query parameter. Workaround for Firefox SameSite=Lax cookie partitioning.", 4342 + "description": null, 4343 + "status": "pending", 4344 + "created_at": "2025-12-28T21:52:22.059862700-05:00", 4345 + "updated_at": "2025-12-28T21:52:22.059862700-05:00", 4346 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4347 + }, 4348 + { 4349 + "id": 396, 4350 + "change_id": "864dd973-5f15-4e31-a7da-c548dbbe1f0e", 4351 + "node_type": "outcome", 4352 + "title": "Extension now uses browser.cookies.get() API to read session cookie and pass as query parameter. Workaround for Firefox SameSite=Lax cookie partitioning in extensions. Extension rebuilt successfully.", 4353 + "description": null, 4354 + "status": "pending", 4355 + "created_at": "2025-12-28T22:51:31.578965200-05:00", 4356 + "updated_at": "2025-12-28T22:51:31.578965200-05:00", 4258 4357 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 4259 4358 } 4260 4359 ], ··· 8471 8570 "weight": 1.0, 8472 8571 "rationale": "Complete fix implemented", 8473 8572 "created_at": "2025-12-28T20:30:09.745415200-05:00" 8573 + }, 8574 + { 8575 + "id": 384, 8576 + "from_node_id": 387, 8577 + "to_node_id": 388, 8578 + "from_change_id": "cffdee0f-8535-4d88-83ed-fdf6101f7ac3", 8579 + "to_change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 8580 + "edge_type": "leads_to", 8581 + "weight": 1.0, 8582 + "rationale": "New issue discovered in health check", 8583 + "created_at": "2025-12-28T20:37:24.355885500-05:00" 8584 + }, 8585 + { 8586 + "id": 385, 8587 + "from_node_id": 388, 8588 + "to_node_id": 389, 8589 + "from_change_id": "0ada864e-be98-4a2f-a14e-ffd3eea9aaa9", 8590 + "to_change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 8591 + "edge_type": "leads_to", 8592 + "weight": 1.0, 8593 + "rationale": "Fix implemented", 8594 + "created_at": "2025-12-28T20:38:22.044029100-05:00" 8595 + }, 8596 + { 8597 + "id": 386, 8598 + "from_node_id": 389, 8599 + "to_node_id": 390, 8600 + "from_change_id": "f522d5b2-c325-4f34-9f27-b8ea5c50618d", 8601 + "to_change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 8602 + "edge_type": "leads_to", 8603 + "weight": 1.0, 8604 + "rationale": "Issue persists - need to debug headers", 8605 + "created_at": "2025-12-28T20:48:14.949702100-05:00" 8606 + }, 8607 + { 8608 + "id": 387, 8609 + "from_node_id": 390, 8610 + "to_node_id": 391, 8611 + "from_change_id": "cfdcf45b-47b3-4239-8053-417bd31957ed", 8612 + "to_change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 8613 + "edge_type": "leads_to", 8614 + "weight": 1.0, 8615 + "rationale": "Root cause identified from debug logs", 8616 + "created_at": "2025-12-28T20:55:34.094943700-05:00" 8617 + }, 8618 + { 8619 + "id": 388, 8620 + "from_node_id": 391, 8621 + "to_node_id": 392, 8622 + "from_change_id": "2b53a419-9a47-4285-9a12-9bdfaeeb9ff0", 8623 + "to_change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 8624 + "edge_type": "leads_to", 8625 + "weight": 1.0, 8626 + "rationale": "Fix implemented", 8627 + "created_at": "2025-12-28T20:57:35.872426900-05:00" 8628 + }, 8629 + { 8630 + "id": 389, 8631 + "from_node_id": 392, 8632 + "to_node_id": 393, 8633 + "from_change_id": "c941d136-3405-483d-bf34-7fb011f6d072", 8634 + "to_change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 8635 + "edge_type": "leads_to", 8636 + "weight": 1.0, 8637 + "rationale": "Complete fix with cleanup", 8638 + "created_at": "2025-12-28T21:37:27.704906300-05:00" 8639 + }, 8640 + { 8641 + "id": 390, 8642 + "from_node_id": 393, 8643 + "to_node_id": 394, 8644 + "from_change_id": "aafd9977-8800-4152-9f7f-b817db6df573", 8645 + "to_change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 8646 + "edge_type": "leads_to", 8647 + "weight": 1.0, 8648 + "rationale": "New issue - cookie partitioning", 8649 + "created_at": "2025-12-28T21:46:48.417911400-05:00" 8650 + }, 8651 + { 8652 + "id": 391, 8653 + "from_node_id": 394, 8654 + "to_node_id": 395, 8655 + "from_change_id": "3b0dea7a-c3cd-45a8-ba1a-f1040aa4e1d9", 8656 + "to_change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 8657 + "edge_type": "leads_to", 8658 + "weight": 1.0, 8659 + "rationale": "Workaround using browser.cookies API", 8660 + "created_at": "2025-12-28T21:52:52.704792400-05:00" 8661 + }, 8662 + { 8663 + "id": 392, 8664 + "from_node_id": 395, 8665 + "to_node_id": 396, 8666 + "from_change_id": "8a93413f-a09c-4cc1-8693-4fe90dc055c4", 8667 + "to_change_id": "864dd973-5f15-4e31-a7da-c548dbbe1f0e", 8668 + "edge_type": "leads_to", 8669 + "weight": 1.0, 8670 + "rationale": "Complete workaround", 8671 + "created_at": "2025-12-28T22:51:33.159870400-05:00" 8474 8672 } 8475 8673 ] 8476 8674 }
+33 -8
packages/extension/src/lib/api-client.ts
··· 78 78 */ 79 79 export async function checkServerHealth(): Promise<boolean> { 80 80 try { 81 - // Try to fetch the root URL with a short timeout 81 + // Try to fetch the health endpoint with a short timeout 82 82 const controller = new AbortController(); 83 83 const timeoutId = setTimeout(() => controller.abort(), 3000); 84 84 85 - const response = await fetch(ATLAST_API_URL, { 86 - method: 'HEAD', 87 - signal: controller.signal 85 + const response = await fetch(`${ATLAST_API_URL}/.netlify/functions/health`, { 86 + method: 'GET', 87 + signal: controller.signal, 88 + credentials: 'include', // Include for CORS 88 89 }); 89 90 90 91 clearTimeout(timeoutId); 91 92 92 - // Any response (even 404) means server is running 93 - return true; 93 + // Any successful response means server is running 94 + return response.ok; 94 95 } catch (error) { 95 96 console.error('[API Client] Server health check failed:', error); 96 97 return false; ··· 115 116 avatar?: string; 116 117 } | null> { 117 118 try { 118 - const response = await fetch(`${ATLAST_API_URL}/.netlify/functions/session`, { 119 + // Try to get session cookie using browser.cookies API 120 + // This works around Firefox's cookie partitioning for extensions 121 + let sessionId: string | null = null; 122 + 123 + try { 124 + const cookieName = __BUILD_MODE__ === 'production' ? 'atlast_session' : 'atlast_session_dev'; 125 + const cookie = await browser.cookies.get({ 126 + url: ATLAST_API_URL, 127 + name: cookieName 128 + }); 129 + 130 + if (cookie) { 131 + sessionId = cookie.value; 132 + console.log('[API Client] Found session cookie:', cookieName); 133 + } 134 + } catch (cookieError) { 135 + console.log('[API Client] Could not read cookie:', cookieError); 136 + } 137 + 138 + // Build URL with session parameter if we have one 139 + const url = sessionId 140 + ? `${ATLAST_API_URL}/.netlify/functions/session?session=${sessionId}` 141 + : `${ATLAST_API_URL}/.netlify/functions/session`; 142 + 143 + const response = await fetch(url, { 119 144 method: 'GET', 120 - credentials: 'include', // Include cookies 145 + credentials: 'include', // Include cookies as fallback 121 146 headers: { 122 147 'Accept': 'application/json' 123 148 }
+4 -2
packages/functions/src/core/middleware/error.middleware.ts
··· 21 21 } 22 22 23 23 if (error instanceof ApiError) { 24 - return errorResponse(error.message, error.statusCode, error.details); 24 + return errorResponse(error.message, error.statusCode, error.details, event); 25 25 } 26 26 27 27 // Unknown errors ··· 29 29 "Internal server error", 30 30 500, 31 31 error instanceof Error ? error.message : "Unknown error", 32 + event, 32 33 ); 33 34 } 34 35 }; ··· 48 49 console.error("Authenticated handler error:", error); 49 50 50 51 if (error instanceof ApiError) { 51 - return errorResponse(error.message, error.statusCode, error.details); 52 + return errorResponse(error.message, error.statusCode, error.details, event); 52 53 } 53 54 54 55 return errorResponse( 55 56 "Internal server error", 56 57 500, 57 58 error instanceof Error ? error.message : "Unknown error", 59 + event, 58 60 ); 59 61 } 60 62 };
+21
packages/functions/src/health.ts
··· 1 + import { SimpleHandler } from "./core/types/api.types"; 2 + import { successResponse } from "./utils"; 3 + import { withErrorHandling } from "./core/middleware"; 4 + 5 + /** 6 + * Health check endpoint 7 + * Returns 200 OK with server status 8 + */ 9 + const healthHandler: SimpleHandler = async (event) => { 10 + return successResponse( 11 + { 12 + status: "ok", 13 + timestamp: new Date().toISOString(), 14 + }, 15 + 200, 16 + {}, 17 + event 18 + ); 19 + }; 20 + 21 + export const handler = withErrorHandling(healthHandler);