+18
-10
docs/git-history.json
+18
-10
docs/git-history.json
···
1
1
[
2
2
{
3
+
"hash": "bd3aabb75abb1875aef125610fcdccb14967a8e3",
4
+
"short_hash": "bd3aabb",
5
+
"author": "Ariel M. Lighty",
6
+
"date": "2025-12-27T22:10:11-05:00",
7
+
"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",
8
+
"files_changed": 5
9
+
},
10
+
{
3
11
"hash": "d07180cd3a19328b82b35118e525b59d4e2e060b",
4
12
"short_hash": "d07180c",
5
13
"author": "Ariel M. Lighty",
···
8
16
"files_changed": 9
9
17
},
10
18
{
11
-
"hash": "6ac877ee6d1990bdab4ef3b03ac59f4682afe0a5",
12
-
"short_hash": "6ac877e",
19
+
"hash": "d07180cd3a19328b82b35118e525b59d4e2e060b",
20
+
"short_hash": "d07180c",
13
21
"author": "Ariel M. Lighty",
14
-
"date": "2025-12-27T16:03:56-05:00",
15
-
"message": "docs: update decision graph after markdown updates",
16
-
"files_changed": 2
22
+
"date": "2025-12-27T18:38:39-05:00",
23
+
"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.",
24
+
"files_changed": 9
17
25
},
18
26
{
19
27
"hash": "fe29bb3e5faa0151f63c14724f7509af669860de",
···
32
40
"files_changed": 4
33
41
},
34
42
{
35
-
"hash": "46bab1202f69d8d03093a20bc8ada5ad6d365401",
36
-
"short_hash": "46bab12",
43
+
"hash": "fcf682bb8969aca108262348e7e17531077713be",
44
+
"short_hash": "fcf682b",
37
45
"author": "Ariel M. Lighty",
38
-
"date": "2025-12-26T22:10:11-05:00",
39
-
"message": "docs: update decision graph after Vite optimization",
40
-
"files_changed": 2
46
+
"date": "2025-12-27T15:48:44-05:00",
47
+
"message": "docs: improve decision graph workflow with lifecycle management\n\nUpdated CLAUDE.md with comprehensive node lifecycle management:\n- Added node status transitions (pending → in_progress → completed)\n- Correct orphan detection commands (awk instead of cut)\n- Common mistakes section with examples\n- Enhanced audit checklist with status verification\n- Verification workflow after node creation\n\nAlso updated extension popup with ATmosphere branding.\n\nDecision graph now at 331 nodes, 332 edges - all orphans resolved.",
48
+
"files_changed": 4
41
49
},
42
50
{
43
51
"hash": "e04934ffb5e2d78791fcd23bc3afeb4d438a5546",
+143
docs/graph-data.json
+143
docs/graph-data.json
···
3937
3937
"created_at": "2025-12-27T22:09:28.843864300-05:00",
3938
3938
"updated_at": "2025-12-27T22:09:32.017503200-05:00",
3939
3939
"metadata_json": "{\"branch\":\"master\",\"confidence\":95}"
3940
+
},
3941
+
{
3942
+
"id": 359,
3943
+
"change_id": "4a7d5885-1713-4ba7-ad13-bb12b58c9410",
3944
+
"node_type": "outcome",
3945
+
"title": "Committed fixes to git",
3946
+
"description": null,
3947
+
"status": "completed",
3948
+
"created_at": "2025-12-27T22:10:25.576235500-05:00",
3949
+
"updated_at": "2025-12-27T22:10:28.961887300-05:00",
3950
+
"metadata_json": "{\"branch\":\"master\",\"commit\":\"bd3aabb\",\"confidence\":95}"
3951
+
},
3952
+
{
3953
+
"id": 360,
3954
+
"change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
3955
+
"node_type": "goal",
3956
+
"title": "Fix extension not detecting login session despite dev server running",
3957
+
"description": null,
3958
+
"status": "completed",
3959
+
"created_at": "2025-12-27T22:23:13.072419900-05:00",
3960
+
"updated_at": "2025-12-27T22:41:49.160848100-05:00",
3961
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":90,\"prompt\":\"dark mode is fixed, but the extension in /chrome/ uploaded still is saying login with atlast and dev server is running\"}"
3962
+
},
3963
+
{
3964
+
"id": 361,
3965
+
"change_id": "aecf2327-d20d-4c6c-b6b0-06ccf26a2b27",
3966
+
"node_type": "observation",
3967
+
"title": "Extension dist/chrome contains production build, not dev build. User ran build:prod last.",
3968
+
"description": null,
3969
+
"status": "completed",
3970
+
"created_at": "2025-12-27T22:23:45.918832500-05:00",
3971
+
"updated_at": "2025-12-27T22:23:48.919570500-05:00",
3972
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":95}"
3973
+
},
3974
+
{
3975
+
"id": 362,
3976
+
"change_id": "e897db97-44d8-4993-b4c3-0d829265b2f8",
3977
+
"node_type": "observation",
3978
+
"title": "Dev build now deployed. Extension will check session at http://127.0.0.1:8888/.netlify/functions/session with credentials:include",
3979
+
"description": null,
3980
+
"status": "completed",
3981
+
"created_at": "2025-12-27T22:24:17.767230200-05:00",
3982
+
"updated_at": "2025-12-27T22:24:20.981953100-05:00",
3983
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":90}"
3984
+
},
3985
+
{
3986
+
"id": 363,
3987
+
"change_id": "2c62bfa3-d148-4448-8c2b-d0cf1e94ceb0",
3988
+
"node_type": "observation",
3989
+
"title": "Found CORS issue: successResponse uses 'Access-Control-Allow-Origin: *' which blocks credentialed requests from extension",
3990
+
"description": null,
3991
+
"status": "completed",
3992
+
"created_at": "2025-12-27T22:24:51.861265800-05:00",
3993
+
"updated_at": "2025-12-27T22:24:55.482724500-05:00",
3994
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":95}"
3995
+
},
3996
+
{
3997
+
"id": 364,
3998
+
"change_id": "560d6bea-47ec-408d-919b-15ca7198aac9",
3999
+
"node_type": "action",
4000
+
"title": "Updating CORS headers to support credentialed requests from extension",
4001
+
"description": null,
4002
+
"status": "completed",
4003
+
"created_at": "2025-12-27T22:25:23.035212700-05:00",
4004
+
"updated_at": "2025-12-27T22:26:03.046221900-05:00",
4005
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":90}"
4006
+
},
4007
+
{
4008
+
"id": 365,
4009
+
"change_id": "3ef0c9e9-aa40-4914-a5f4-32bcfaf68d04",
4010
+
"node_type": "outcome",
4011
+
"title": "Fixed CORS to support credentialed requests from extensions",
4012
+
"description": null,
4013
+
"status": "completed",
4014
+
"created_at": "2025-12-27T22:41:38.430661200-05:00",
4015
+
"updated_at": "2025-12-27T22:41:48.981429600-05:00",
4016
+
"metadata_json": "{\"branch\":\"master\",\"confidence\":95}"
3940
4017
}
3941
4018
],
3942
4019
"edges": [
···
7866
7943
"weight": 1.0,
7867
7944
"rationale": "Final outcome of fixes",
7868
7945
"created_at": "2025-12-27T22:09:30.425884400-05:00"
7946
+
},
7947
+
{
7948
+
"id": 358,
7949
+
"from_node_id": 352,
7950
+
"to_node_id": 359,
7951
+
"from_change_id": "b852ce18-1747-4c26-a65e-acfbbed2b1a5",
7952
+
"to_change_id": "4a7d5885-1713-4ba7-ad13-bb12b58c9410",
7953
+
"edge_type": "leads_to",
7954
+
"weight": 1.0,
7955
+
"rationale": "Git commit for fixes",
7956
+
"created_at": "2025-12-27T22:10:27.225192300-05:00"
7957
+
},
7958
+
{
7959
+
"id": 359,
7960
+
"from_node_id": 360,
7961
+
"to_node_id": 361,
7962
+
"from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
7963
+
"to_change_id": "aecf2327-d20d-4c6c-b6b0-06ccf26a2b27",
7964
+
"edge_type": "leads_to",
7965
+
"weight": 1.0,
7966
+
"rationale": "Root cause analysis",
7967
+
"created_at": "2025-12-27T22:23:47.445630900-05:00"
7968
+
},
7969
+
{
7970
+
"id": 360,
7971
+
"from_node_id": 360,
7972
+
"to_node_id": 362,
7973
+
"from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
7974
+
"to_change_id": "e897db97-44d8-4993-b4c3-0d829265b2f8",
7975
+
"edge_type": "leads_to",
7976
+
"weight": 1.0,
7977
+
"rationale": "Rebuilt dev version",
7978
+
"created_at": "2025-12-27T22:24:19.438433600-05:00"
7979
+
},
7980
+
{
7981
+
"id": 361,
7982
+
"from_node_id": 360,
7983
+
"to_node_id": 363,
7984
+
"from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
7985
+
"to_change_id": "2c62bfa3-d148-4448-8c2b-d0cf1e94ceb0",
7986
+
"edge_type": "leads_to",
7987
+
"weight": 1.0,
7988
+
"rationale": "Root cause: CORS configuration",
7989
+
"created_at": "2025-12-27T22:24:53.741163700-05:00"
7990
+
},
7991
+
{
7992
+
"id": 362,
7993
+
"from_node_id": 360,
7994
+
"to_node_id": 364,
7995
+
"from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
7996
+
"to_change_id": "560d6bea-47ec-408d-919b-15ca7198aac9",
7997
+
"edge_type": "leads_to",
7998
+
"weight": 1.0,
7999
+
"rationale": "Implementation of CORS fix",
8000
+
"created_at": "2025-12-27T22:25:24.843330900-05:00"
8001
+
},
8002
+
{
8003
+
"id": 363,
8004
+
"from_node_id": 360,
8005
+
"to_node_id": 365,
8006
+
"from_change_id": "706d5a7f-08ed-43f7-aee5-0bed28d9402a",
8007
+
"to_change_id": "3ef0c9e9-aa40-4914-a5f4-32bcfaf68d04",
8008
+
"edge_type": "leads_to",
8009
+
"weight": 1.0,
8010
+
"rationale": "CORS fix completed",
8011
+
"created_at": "2025-12-27T22:41:44.160528300-05:00"
7869
8012
}
7870
8013
]
7871
8014
}
+2
-2
packages/functions/src/session.ts
+2
-2
packages/functions/src/session.ts
···
30
30
return successResponse(cached, 200, {
31
31
"Cache-Control": "private, max-age=300",
32
32
"X-Cache-Status": "HIT",
33
-
});
33
+
}, event);
34
34
}
35
35
36
36
const { agent } = await SessionService.getAgentForSession(sessionId, event);
···
50
50
return successResponse(profileData, 200, {
51
51
"Cache-Control": "private, max-age=300",
52
52
"X-Cache-Status": "MISS",
53
-
});
53
+
}, event);
54
54
};
55
55
56
56
export const handler = withErrorHandling(sessionHandler);
+42
-3
packages/functions/src/utils/response.utils.ts
+42
-3
packages/functions/src/utils/response.utils.ts
···
1
-
import { HandlerResponse } from "@netlify/functions";
1
+
import { HandlerResponse, HandlerEvent } from "@netlify/functions";
2
2
import { ApiResponse } from "../core/types";
3
3
4
+
/**
5
+
* Get CORS headers based on request origin
6
+
* Supports credentialed requests from extensions and localhost
7
+
*/
8
+
function getCorsHeaders(event?: HandlerEvent): Record<string, string> {
9
+
const origin = event?.headers?.origin || event?.headers?.Origin;
10
+
11
+
// Allow all origins for non-credentialed requests (backward compatibility)
12
+
if (!origin) {
13
+
return {
14
+
"Access-Control-Allow-Origin": "*",
15
+
};
16
+
}
17
+
18
+
// Check if origin is allowed for credentialed requests
19
+
const allowedOrigins = [
20
+
'http://localhost:8888',
21
+
'http://127.0.0.1:8888',
22
+
'https://atlast.byarielm.fyi',
23
+
];
24
+
25
+
const isExtension = origin.startsWith('chrome-extension://');
26
+
const isAllowedOrigin = allowedOrigins.includes(origin);
27
+
28
+
if (isExtension || isAllowedOrigin) {
29
+
return {
30
+
"Access-Control-Allow-Origin": origin,
31
+
"Access-Control-Allow-Credentials": "true",
32
+
};
33
+
}
34
+
35
+
// Default to wildcard for unknown origins
36
+
return {
37
+
"Access-Control-Allow-Origin": "*",
38
+
};
39
+
}
40
+
4
41
export function successResponse<T>(
5
42
data: T,
6
43
statusCode: number = 200,
7
44
additionalHeaders: Record<string, string> = {},
45
+
event?: HandlerEvent,
8
46
): HandlerResponse {
9
47
const response: ApiResponse<T> = {
10
48
success: true,
···
15
53
statusCode,
16
54
headers: {
17
55
"Content-Type": "application/json",
18
-
"Access-Control-Allow-Origin": "*",
56
+
...getCorsHeaders(event),
19
57
...additionalHeaders,
20
58
},
21
59
body: JSON.stringify(response),
···
26
64
error: string,
27
65
statusCode: number = 500,
28
66
details?: string,
67
+
event?: HandlerEvent,
29
68
): HandlerResponse {
30
69
const response: ApiResponse = {
31
70
success: false,
···
37
76
statusCode,
38
77
headers: {
39
78
"Content-Type": "application/json",
40
-
"Access-Control-Allow-Origin": "*",
79
+
...getCorsHeaders(event),
41
80
},
42
81
body: JSON.stringify(response),
43
82
};