commits
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>
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>