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

docs: improve decision graph workflow with lifecycle management

Updated CLAUDE.md with comprehensive node lifecycle management:
- Added node status transitions (pending → in_progress → completed)
- Correct orphan detection commands (awk instead of cut)
- Common mistakes section with examples
- Enhanced audit checklist with status verification
- Verification workflow after node creation

Also updated extension popup with ATmosphere branding.

Decision graph now at 331 nodes, 332 edges - all orphans resolved.

byarielm.fyi fcf682bb 46bab120

verified
Changed files
+458 -124
docs
packages
extension
src
popup
+119 -3
CLAUDE.md
··· 78 78 79 79 **Root `goal` nodes are the ONLY valid orphans.** 80 80 81 + ### Node Lifecycle Management 82 + 83 + **Every node has a lifecycle. Update status in REAL-TIME:** 84 + 85 + ```bash 86 + # 1. Create node (defaults to 'pending') 87 + deciduous add action "Implementing feature X" -c 85 88 + 89 + # 2. IMMEDIATELY link to parent (before doing anything else) 90 + deciduous link <parent_id> <new_node_id> -r "Reason for connection" 91 + 92 + # 3. Mark as in_progress BEFORE starting work 93 + deciduous status <node_id> in_progress 94 + 95 + # 4. Do the work... 96 + 97 + # 5. Mark as completed IMMEDIATELY after work finishes 98 + deciduous status <node_id> completed 99 + ``` 100 + 101 + **Status Transitions:** 102 + - `pending` → Default state when created 103 + - `in_progress` → Mark BEFORE starting work (only ONE at a time) 104 + - `completed` → Mark IMMEDIATELY when done (proven by git commit, test pass, etc.) 105 + 106 + **CRITICAL RULES:** 107 + - ✅ Link nodes IMMEDIATELY after creation (same command sequence) 108 + - ✅ Update status to `completed` as soon as work is done 109 + - ✅ Only ONE node should be `in_progress` at a time 110 + - ✅ Verify link exists before moving on (check `deciduous edges`) 111 + - ❌ NEVER leave completed work marked as `pending` 112 + - ❌ NEVER create orphan nodes (except root goals) 113 + - ❌ NEVER batch status updates - update immediately 114 + 115 + **Verification Workflow:** 116 + ```bash 117 + # After creating and linking a node, verify: 118 + deciduous edges | grep <new_node_id> # Should show incoming edge 119 + deciduous nodes | grep <new_node_id> # Check status is correct 120 + ``` 121 + 122 + **Common Mistakes That Break the Graph:** 123 + 124 + 1. **Creating nodes without linking** → Orphans 125 + ```bash 126 + # WRONG 127 + deciduous add action "Fix bug" -c 85 128 + # (forget to link, move on to next task) 129 + 130 + # RIGHT 131 + deciduous add action "Fix bug" -c 85 132 + deciduous link 42 43 -r "Action to resolve goal #42" 133 + ``` 134 + 135 + 2. **Leaving nodes as "pending" after work completes** → Stale status 136 + ```bash 137 + # WRONG 138 + git commit -m "fix: bug fixed" 139 + # (forget to update node status) 140 + 141 + # RIGHT 142 + git commit -m "fix: bug fixed" 143 + deciduous status 43 completed 144 + ``` 145 + 146 + 3. **Batch-creating multiple nodes before linking** → Connection gaps 147 + ```bash 148 + # WRONG 149 + deciduous add action "Task 1" -c 85 150 + deciduous add action "Task 2" -c 85 151 + deciduous add action "Task 3" -c 85 152 + # (now have to remember all IDs to link) 153 + 154 + # RIGHT 155 + deciduous add action "Task 1" -c 85 156 + deciduous link 42 43 -r "First task" 157 + deciduous add action "Task 2" -c 85 158 + deciduous link 42 44 -r "Second task" 159 + ``` 160 + 161 + 4. **Not regenerating parent list during orphan checks** → False positives 162 + ```bash 163 + # WRONG 164 + # (generate parent list once) 165 + deciduous link X Y -r "fix orphan" 166 + # (check orphans with stale parent list) 167 + 168 + # RIGHT 169 + deciduous link X Y -r "fix orphan" 170 + # Regenerate parent list before checking again 171 + deciduous edges | tail -n+3 | awk '{print $3}' | sort -u > /tmp/has_parent.txt 172 + ``` 173 + 81 174 ### Quick Commands 82 175 83 176 ```bash ··· 181 274 182 275 ### Audit Checklist (Before Every Sync) 183 276 184 - 1. Does every **outcome** link back to what caused it? 185 - 2. Does every **action** link to why you did it? 186 - 3. Any **dangling outcomes** without parents? 277 + Run these checks before `deciduous sync`: 278 + 279 + 1. **Connection integrity**: Does every non-goal node have a parent? 280 + ```bash 281 + deciduous edges | tail -n+3 | awk '{print $3}' | sort -u > /tmp/has_parent.txt 282 + deciduous nodes | tail -n+3 | awk '{print $1}' > /tmp/all_nodes.txt 283 + while read id; do grep -q "^$id$" /tmp/has_parent.txt || echo "CHECK: $id"; done < /tmp/all_nodes.txt 284 + # Only root goals should appear 285 + ``` 286 + 287 + 2. **Status accuracy**: Are completed nodes marked `completed`? 288 + ```bash 289 + deciduous nodes | grep pending 290 + # Review: is this work actually still pending, or is it done? 291 + ``` 292 + 293 + 3. **Active work**: Is there exactly ONE `in_progress` node? 294 + ```bash 295 + deciduous nodes | grep in_progress 296 + # Should see 0-1 nodes, not multiple 297 + ``` 298 + 299 + 4. **Logical flow**: Does every outcome link back to what caused it? 300 + - `outcome` → `action` or `goal` 301 + - `action` → `goal` or `decision` 302 + - `observation` → related `goal` or `action` 187 303 188 304 ### Session Start Checklist 189 305
+16 -16
docs/git-history.json
··· 8 8 "files_changed": 1 9 9 }, 10 10 { 11 - "hash": "8f692c7ff534680b09e98e16c58e5effa0badd9f", 12 - "short_hash": "8f692c7", 11 + "hash": "e04934ffb5e2d78791fcd23bc3afeb4d438a5546", 12 + "short_hash": "e04934f", 13 13 "author": "Ariel M. Lighty", 14 - "date": "2025-12-26T21:48:59-05:00", 15 - "message": "docs: update decision graph after timezone fix", 16 - "files_changed": 2 14 + "date": "2025-12-26T21:57:05-05:00", 15 + "message": "perf: optimize Vite dev server startup\n\nAdded explicit optimizeDeps.include to pre-bundle common dependencies:\n- React ecosystem (react, react-dom, react-router-dom)\n- Icon libraries (@icons-pack/react-simple-icons, lucide-react)\n- Other deps (date-fns, jszip, zustand, @tanstack/react-virtual)\n\nAlso added server.fs.allow config for monorepo file serving.\n\nThis should speed up subsequent dev server starts by ensuring these\ndependencies are consistently pre-bundled.", 16 + "files_changed": 1 17 17 }, 18 18 { 19 19 "hash": "aacbbaa27797781098dacdfd0194c93cd71d7bd2", ··· 32 32 "files_changed": 1 33 33 }, 34 34 { 35 - "hash": "212660a996d6b0f1db59f9532d2b3968c7113f10", 36 - "short_hash": "212660a", 35 + "hash": "46626f4a18eaaaaf42368361130bb1ddc7bd9677", 36 + "short_hash": "46626f4", 37 37 "author": "Ariel M. Lighty", 38 - "date": "2025-12-26T20:58:45-05:00", 39 - "message": "fix: pass final search results to onComplete callback\n\nFixes issue where results were displayed but not saved to database until\npage refresh. Root cause: onComplete callback accessed stale searchResults\nfrom closure instead of updated state.\n\nChanges:\n- useSearch.searchAllUsers: onComplete now receives SearchResult[] param\n- useSearch: uses setSearchResults updater to get current state\n- App.tsx: updated all 3 searchAllUsers calls to use finalResults\n- Removed setTimeout workarounds\n\nResult: Extension and file upload flows now save immediately after search.", 40 - "files_changed": 4 38 + "date": "2025-12-26T21:20:34-05:00", 39 + "message": "fix: show loading screen during extension upload search\n\nPreviously when loading an upload from extension that hadn't been searched yet,\nthe app would immediately navigate to the results page showing 'none' for all\nmatches, then update them as the search progressed.\n\nNow it behaves like the file upload flow:\n- Shows loading screen during search\n- Navigates to results only after search completes and results are saved\n- If upload already has matches, navigates to results immediately", 40 + "files_changed": 1 41 41 }, 42 42 { 43 43 "hash": "212660a996d6b0f1db59f9532d2b3968c7113f10", ··· 120 120 "files_changed": 3 121 121 }, 122 122 { 123 - "hash": "32cdee3aeac7ef986df47e0fff786b5f7471e55b", 124 - "short_hash": "32cdee3", 123 + "hash": "ba29fd68872913ba0a587aa7f29f97b3d373a732", 124 + "short_hash": "ba29fd6", 125 125 "author": "Ariel M. Lighty", 126 126 "date": "2025-12-25T13:22:32-05:00", 127 127 "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.", 128 - "files_changed": 4 128 + "files_changed": 5 129 129 }, 130 130 { 131 - "hash": "ba29fd68872913ba0a587aa7f29f97b3d373a732", 132 - "short_hash": "ba29fd6", 131 + "hash": "32cdee3aeac7ef986df47e0fff786b5f7471e55b", 132 + "short_hash": "32cdee3", 133 133 "author": "Ariel M. Lighty", 134 134 "date": "2025-12-25T13:22:32-05:00", 135 135 "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.", 136 - "files_changed": 5 136 + "files_changed": 4 137 137 }, 138 138 { 139 139 "hash": "c3e7afad396d130791d801a85cbfc9643bcd6309",
+216 -18
docs/graph-data.json
··· 3504 3504 "node_type": "observation", 3505 3505 "title": "save-results has hasRecentUpload check that skips saving if upload created within 5 seconds - extension-import creates upload then save-results is called immediately, gets skipped!", 3506 3506 "description": null, 3507 - "status": "pending", 3507 + "status": "completed", 3508 3508 "created_at": "2025-12-26T20:37:34.735156200-05:00", 3509 - "updated_at": "2025-12-26T20:37:34.735156200-05:00", 3509 + "updated_at": "2025-12-27T15:37:51.134056500-05:00", 3510 3510 "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3511 3511 }, 3512 3512 { ··· 3515 3515 "node_type": "action", 3516 3516 "title": "Fix save-results to skip duplicate check for extension uploads and handle timestamps correctly", 3517 3517 "description": null, 3518 - "status": "pending", 3518 + "status": "completed", 3519 3519 "created_at": "2025-12-26T20:38:45.703038700-05:00", 3520 - "updated_at": "2025-12-26T20:38:45.703038700-05:00", 3520 + "updated_at": "2025-12-27T15:37:51.269445900-05:00", 3521 3521 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3522 3522 }, 3523 3523 { ··· 3526 3526 "node_type": "outcome", 3527 3527 "title": "Fixed save-results to check if upload exists by ID instead of recent time check - extension flow now saves matches", 3528 3528 "description": null, 3529 - "status": "pending", 3529 + "status": "completed", 3530 3530 "created_at": "2025-12-26T20:39:45.657720100-05:00", 3531 - "updated_at": "2025-12-26T20:39:45.657720100-05:00", 3531 + "updated_at": "2025-12-27T15:37:51.395550200-05:00", 3532 3532 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3533 3533 }, 3534 3534 { ··· 3537 3537 "node_type": "observation", 3538 3538 "title": "onComplete callback in handleLoadUpload accesses stale searchResults from closure - state updated by searchAllUsers not visible to callback", 3539 3539 "description": null, 3540 - "status": "pending", 3540 + "status": "completed", 3541 3541 "created_at": "2025-12-26T20:51:55.431293100-05:00", 3542 - "updated_at": "2025-12-26T20:51:55.431293100-05:00", 3542 + "updated_at": "2025-12-27T15:37:51.544390300-05:00", 3543 3543 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3544 3544 }, 3545 3545 { ··· 3548 3548 "node_type": "outcome", 3549 3549 "title": "Fixed stale closure issue - onComplete now receives finalResults from useSearch state", 3550 3550 "description": null, 3551 - "status": "pending", 3551 + "status": "completed", 3552 3552 "created_at": "2025-12-26T20:55:36.922743800-05:00", 3553 - "updated_at": "2025-12-26T20:55:36.922743800-05:00", 3553 + "updated_at": "2025-12-27T15:37:51.688947900-05:00", 3554 3554 "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3555 3555 }, 3556 3556 { ··· 3559 3559 "node_type": "outcome", 3560 3560 "title": "Committed stale closure fix - results now save immediately after search completes", 3561 3561 "description": null, 3562 - "status": "pending", 3562 + "status": "completed", 3563 3563 "created_at": "2025-12-26T20:58:48.266958800-05:00", 3564 - "updated_at": "2025-12-26T20:58:48.266958800-05:00", 3564 + "updated_at": "2025-12-27T15:37:51.824656100-05:00", 3565 3565 "metadata_json": "{\"branch\":\"master\",\"commit\":\"212660a\",\"confidence\":95}" 3566 3566 }, 3567 3567 { ··· 3570 3570 "node_type": "outcome", 3571 3571 "title": "Loading screen now shows during extension upload search", 3572 3572 "description": null, 3573 - "status": "pending", 3573 + "status": "completed", 3574 3574 "created_at": "2025-12-26T21:20:42.635515100-05:00", 3575 - "updated_at": "2025-12-26T21:20:42.635515100-05:00", 3575 + "updated_at": "2025-12-27T15:37:51.996612500-05:00", 3576 3576 "metadata_json": "{\"branch\":\"master\",\"commit\":\"46626f4\",\"confidence\":95}" 3577 3577 }, 3578 3578 { ··· 3581 3581 "node_type": "outcome", 3582 3582 "title": "Fixed timezone issue - all timestamp columns now use TIMESTAMPTZ", 3583 3583 "description": null, 3584 - "status": "pending", 3584 + "status": "completed", 3585 3585 "created_at": "2025-12-26T21:46:14.340967100-05:00", 3586 - "updated_at": "2025-12-26T21:46:14.340967100-05:00", 3586 + "updated_at": "2025-12-27T15:37:52.151895800-05:00", 3587 3587 "metadata_json": "{\"branch\":\"master\",\"commit\":\"aacbbaa\",\"confidence\":95}" 3588 3588 }, 3589 3589 { ··· 3592 3592 "node_type": "outcome", 3593 3593 "title": "Optimized Vite config with explicit dependency pre-bundling", 3594 3594 "description": null, 3595 - "status": "pending", 3595 + "status": "completed", 3596 3596 "created_at": "2025-12-26T21:57:16.155112400-05:00", 3597 - "updated_at": "2025-12-26T21:57:16.155112400-05:00", 3597 + "updated_at": "2025-12-27T15:37:52.289922500-05:00", 3598 3598 "metadata_json": "{\"branch\":\"master\",\"commit\":\"e04934f\",\"confidence\":85}" 3599 + }, 3600 + { 3601 + "id": 328, 3602 + "change_id": "7823be1a-fca9-4cb5-9e62-dfbc8cb71e55", 3603 + "node_type": "outcome", 3604 + "title": "Fixed decision graph integrity - linked 18 orphan nodes to parent goals, marked nodes 319-327 as completed", 3605 + "description": null, 3606 + "status": "pending", 3607 + "created_at": "2025-12-27T15:38:21.291457500-05:00", 3608 + "updated_at": "2025-12-27T15:38:21.291457500-05:00", 3609 + "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3610 + }, 3611 + { 3612 + "id": 329, 3613 + "change_id": "c839ec54-b098-4030-8ff4-857549b17363", 3614 + "node_type": "observation", 3615 + "title": "Decision graph audit revealed systematic issues: 18 orphan nodes, incorrect status (pending vs completed), wrong orphan detection commands in recovery workflow", 3616 + "description": null, 3617 + "status": "pending", 3618 + "created_at": "2025-12-27T15:40:23.238704300-05:00", 3619 + "updated_at": "2025-12-27T15:40:23.238704300-05:00", 3620 + "metadata_json": "{\"branch\":\"master\",\"confidence\":95}" 3621 + }, 3622 + { 3623 + "id": 330, 3624 + "change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 3625 + "node_type": "action", 3626 + "title": "Analyzing decision graph issues and updating CLAUDE.md with improved workflow", 3627 + "description": null, 3628 + "status": "completed", 3629 + "created_at": "2025-12-27T15:41:04.067444-05:00", 3630 + "updated_at": "2025-12-27T15:47:53.643256600-05:00", 3631 + "metadata_json": "{\"branch\":\"master\",\"confidence\":90}" 3632 + }, 3633 + { 3634 + "id": 331, 3635 + "change_id": "8c746dd6-d571-4446-8a53-af6279fc9c21", 3636 + "node_type": "outcome", 3637 + "title": "Updated CLAUDE.md and .claude/ files with node lifecycle management, correct orphan detection commands, and common mistakes section", 3638 + "description": null, 3639 + "status": "completed", 3640 + "created_at": "2025-12-27T15:47:49.308750700-05:00", 3641 + "updated_at": "2025-12-27T15:47:55.838439500-05:00", 3642 + "metadata_json": "{\"branch\":\"master\",\"confidence\":100}" 3599 3643 } 3600 3644 ], 3601 3645 "edges": [ ··· 7096 7140 "weight": 1.0, 7097 7141 "rationale": "User reported slow dev server startup - 4.5s from Vite", 7098 7142 "created_at": "2025-12-26T21:57:18.723545100-05:00" 7143 + }, 7144 + { 7145 + "id": 319, 7146 + "from_node_id": 305, 7147 + "to_node_id": 325, 7148 + "from_change_id": "8ad6ef53-29a2-442e-b88f-9e0541634950", 7149 + "to_change_id": "e44f45f8-bac9-4a49-ac68-ac9d7d113226", 7150 + "edge_type": "leads_to", 7151 + "weight": 1.0, 7152 + "rationale": "Implemented loading screen for extension upload flow", 7153 + "created_at": "2025-12-27T15:22:53.706223600-05:00" 7154 + }, 7155 + { 7156 + "id": 320, 7157 + "from_node_id": 318, 7158 + "to_node_id": 326, 7159 + "from_change_id": "371f788d-46df-4651-b338-f9310f8ae810", 7160 + "to_change_id": "af76ea64-b0b1-4577-b521-4ec21cc555e1", 7161 + "edge_type": "leads_to", 7162 + "weight": 1.0, 7163 + "rationale": "Fixed timezone issue with TIMESTAMPTZ migration", 7164 + "created_at": "2025-12-27T15:22:56.160485500-05:00" 7165 + }, 7166 + { 7167 + "id": 321, 7168 + "from_node_id": 69, 7169 + "to_node_id": 67, 7170 + "from_change_id": "5754ca49-f09b-489f-a4b0-f412159f4cd4", 7171 + "to_change_id": "6aef16a0-0524-4ad9-a8ff-b335069c860d", 7172 + "edge_type": "leads_to", 7173 + "weight": 1.0, 7174 + "rationale": "Action to understand current duplicate types", 7175 + "created_at": "2025-12-27T15:36:45.647337400-05:00" 7176 + }, 7177 + { 7178 + "id": 322, 7179 + "from_node_id": 110, 7180 + "to_node_id": 117, 7181 + "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 7182 + "to_change_id": "d78b544a-8897-4149-ac48-4f35f6def985", 7183 + "edge_type": "leads_to", 7184 + "weight": 1.0, 7185 + "rationale": "Cleanup observation during codebase cleanup", 7186 + "created_at": "2025-12-27T15:36:47.932994300-05:00" 7187 + }, 7188 + { 7189 + "id": 323, 7190 + "from_node_id": 110, 7191 + "to_node_id": 183, 7192 + "from_change_id": "22b9c3db-9f95-45d7-a3ed-bdfac54677db", 7193 + "to_change_id": "6e1851e2-134c-4c8f-86af-5487fda7d05c", 7194 + "edge_type": "leads_to", 7195 + "weight": 1.0, 7196 + "rationale": "Removed build artifacts from git history", 7197 + "created_at": "2025-12-27T15:36:50.152456600-05:00" 7198 + }, 7199 + { 7200 + "id": 324, 7201 + "from_node_id": 184, 7202 + "to_node_id": 228, 7203 + "from_change_id": "919c42ef-9fae-473f-b755-ee32d8999204", 7204 + "to_change_id": "7958ec7b-ff18-41d4-b1e1-fc9fa5603a1b", 7205 + "edge_type": "leads_to", 7206 + "weight": 1.0, 7207 + "rationale": "Installing pnpm for monorepo structure", 7208 + "created_at": "2025-12-27T15:36:52.522283200-05:00" 7209 + }, 7210 + { 7211 + "id": 325, 7212 + "from_node_id": 258, 7213 + "to_node_id": 262, 7214 + "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7215 + "to_change_id": "b8097a68-a63f-4cb6-aeac-2ed746e90126", 7216 + "edge_type": "leads_to", 7217 + "weight": 1.0, 7218 + "rationale": "Discovered extension-import endpoint during debugging", 7219 + "created_at": "2025-12-27T15:36:55.150261400-05:00" 7220 + }, 7221 + { 7222 + "id": 326, 7223 + "from_node_id": 258, 7224 + "to_node_id": 263, 7225 + "from_change_id": "b8c6cd90-7f32-461e-aad5-537cc1cbfafe", 7226 + "to_change_id": "b5109344-a5d3-43b3-b743-b06730453514", 7227 + "edge_type": "leads_to", 7228 + "weight": 1.0, 7229 + "rationale": "Discovered routing issue during debugging", 7230 + "created_at": "2025-12-27T15:36:57.690344600-05:00" 7231 + }, 7232 + { 7233 + "id": 327, 7234 + "from_node_id": 270, 7235 + "to_node_id": 275, 7236 + "from_change_id": "8cf80c58-e909-4f0b-85e8-ac15d7cf3640", 7237 + "to_change_id": "dcc9f401-1a68-479e-97de-7a04e5597e00", 7238 + "edge_type": "leads_to", 7239 + "weight": 1.0, 7240 + "rationale": "Discovered CORS blocking health check", 7241 + "created_at": "2025-12-27T15:37:00.388733200-05:00" 7242 + }, 7243 + { 7244 + "id": 328, 7245 + "from_node_id": 278, 7246 + "to_node_id": 282, 7247 + "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7248 + "to_change_id": "206347b5-4178-43dd-bb05-657b3788a6b0", 7249 + "edge_type": "leads_to", 7250 + "weight": 1.0, 7251 + "rationale": "Refactoring extension flow to match upload behavior", 7252 + "created_at": "2025-12-27T15:37:02.697547600-05:00" 7253 + }, 7254 + { 7255 + "id": 329, 7256 + "from_node_id": 278, 7257 + "to_node_id": 283, 7258 + "from_change_id": "fa11e7d7-ac30-4d0e-bc8a-d2332f724d92", 7259 + "to_change_id": "e3adddaf-9126-4bfa-8d75-aa8b94323077", 7260 + "edge_type": "leads_to", 7261 + "weight": 1.0, 7262 + "rationale": "Observation after implementing auth and upload creation", 7263 + "created_at": "2025-12-27T15:37:04.961909600-05:00" 7264 + }, 7265 + { 7266 + "id": 330, 7267 + "from_node_id": 328, 7268 + "to_node_id": 329, 7269 + "from_change_id": "7823be1a-fca9-4cb5-9e62-dfbc8cb71e55", 7270 + "to_change_id": "c839ec54-b098-4030-8ff4-857549b17363", 7271 + "edge_type": "leads_to", 7272 + "weight": 1.0, 7273 + "rationale": "Analysis of what went wrong during graph maintenance", 7274 + "created_at": "2025-12-27T15:40:25.442264900-05:00" 7275 + }, 7276 + { 7277 + "id": 331, 7278 + "from_node_id": 329, 7279 + "to_node_id": 330, 7280 + "from_change_id": "c839ec54-b098-4030-8ff4-857549b17363", 7281 + "to_change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 7282 + "edge_type": "leads_to", 7283 + "weight": 1.0, 7284 + "rationale": "Action to prevent future graph integrity issues", 7285 + "created_at": "2025-12-27T15:41:06.239618300-05:00" 7286 + }, 7287 + { 7288 + "id": 332, 7289 + "from_node_id": 330, 7290 + "to_node_id": 331, 7291 + "from_change_id": "1f554b87-3775-450b-a3a1-b23eeebc7e38", 7292 + "to_change_id": "8c746dd6-d571-4446-8a53-af6279fc9c21", 7293 + "edge_type": "leads_to", 7294 + "weight": 1.0, 7295 + "rationale": "Successfully completed documentation updates", 7296 + "created_at": "2025-12-27T15:47:51.427087400-05:00" 7099 7297 } 7100 7298 ] 7101 7299 }
+107 -87
packages/extension/src/popup/popup.html
··· 1 - <!DOCTYPE html> 1 + <!doctype html> 2 2 <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8"> 5 - <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 - <title>ATlast Importer</title> 7 - <link rel="stylesheet" href="popup.css"> 8 - </head> 9 - <body> 10 - <div class="container"> 11 - <header> 12 - <h1>ATlast Importer</h1> 13 - <p class="tagline">Find your follows on Bluesky</p> 14 - </header> 3 + <head> 4 + <meta charset="UTF-8" /> 5 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 + <title>ATlast Importer</title> 7 + <link rel="stylesheet" href="popup.css" /> 8 + </head> 9 + <body> 10 + <div class="container"> 11 + <header> 12 + <h1>ATlast Importer</h1> 13 + <p class="tagline">Find your follows in the ATmosphere</p> 14 + </header> 15 15 16 - <main id="app"> 17 - <!-- Idle state --> 18 - <div id="state-idle" class="state hidden"> 19 - <div class="icon">🔍</div> 20 - <p class="message">Go to your Twitter/X Following page to start</p> 21 - <p class="hint">Visit x.com/yourusername/following</p> 22 - </div> 16 + <main id="app"> 17 + <!-- Idle state --> 18 + <div id="state-idle" class="state hidden"> 19 + <div class="icon">🔍</div> 20 + <p class="message"> 21 + Go to your Twitter/X Following page to start 22 + </p> 23 + <p class="hint">Visit x.com/yourusername/following</p> 24 + </div> 23 25 24 - <!-- Ready state --> 25 - <div id="state-ready" class="state hidden"> 26 - <div class="icon">✅</div> 27 - <p class="message">Ready to scan <span id="platform-name"></span></p> 28 - <button id="btn-start" class="btn-primary">Start Scan</button> 29 - </div> 26 + <!-- Ready state --> 27 + <div id="state-ready" class="state hidden"> 28 + <div class="icon">✅</div> 29 + <p class="message"> 30 + Ready to scan <span id="platform-name"></span> 31 + </p> 32 + <button id="btn-start" class="btn-primary"> 33 + Start Scan 34 + </button> 35 + </div> 30 36 31 - <!-- Scraping state --> 32 - <div id="state-scraping" class="state hidden"> 33 - <div class="icon spinner">⏳</div> 34 - <p class="message">Scanning...</p> 35 - <div class="progress"> 36 - <div class="progress-bar"> 37 - <div id="progress-fill" class="progress-fill"></div> 38 - </div> 39 - <p class="progress-text"> 40 - Found <span id="count">0</span> users 41 - </p> 42 - <p id="status-message" class="status-message"></p> 43 - </div> 44 - </div> 37 + <!-- Scraping state --> 38 + <div id="state-scraping" class="state hidden"> 39 + <div class="icon spinner">⏳</div> 40 + <p class="message">Scanning...</p> 41 + <div class="progress"> 42 + <div class="progress-bar"> 43 + <div id="progress-fill" class="progress-fill"></div> 44 + </div> 45 + <p class="progress-text"> 46 + Found <span id="count">0</span> users 47 + </p> 48 + <p id="status-message" class="status-message"></p> 49 + </div> 50 + </div> 45 51 46 - <!-- Complete state --> 47 - <div id="state-complete" class="state hidden"> 48 - <div class="icon">🎉</div> 49 - <p class="message">Scan complete!</p> 50 - <p class="count-display">Found <strong id="final-count">0</strong> users</p> 51 - <button id="btn-upload" class="btn-primary">Open in ATlast</button> 52 - </div> 52 + <!-- Complete state --> 53 + <div id="state-complete" class="state hidden"> 54 + <div class="icon">🎉</div> 55 + <p class="message">Scan complete!</p> 56 + <p class="count-display"> 57 + Found <strong id="final-count">0</strong> users 58 + </p> 59 + <button id="btn-upload" class="btn-primary"> 60 + Open in ATlast 61 + </button> 62 + </div> 53 63 54 - <!-- Uploading state --> 55 - <div id="state-uploading" class="state hidden"> 56 - <div class="icon spinner">📤</div> 57 - <p class="message">Uploading to ATlast...</p> 58 - </div> 64 + <!-- Uploading state --> 65 + <div id="state-uploading" class="state hidden"> 66 + <div class="icon spinner">📤</div> 67 + <p class="message">Uploading to ATlast...</p> 68 + </div> 59 69 60 - <!-- Error state --> 61 - <div id="state-error" class="state hidden"> 62 - <div class="icon">⚠️</div> 63 - <p class="message">Error</p> 64 - <p id="error-message" class="error-message"></p> 65 - <button id="btn-retry" class="btn-secondary">Try Again</button> 66 - </div> 70 + <!-- Error state --> 71 + <div id="state-error" class="state hidden"> 72 + <div class="icon">⚠️</div> 73 + <p class="message">Error</p> 74 + <p id="error-message" class="error-message"></p> 75 + <button id="btn-retry" class="btn-secondary"> 76 + Try Again 77 + </button> 78 + </div> 67 79 68 - <!-- Server offline state --> 69 - <div id="state-offline" class="state hidden"> 70 - <div class="icon">🔌</div> 71 - <p class="message">ATlast server not running</p> 72 - <p class="error-message"> 73 - Start the dev server:<br> 74 - <code>npx netlify-cli dev --filter @atlast/web</code> 75 - </p> 76 - <p class="hint" id="server-url"></p> 77 - <button id="btn-check-server" class="btn-primary">Check Again</button> 78 - </div> 80 + <!-- Server offline state --> 81 + <div id="state-offline" class="state hidden"> 82 + <div class="icon">🔌</div> 83 + <p class="message">ATlast server not running</p> 84 + <p class="error-message"> 85 + Start the dev server:<br /> 86 + <code>npx netlify-cli dev --filter @atlast/web</code> 87 + </p> 88 + <p class="hint" id="server-url"></p> 89 + <button id="btn-check-server" class="btn-primary"> 90 + Check Again 91 + </button> 92 + </div> 79 93 80 - <!-- Not logged in state --> 81 - <div id="state-not-logged-in" class="state hidden"> 82 - <div class="icon">🔐</div> 83 - <p class="message">Not logged in to ATlast</p> 84 - <p class="error-message"> 85 - Please log in to ATlast first, then return here to scan. 86 - </p> 87 - <button id="btn-open-atlast" class="btn-primary">Open ATlast</button> 88 - <button id="btn-retry-login" class="btn-secondary">Check Again</button> 89 - </div> 90 - </main> 94 + <!-- Not logged in state --> 95 + <div id="state-not-logged-in" class="state hidden"> 96 + <div class="icon">🔐</div> 97 + <p class="message">Not logged in to ATlast</p> 98 + <p class="error-message"> 99 + Please log in to ATlast first, then return here to scan. 100 + </p> 101 + <button id="btn-open-atlast" class="btn-primary"> 102 + Open ATlast 103 + </button> 104 + <button id="btn-retry-login" class="btn-secondary"> 105 + Check Again 106 + </button> 107 + </div> 108 + </main> 91 109 92 - <footer> 93 - <a href="https://atlast.byarielm.fyi" target="_blank">atlast.byarielm.fyi</a> 94 - </footer> 95 - </div> 110 + <footer> 111 + <a href="https://atlast.byarielm.fyi" target="_blank" 112 + >atlast.byarielm.fyi</a 113 + > 114 + </footer> 115 + </div> 96 116 97 - <script type="module" src="popup.js"></script> 98 - </body> 117 + <script type="module" src="popup.js"></script> 118 + </body> 99 119 </html>