-165
EXTENSION_STATUS.md
-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
+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
+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
+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
+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
+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);