commits
- add collapsible educational section explaining atproto, data ownership, and the silo problem
- implement demo mode that loads paul frazee's account for exploration without login
- add demo banner with exit functionality
- adjust UI elements (info, watch live, logout buttons) to avoid overlapping with demo banner
- clear localStorage when exiting demo to prevent auto-restore behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add display: flex and align-items: center to .logout for consistent vertical alignment with .watch-live-btn
- add explicit font-family: inherit to .watch-live-btn to ensure monospace font usage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add clickable "view record" links to firehose toast notifications that open raw record JSON from user's PDS. Also fix particle animation direction to flow from apps to PDS (correctly showing data writes).
Changes:
- Add /api/record endpoint to fetch individual records
- Refactor firehose to use DID-specific connections via manager
- Add toast link element with hover styling
- Fetch record details for richer toast messages
- Reverse particle flow direction (app → PDS)
- Add "Your PDS" label to identity circle
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
implements the visual layer for real-time firehose events:
- watch live toggle button in top-right corner
- toast notifications showing event actions (create/update/delete)
- particle animation system using canvas overlay
- colored particles flow from identity to app circles
- particles: green for create, blue for update, red for delete
- app circles pulse when receiving data
- auto-reconnects on connection drop
- clean shutdown when toggled off
complete implementation:
- backend: rust jetstream connector + SSE endpoint (src/firehose.rs, src/routes.rs)
- frontend: particle system + event handling (static/app.js)
- ui: button, toast, css animations (src/templates.rs)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
adds rust backend for real-time firehose visualization:
- firehose module connects to jetstream and broadcasts all atproto events
- uses rocketman crate with lexicon ingester pattern
- SSE endpoint at /api/firehose/watch streams filtered events by DID
- auto-reconnects on connection drop
remaining work:
- add UI toggle button and toast notifications in templates
- implement particle animation system in static/app.js
- test with live events
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
some servers (like bsky.app) return HTTP 405 for HEAD requests but work fine with GET. this commit adds a fallback strategy:
- try HEAD first (faster, less bandwidth)
- if HEAD returns error status (405, etc), fall back to GET
- if HEAD fails completely, also try GET
- mark as valid only if either succeeds
this ensures valid URLs aren't incorrectly grayed out while still catching truly invalid domains.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
validates all app URLs concurrently on page load:
- created /api/validate-url endpoint with HEAD request and 3s timeout
- grays out invalid links with reduced opacity
- adds tooltip explaining domain is not reachable
- disables clicking on invalid links
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- reverse namespace display (app.bsky -> bsky.app)
- make app names clickable links to actual URLs
- add hover underline effect for app name links
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
reduces client-side javascript by moving core business logic to rust:
- created /api/init endpoint for did resolution, pds extraction, and app grouping
- created /api/avatar endpoint for namespace avatar lookups
- simplified fetchAppAvatar from 30 lines to 8 lines
- removed duplicate avatar fetching logic
- app.js reduced from 760 to 714 lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add tabbed interface for collections with 5+ records (records/mst tabs)
- implement canvas-based MST tree visualization
- add hover tooltips showing TID for each node
- add click modal showing full record details (TID, CID, URI, JSON data)
- improve tree layout algorithm to prevent node overlap
- hide scrollbar in detail panel and increase width to 500px
- link to atproto docs for MST and TID explanations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- capitalize Personal Data Server (PDS) throughout
- link first mention in info modal to atproto.com/guides/overview
- update meta descriptions and onboarding text
- move identity click handler after apps is populated
- change messaging from ban-focused to lock-in/distribution focused
- emphasize 'you build their network, they own distribution'
- softer language: locked in vs can't export, starting over vs gone
- show stats (record types, apps) when clicking identity
- contrast walled gardens vs atproto ownership
- update info modal to emphasize ownership
- add visual styling for ownership boxes
- make login card background fully transparent
- keep input field and button with solid backgrounds for visibility
- increase border opacity on input/button for better definition
- maintain backdrop blur for subtle effect
- add og:title, og:description, og:image, og:url meta tags
- add twitter:card, twitter:title, twitter:description, twitter:image meta tags
- create og-image.png (1200x630) with @me branding and aesthetic
- matches app's dark gradient background with orbital design
- improves social media sharing experience
- extract javascript from templates.rs into modular static files
- implement 3-step onboarding overlay for first-time users
- add user profile picture to center identity circle
- make entire ui responsive with viewport-relative units using clamp()
- add help button to restart onboarding tour
- improve technical accuracy of onboarding text about atproto
- add actix-files for static file serving
- reduce templates.rs by 600+ lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fetch app logos from reversed namespace handles (e.g., io.zzstoatzz -> zzstoatzz.io)
- group collections hierarchically by sub-namespace in detail panel
- fix load more button to only show when full page returned
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
following tangled.org/core pattern where linting and testing are
combined in one workflow with multiple steps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fmt.yaml: checks code formatting with cargo fmt
- clippy.yaml: runs clippy linter with warnings as errors
- both run on push and pull_request events
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fix @ symbol positioning: larger (1.2rem) and better aligned with handle
- add structured record display with headers and content sections
- add copy button to each record with visual feedback
- improve mobile responsiveness for identity circle and records
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
the favicon.svg is embedded at compile time via include_str!(), so the
static/ directory needs to be present in the build context
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- move spindle config to .tangled/workflows/ for auto-deploy on push to main
- simplify readme link styling
- improve identity visualization: show @ symbol as label with handle, add "tap for details" hint
- remove redundant @ prefix from handle display since it's now shown as separate label
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add close button (×) to detail panel, visible on all devices
- make close button larger on mobile (40px) for better touch targets
- personalize identity explanation with actual user handle and pds
- change generic text to: "your data lives at bsky.social. apps like bluesky write to and read from this server. you control @yourhandle..."
- fixes mobile bug where panel couldn't be closed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add spindle.yaml for automated deployment to fly.io on push to main
- install flyctl in ci environment using curl
- deploy using flyctl with FLY_API_TOKEN secret
- add deployed app link to readme
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- upgrade font stack to modern system monospace fonts
- add responsive touch targets for all interactive elements
- improve button/link active states for mobile
- make detail panel full-width on mobile
- add tap highlight removal for better mobile feel
- increase padding on mobile for better usability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fix logout button to clear localStorage before redirecting
- fix load more button using event delegation for dynamic buttons
- add interactive identity circle with pds info on click
- improve record display styling with better spacing and hover effects
- improve overlay behavior to close all panels
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- use AtprotoClientMetadata for https URLs (production)
- use AtprotoLocalhostClientMetadata for http URLs (local dev)
- add /oauth-client-metadata.json endpoint
- fixes OAuth client creation failure in production
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
binding to 127.0.0.1 only accepts localhost connections,
which doesn't work in containerized environments
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- update README: friendlier framing, remove condescending language
- add mobile responsiveness: viewport meta, responsive CSS, larger tap targets
- create Dockerfile: two-stage build for minimal production image
- make OAuth production-ready: configurable redirect URI via env var
- add fly.toml: deployment config with production OAuth callback
- create justfile: deploy and dev commands
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
a radial visualization showing your atproto identity at the center,
surrounded by third-party apps that store data in your PDS.
features:
- oauth login with any atproto handle
- session persistence via localStorage
- radial layout of third-party apps grouped by lexicon namespace
- click apps to see collection types
- click collections to view actual record data with pagination
- info modal explaining the atproto ecosystem
- light/dark mode following system preference
- responsive design with monospace courier new aesthetic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add collapsible educational section explaining atproto, data ownership, and the silo problem
- implement demo mode that loads paul frazee's account for exploration without login
- add demo banner with exit functionality
- adjust UI elements (info, watch live, logout buttons) to avoid overlapping with demo banner
- clear localStorage when exiting demo to prevent auto-restore behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add display: flex and align-items: center to .logout for consistent vertical alignment with .watch-live-btn
- add explicit font-family: inherit to .watch-live-btn to ensure monospace font usage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add clickable "view record" links to firehose toast notifications that open raw record JSON from user's PDS. Also fix particle animation direction to flow from apps to PDS (correctly showing data writes).
Changes:
- Add /api/record endpoint to fetch individual records
- Refactor firehose to use DID-specific connections via manager
- Add toast link element with hover styling
- Fetch record details for richer toast messages
- Reverse particle flow direction (app → PDS)
- Add "Your PDS" label to identity circle
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
implements the visual layer for real-time firehose events:
- watch live toggle button in top-right corner
- toast notifications showing event actions (create/update/delete)
- particle animation system using canvas overlay
- colored particles flow from identity to app circles
- particles: green for create, blue for update, red for delete
- app circles pulse when receiving data
- auto-reconnects on connection drop
- clean shutdown when toggled off
complete implementation:
- backend: rust jetstream connector + SSE endpoint (src/firehose.rs, src/routes.rs)
- frontend: particle system + event handling (static/app.js)
- ui: button, toast, css animations (src/templates.rs)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
adds rust backend for real-time firehose visualization:
- firehose module connects to jetstream and broadcasts all atproto events
- uses rocketman crate with lexicon ingester pattern
- SSE endpoint at /api/firehose/watch streams filtered events by DID
- auto-reconnects on connection drop
remaining work:
- add UI toggle button and toast notifications in templates
- implement particle animation system in static/app.js
- test with live events
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
some servers (like bsky.app) return HTTP 405 for HEAD requests but work fine with GET. this commit adds a fallback strategy:
- try HEAD first (faster, less bandwidth)
- if HEAD returns error status (405, etc), fall back to GET
- if HEAD fails completely, also try GET
- mark as valid only if either succeeds
this ensures valid URLs aren't incorrectly grayed out while still catching truly invalid domains.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
validates all app URLs concurrently on page load:
- created /api/validate-url endpoint with HEAD request and 3s timeout
- grays out invalid links with reduced opacity
- adds tooltip explaining domain is not reachable
- disables clicking on invalid links
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
reduces client-side javascript by moving core business logic to rust:
- created /api/init endpoint for did resolution, pds extraction, and app grouping
- created /api/avatar endpoint for namespace avatar lookups
- simplified fetchAppAvatar from 30 lines to 8 lines
- removed duplicate avatar fetching logic
- app.js reduced from 760 to 714 lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add tabbed interface for collections with 5+ records (records/mst tabs)
- implement canvas-based MST tree visualization
- add hover tooltips showing TID for each node
- add click modal showing full record details (TID, CID, URI, JSON data)
- improve tree layout algorithm to prevent node overlap
- hide scrollbar in detail panel and increase width to 500px
- link to atproto docs for MST and TID explanations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add og:title, og:description, og:image, og:url meta tags
- add twitter:card, twitter:title, twitter:description, twitter:image meta tags
- create og-image.png (1200x630) with @me branding and aesthetic
- matches app's dark gradient background with orbital design
- improves social media sharing experience
- extract javascript from templates.rs into modular static files
- implement 3-step onboarding overlay for first-time users
- add user profile picture to center identity circle
- make entire ui responsive with viewport-relative units using clamp()
- add help button to restart onboarding tour
- improve technical accuracy of onboarding text about atproto
- add actix-files for static file serving
- reduce templates.rs by 600+ lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fetch app logos from reversed namespace handles (e.g., io.zzstoatzz -> zzstoatzz.io)
- group collections hierarchically by sub-namespace in detail panel
- fix load more button to only show when full page returned
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
following tangled.org/core pattern where linting and testing are
combined in one workflow with multiple steps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fix @ symbol positioning: larger (1.2rem) and better aligned with handle
- add structured record display with headers and content sections
- add copy button to each record with visual feedback
- improve mobile responsiveness for identity circle and records
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- move spindle config to .tangled/workflows/ for auto-deploy on push to main
- simplify readme link styling
- improve identity visualization: show @ symbol as label with handle, add "tap for details" hint
- remove redundant @ prefix from handle display since it's now shown as separate label
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add close button (×) to detail panel, visible on all devices
- make close button larger on mobile (40px) for better touch targets
- personalize identity explanation with actual user handle and pds
- change generic text to: "your data lives at bsky.social. apps like bluesky write to and read from this server. you control @yourhandle..."
- fixes mobile bug where panel couldn't be closed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- add spindle.yaml for automated deployment to fly.io on push to main
- install flyctl in ci environment using curl
- deploy using flyctl with FLY_API_TOKEN secret
- add deployed app link to readme
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- upgrade font stack to modern system monospace fonts
- add responsive touch targets for all interactive elements
- improve button/link active states for mobile
- make detail panel full-width on mobile
- add tap highlight removal for better mobile feel
- increase padding on mobile for better usability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- fix logout button to clear localStorage before redirecting
- fix load more button using event delegation for dynamic buttons
- add interactive identity circle with pds info on click
- improve record display styling with better spacing and hover effects
- improve overlay behavior to close all panels
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- use AtprotoClientMetadata for https URLs (production)
- use AtprotoLocalhostClientMetadata for http URLs (local dev)
- add /oauth-client-metadata.json endpoint
- fixes OAuth client creation failure in production
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- update README: friendlier framing, remove condescending language
- add mobile responsiveness: viewport meta, responsive CSS, larger tap targets
- create Dockerfile: two-stage build for minimal production image
- make OAuth production-ready: configurable redirect URI via env var
- add fly.toml: deployment config with production OAuth callback
- create justfile: deploy and dev commands
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
a radial visualization showing your atproto identity at the center,
surrounded by third-party apps that store data in your PDS.
features:
- oauth login with any atproto handle
- session persistence via localStorage
- radial layout of third-party apps grouped by lexicon namespace
- click apps to see collection types
- click collections to view actual record data with pagination
- info modal explaining the atproto ecosystem
- light/dark mode following system preference
- responsive design with monospace courier new aesthetic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>