Commit graph

535 commits

Author SHA1 Message Date
shakespeare.diy
4398c2e73b Fix Amber login stuck on GrapheneOS/Android browsers
Root cause: window.location.href navigates the tab away entirely on Android,
destroying sessionStorage. When Amber calls back to /amber-callback the login
completes there, but returning to the dialog the state is lost.

Fixes:
- Switch from sessionStorage to localStorage for amber_return_path and
  amber_login_attempt_ts — survives tab navigation on Android
- Add 500ms polling loop in handleAmberLogin that checks getAmberLogin()
  every 500ms — detects when AmberCallbackPage stored the pubkey and
  auto-completes login without needing visibilitychange to fire
- Add "I approved — complete login" manual button in waiting state as
  explicit fallback for stuck users (reads localStorage right away)
- AmberCallbackPage now uses localStorage for all persistence
- Clean up poll interval on dialog close and unmount

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 22:37:26 +07:00
shakespeare.diy
03d0fe93b0 Improve Amber login flow - zero friction, auto-complete on return
- Add dedicated /amber-callback route so Amber always has a stable return URL
  - Handles get_public_key (login), sign_event, nip44/nip04 encrypt/decrypt
  - Shows animated processing screen while completing, then redirects back
- Add subscribeToAmberReturn() helper in amber.ts using visibilitychange
  - Auto-detects when user returns to the tab after cancelling in Amber
  - Resets login UI to initial state gracefully
- Update buildCallbackUrl() to use /amber-callback instead of current page URL
- Rewrite Amber tab in LoginDialog:
  - Remove 2-step clipboard paste flow entirely
  - Single tap opens Amber, login completes automatically on return
  - Waiting state shows animated dots + cancel button
  - No manual pubkey entry needed
- Save return path in sessionStorage so AmberCallbackPage redirects user back

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 22:29:06 +07:00
shakespeare.diy
aac2b7b9a2 Improve mobile/Android UI responsiveness
- Add xs (375px) breakpoint to Tailwind config for small phone targeting
- Fix main content bottom padding to account for safe-area-inset-bottom
- Redesign mobile bottom nav: active dot indicator, proper safe-area padding,
  flex-1 tabs that scale to any width, tighter text on xs screens
- Fix hero section: smaller padding/text on tiny phones (320-375px),
  horizontal badge wrapping, full-width buttons stack below xs
- Add CSS improvements: overscroll-behavior, -webkit-text-size-adjust,
  input font-size fix for iOS zoom prevention, scroll-x helper class,
  touch-friendly min tap target sizes

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 22:04:29 +07:00
shakespeare.diy
a3cd6cf9f4 feat: Sasquatch clickable links, weather tool, ContextVM footer
- ChatText component renders markdown [label](url) and bare URLs as neon clickable links
- 👉 URL patterns also rendered as clickable links
- get_weather tool: real-time weather + skateability score via Open-Meteo
  Ask "weather in Bangkok?" or "is it good to skate in Barcelona today?"
- Footer updated: "Powered by ContextVM & Nostr Relays Data" with ContextVM
  linking to https://contextvm.org/s/e3564bb877...
- Weather geocodes city name via Nominatim, returns temp/conditions/wind/skateability

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 15:55:53 +07:00
shakespeare.diy
f9c0f3c5ac feat: redesign Sasquatch UI - dark jungle aesthetic, mobile-first
- Dark forest green + neon lime (#ccff00) theme matching app's THUG2 aesthetic
- Mobile: compact strip above bottom nav, no more full-width overlay
- Minimized: small round button with neon pulse, lives at bottom-left
- Jungle texture strips top/bottom, dark gradient background
- Chat bubbles: neon red for user, neon lime for Sasquatch
- Input styled to match dark app theme
- Neon glow effects, live dot indicator
- Works cleanly on all screen sizes

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:50:41 +07:00
shakespeare.diy
c31f79e8b0 fix: improve Sasquatch prompts for accuracy and cleaner responses
- Rewrite system prompt: coaches in Thailand → search Bangkok, use limit:20
- Second-pass prompt explicitly bans JSON tool calls in responses
- Country → city mapping guidance (Thailand → Bangkok)
- Cleaner formatting instructions for results presentation

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:46:39 +07:00
shakespeare.diy
c672066c2c fix: update free AI models to confirmed-working OpenRouter models
Previous models (llama-3.1-8b, gemma-3-4b, mistral-7b) returned 404 unavailable.
Tested and confirmed working: openai/gpt-oss-20b:free and google/gemma-4-31b-it:free.
Keep llama-3.3-70b as quality option when not rate-limited.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:20:28 +07:00
shakespeare.diy
cb7714d875 fix: Sasquatch AI fallback chain + greeting responses + better error message
- Try 4 free OpenRouter models in order (rate limit resilience)
- Add greeting responses to static FAQ so hi/hello/hey never need AI
- Fix static FAQ to exact-match short words like "hi" before partial match
- Better error message explaining free tier rate limits

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:16:13 +07:00
shakespeare.diy
84aa009b33 fix: CVM server tag mapping + add city/country geocoding to spots
CVM server fixes (cvm-server/server.ts):
- Use 'title' tag instead of 'name' to read spot names (app publishes 'title')
- Search now checks 'title' tag (not just 'name') for keyword matches
- City filter now also checks 'title' tag and event content
- Country filter also checks event content
- Features filter now checks 't' tags (app uses 't' not 'feature')
- Validate spots with 't: skatespot' tag (same rule as the app)
- Return 'location' field and proper features list in results
- Image parsing now supports both 'image' (legacy) and 'imeta' (NIP-92)

CreateSpotPage fix (src/pages/CreateSpotPage.tsx):
- Add reverse geocoding via Nominatim on spot submit
- Emit structured 'city' and 'country' tags so CVM can filter by them
- Auto-fill location field from geocoding if user left it blank

SasquatchGuide improvement (src/components/SasquatchGuide.tsx):
- Add data model notes to system prompt explaining tag structure
- Instruct AI to handle 0-result responses gracefully (encourage adding spots)
- Use limit:20+ for city/country searches

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 11:14:50 +07:00
shakespeare.diy
252163625e feat: rebuild Sasquatch as proper CVM agent bridge
- Rich system prompt that explains the CVM architecture: it aggregates
  across multiple relays, deduplicates, and filters by features inside
  events (complex queries that plain Nostr filters can't do)
- Switched tool call format from fragile regex (TOOL:name {...}) to
  clean JSON {"tool":"name","args":{...}} that's easier for the LLM
- More robust JSON parsing — scans the full AI response for the tool call
- Better second-pass prompt: AI formats results with bullet points + links
- Updated suggested questions to showcase real CVM queries
- CVM failure gives a clear message explaining what the server does

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:39:51 +07:00
shakespeare.diy
c2b7a29d07 feat: update default relay set to all 5 relays
Added auth.nostr1.com and wotr.relatr.xyz back as default relays.
All 5 relays are now the default for all new users:
- wss://auth.nostr1.com (auth)
- wss://wotr.relatr.xyz (web of trust)
- wss://relay.ditto.pub (general)
- wss://goskatespots.nostr1.com (community - toggleable)
- wss://purplepag.es (profiles - read only)

Updated across: App.tsx, NostrProvider.tsx, NostrSync.tsx, TestApp.tsx
Updated Settings page Default Relays info cards to show all 5 with descriptions.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:35:09 +07:00
shakespeare.diy
5526265aea fix: update free model to meta-llama/llama-3.3-70b-instruct:free
The 3.1-8b:free model is no longer free on OpenRouter.
Switching to llama-3.3-70b:free which is available and actually
a much better model (70B vs 8B).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:25:33 +07:00
shakespeare.diy
966907a848 chore: clean up console noise - remove debug logs from NostrProvider, NostrSync, useShakespeare
Removed:
- [NostrProvider] Routing query to read relays (fired on EVERY query)
- [NostrProvider] Publishing kind X to relays
- [NostrSync] Starting sync / querying profile / profile query returned / sync completed
- [NostrSync] Profile not found on main relays
- [NostrSync] Profile synced and cached
- [Shakespeare] Fetching / Model / Response status debug logs

Kept all warn/error logs for actual failure cases.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:23:00 +07:00
shakespeare.diy
89b43a44e6 fix: remove leftover shakespeare reference from useCallback deps array
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:06:41 +07:00
shakespeare.diy
9be89bf287 feat: switch Sasquatch to free OpenRouter model - works for everyone
Replaced Shakespeare AI (paid, NIP-98) with OpenRouter free model
(meta-llama/llama-3.1-8b-instruct:free). No login required, no credits
needed - anyone can use Sasquatch AI for free.

- Removed useShakespeare hook dependency from SasquatchGuide
- Added direct callAI() function using OpenRouter API
- AI + CVM live data still works the same way
- Removed login nudge, updated placeholder and AI badge

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 22:05:27 +07:00
shakespeare.diy
b815cbfda6 fix: remove dead relay.nostr.band from all relay lists across the app
Removed from: useCVMClient, NostrSync, useLoggedInAccounts, useAuthor, SettingsPage
Replaced with relay.damus.io where a fallback was still needed.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 21:49:02 +07:00
shakespeare.diy
223b7602bf fix: correct model ID to 'shakespeare/claude-sonnet-4.6' for Shakespeare AI
Previous attempts used 'shakespeare' and 'claude-sonnet-4-5' — both invalid.
The correct format matches the recentlyUsedModels in ai.json config:
provider/model-name with dots not dashes.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 20:26:01 +07:00
shakespeare.diy
2aeb41afdc fix: use correct model ID 'claude-sonnet-4-5' for Shakespeare AI calls
The model name 'shakespeare' does not exist on the API — it was returning:
  "Model 'shakespeare' is not supported" (400 invalid_request_error)

Updated both sendChatMessage calls in SasquatchGuide and the default
model in useShakespeare hook (sendChatMessage + sendStreamingMessage).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 20:05:26 +07:00
shakespeare.diy
9d1e875c36 fix: remove wss://wotr.relatr.xyz relay that was consistently failing
The wotr.relatr.xyz relay was generating a flood of AbortError warnings
on every query because it was consistently unreachable/timing out.

Removed from:
- src/App.tsx (default config)
- src/components/NostrProvider.tsx (DEFAULT_RELAYS)
- src/components/NostrSync.tsx (NEW_USER_RELAYS for new users)
- src/test/TestApp.tsx (test config)

Replaced the Settings page entry with purplepag.es (profile aggregator)
which is already in the relay list and actually working.

Updated Sasquatch FAQ answer to reflect the correct relay list.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:52:02 +07:00
shakespeare.diy
632de3e5bd fix: wrap AI block in try/catch for graceful fallback when Shakespeare API fails
If the AI call throws (400, 401, network error, etc.), Sasquatch now:
- Catches the error silently (logs to console as warning)
- Falls back to the static FAQ answer if one matches
- Falls back to a friendly "try again" message if no FAQ match
- Never shows a crash or blank response to the user

The toolMatch reference inside the try block is properly scoped so the
isLive flag works correctly when the full AI + CVM flow succeeds.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:47:49 +07:00
shakespeare.diy
054c06d573 fix: shorten system prompt, improve 400 error logging in Shakespeare hook
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:42:22 +07:00
shakespeare.diy
ba8b65b6d9 fix: remove system role from Shakespeare AI calls, embed prompt in user message instead
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:39:50 +07:00
shakespeare.diy
4aebbc8798 fix: use correct 'shakespeare' model name in SasquatchGuide AI calls
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:36:24 +07:00
shakespeare.diy
fadf36d86e feat: upgrade Sasquatch from static FAQ to live AI agent with CVM data
- Add useShakespeare.ts hook (Shakespeare AI via NIP-98 auth)
- Add useCVMClient.ts hook — calls SkateSpots CVM server tools over
  Nostr directly from the browser (NIP-44 encrypted request/response,
  no @contextvm/sdk bundle needed, pure nostr-tools)
- Rewrite SasquatchGuide to use Shakespeare AI + live CVM data:
  * Static FAQ answers for protocol/app questions (fast, no API)
  * Shakespeare AI for natural language understanding
  * AI detects TOOL: calls in its response and executes them live
  * CVM server queried for find_spots, find_events, find_coaches,
    find_gear, get_community_stats
  * Streaming "thinking..." and "Searching Nostr..." indicators
  * Live/offline status badge shows CVM server connectivity
  * Graceful fallback when CVM server unreachable
  * Login nudge for unauthenticated users

CVM server pubkey: e3564bb877adb0c99a7e4973ccb22e516d7d9eca0027d0bd62a04174ed670530
CVM server host: 185.18.221.2 (LNVPS, Dublin)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 19:30:00 +07:00
shakespeare.diy
ebbf2d6326 fix: remove orphaned canvas code from RiderCardPage causing ctx/Printer is not defined crash
The drawCardToCanvas function had an old version of the card rendering logic
that leaked outside the function body (lines 505-731 were orphaned code).
This code referenced local variables (ctx, p, data, qrX, qrSize, PAD, etc.)
that only existed inside the function, causing ReferenceError at module load time
and crashing the entire app with a blank screen.

Also added missing lucide-react imports (Printer, Loader2, Share2, Download,
Check, Copy, Award, Zap, Info, Palette, Shield, ChevronUp, ChevronDown) that
were used in the JSX but not imported, causing the secondary Printer is not
defined ReferenceError.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 17:02:59 +07:00
shakespeare.diy
6ba5dc1187 Fix QRCodeCanvas: guard against empty value and null context
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 16:17:56 +07:00
shakespeare.diy
838ef3f355 feat: SkateSpots Rider Cards — 3 card types, 6 themes, holographic shimmer, print-ready
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 14:29:54 +07:00
shakespeare.diy
4e227f0367 feat: License page, Video Editors in Lab, Buy/Sell Gear, Stash locations, Supporters page
1. /license page
   - New LicensePage with "YOU ARE FREE TO SKATEBOARD" license text
   - Copyright 2025-∞ with neon THUG2 styling
   - Footer: "License" and "Supporters" links added next to OpenSats

2. /lab — Video Editor category
   - New SKATE_EDITOR_KIND (35003) in types.ts
   - EDITOR_SERVICE_LABELS/DESCRIPTIONS (8 edit types)
   - EDITOR_SKILL_LABELS/DESCRIPTIONS (8 software/hardware skills)
   - SkateEditor interface + parseSkateEditor() parser
   - useLabProfiles updated to query kind 35003 + 'skateeditor' tag
   - LabPage: new "Video Editors" tab (purple, Scissors icon)
   - LabPage: "Offer Editing" button in header
   - BecomeEditorPage: full form with edit types, skills, hardware,
     software, portfolio, contact, location, wallet requirement
   - Route /become-editor registered in AppRouter

3. /map Quick Actions
   - "Sell Gear" → "Buy/Sell Gear" with ArrowRightLeft icon
   - Button now links to /marketplace (browse + sell)

4. /stash — Storage locations
   - StashItem.storageLocation field: home/warehouse/friends/parents/wardrobe/other
   - AddItemDialog: 6-button grid to tag where gear is stored
   - StashItemCard: shows location badge on each card
   - Filter bar: pill filter chips to filter stash by location
   - storageLocation saved/restored via onAdd handler

5. /supporters page
   - btcmap.org-style supporters page
   - Live Geyser GraphQL leaderboard (skatespots project)
   - Avatar grid with sat amounts, anon fallbacks
   - Mission section + "Send Sats" section (Lightning address + Geyser)
   - Added to footer and desktop "More" dropdown and mobile menu

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 11:05:03 +07:00
shakespeare.diy
122bdfb102 Sync with skate-spots: THUG2 neon theme, remove old AuthDialog and unused lib files
- Replace generic MKStack default CSS with THUG2-inspired neon theme:
  - Neon red primary (#ff0040) and neon lime accent (#ccff00)
  - Pure black dark mode background
  - Custom CSS variables for gradients, sidebar, and animations
  - Leaflet map dark mode overrides
  - Custom scrollbar styling
  - Mobile touch target improvements and iOS input zoom fix
  - Safe area insets for notched devices
  - scrollbar-hide utility class
  - Animation classes: neon-glow, stagger, fadeIn, slideUp, pulse-glow
  - Glass effect and gradient-text utilities
- Remove AuthDialog.tsx (old Sign Up flow replaced by newer LoginArea/SignupDialog)
- Remove appBlossom.ts and appRelays.ts (not used in this project)
- Remove useLoginActions.test.tsx (not present in reference version)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 23:00:01 +07:00
shakespeare.diy
e29d35f1e4 fix: restore full skate-spots source tree from misplaced src/src/ copy
The entire skate-spots codebase was accidentally copied into src/src/ and
public/public/ instead of src/ and public/ directly. This left the real
src/ directory as blank MKStack template stubs, explaining why the landing
page showed the default template instead of SkateSpots.

Changes made:
- Copied all files from src/src/ up to src/ (App.tsx, AppRouter.tsx, main.tsx,
  all pages, components, hooks, contexts, lib, i18n, test)
- Copied all files from public/public/ up to public/ (images, manifest, etc.)
- Deleted src/src/ and public/public/ nested directories
- Removed HelloWorld.tsx template stub from pages/
- Retained the previously fixed index.css (Tailwind v3 directives)

Full skate-spots feature set is now active:
- All 30+ routes (map, events, spots, coaches, marketplace, wallet, etc.)
- NWCProvider, LanguageProvider, PWAInstallPrompt, AmberCallbackHandler
- Skate community relays (goskatespots.nostr1.com, wotr.relatr.xyz, etc.)
- Outfit Variable font, Amber pre-check in main.tsx
- All hooks (useSkateSpots, useCoaches, useZaps, etc.)
- i18n support (en/es)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 22:18:28 +07:00
shakespeare.diy
85c2bdc5cc fix: replace radix-ui umbrella imports with direct @radix-ui/react-* packages
The shadcn/ui components were using the new "radix-ui" umbrella package
import style (e.g. `import { Tooltip as TooltipPrimitive } from "radix-ui"`).
However, radix-ui@1.5.0 re-exports ALL radix primitives including ones not
installed (@radix-ui/react-accessible-icon, @radix-ui/react-form,
@radix-ui/react-one-time-password-field, @radix-ui/react-password-toggle-field,
@radix-ui/react-toolbar), causing esbuild to fail with 5 unresolved import
errors outside Shakespeare.

Fix: rewrite all 32 imports across the ui/ components to import directly
from their individual @radix-ui/react-* packages (which are all already
installed). Remove the radix-ui umbrella package entirely from package.json
and package-lock.json.

Affected files (32 import changes):
accordion, alert-dialog, aspect-ratio, avatar, badge, breadcrumb, button,
checkbox, collapsible, context-menu, dialog, dropdown-menu, form, hover-card,
label, menubar, navigation-menu, popover, progress, radio-group, scroll-area,
select, separator, sheet, sidebar, slider, switch, tabs, toggle-group, toggle,
tooltip

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 22:01:07 +07:00
shakespeare.diy
947bb2784b fix: resolve Zod compatibility issue
- Change z.url() to z.string().url() in AppProvider.tsx for Zod compatibility
- Update Zod version from ^3.25.71 to ^3.23.8 (valid published version)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 21:26:53 +07:00
shakespeare.diy
e5f26f4b1f Revert "fix: resolve Zod compatibility issues for clean build"
This reverts commit be47816c64.


Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 21:24:25 +07:00
shakespeare.diy
be47816c64 fix: resolve Zod compatibility issues for clean build
- Update Zod version from ^3.25.71 to ^3.23.8 (valid published version)
- Replace z.url() with z.string().url() in AppProvider.tsx for compatibility
- Remove unused npubcash-sdk dependency
- Remove duplicate nested src/src directory that was incorrectly created

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 20:53:41 +07:00
shakespeare.diy
06fae294b8 New project created with Shakespeare
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 19:49:07 +07:00