Commit graph

18 commits

Author SHA1 Message Date
SkateSpots
6407310213 feat(relay): cut over community relay to self-hosted Newlay
Point SKATE_RELAY, the default relay pools, the DM/CVM/zap relay arrays, the cvm-server + push-service defaults, and the archive default at wss://relay.skate-spots.org, keeping the legacy hosted relay as a fallback during the client-update window. Restored 115/115 archived events; the relay runs behind Caddy with TLS. Docs + AGENTS.md updated.
2026-10-12 12:38:13 +07:00
SkateSpots
c794d5fd18 Give Lab profiles a per-craft URL: /lab/<craft>/<pubkey>/<id>
Every provider lived at /coach/<pubkey>/<id> regardless of craft (a barber got
a "coach" URL). New src/lib/labRoutes.ts maps craft kind → segment and builds
the canonical path; the router adds /lab/:craft/:pubkey/:identifier (the craft
segment is cosmetic — the page still resolves by pubkey + identifier) and keeps
/coach/... working for old links. All generated links updated: offer-form
redirects, Lab cards + "Your Lab profiles", cross-links, spot/event/admin links,
the CVM client URL, the share path, and the SPA clean-link shim.
2026-10-04 11:32:15 +07:00
SkateSpots
cbd0287447 fix(sasquatch): cover the organizer + barber Lab roles
useCVMClient's findCoaches ROLE_KIND, self-tag set and getCommunityStats stopped
at 35012, so Sasquatch could not find the event-organizer (35013) or barber
(35014) profiles we added. Extend LabRole, ROLE_KIND, SELF_TAGS and the stats
queries/counts (lab_total) to cover all Lab kinds 35001-35014.
2026-09-27 11:12:14 +07:00
SkateSpots
18cc8218b2 fix(sasquatch): bound AI latency, separate system prompt, verify relay events
- sasquatchBrain: abort each provider request after 15s and give up the whole
  multi-provider attempt after 35s, so a hung OpenRouter/Pollinations call can no
  longer wedge the chat (it now falls through to the static/local fallbacks).
- SasquatchGuide: send the system prompt as a real system message (both the
  first pass and the tool-synthesis pass) instead of smuggling it into a user
  turn, and mark tool output as untrusted — blunts prompt injection via event
  content.
- useCVMClient: signature-verify (verifyEvent) every relay result, matching the
  standalone server and the release-notes claim.
- useCVMServerHealth: stale threshold 1h -> 45m to match the server heartbeat.
2026-09-27 10:32:07 +07:00
shakespeare.diy
8d464a05f3 fix: resolve pre-existing tsc errors blocking the test gate
Two type errors (surfaced by `npm run test` / tsc --noEmit on a full
toolchain; the in-browser bundler does not run tsc, so they were latent):

- useCVMClient.ts: remove a malformed cast
  `spots as typeof spots & { tags; created_at }[]` feeding
  deduplicateByIdentity(). The intersection dropped pubkey/kind and broke
  the reassignment to `spots`. deduplicateAddressable() already returns
  the correct shape, so the cast was both wrong and unnecessary.

- queryPersister.ts: import PersistedClient / Persister from
  @tanstack/query-persist-client-core (their canonical source) instead of
  @tanstack/react-query-persist-client, whose `export *` re-export tsc
  won't resolve for named type imports. Added the core package (5.102.8,
  matching the pinned wrapper) as an explicit dependency.

Both are pre-existing issues on the branch, unrelated to the audit
remediation commits.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-24 19:46:27 +07:00
shakespeare.diy
00482fc332 Security polish (audit F5-F6): disable broad allowMixedContent on Android (loopback cleartext stays via network_security_config); document CVM client's intentional fixed data-relay set + IP-disclosure privacy note
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-24 18:15:19 +07:00
shakespeare.diy
ee23f3e063 Fix spot dedupe: merge same-named spots across geohash/city + name-suffix variants
The old identity dedupe keyed on `name|place` where place was a single field
(geohash OR location OR city, first non-empty). Two copies of the same spot —
one carrying a geohash, one carrying only a city — produced different keys and
both survived (the Yellow Park duplicate).

Now:
- Name is reduced to a signature that strips trailing generic words
  (skatepark/park/plaza/spot/diy/...) and leading articles, so "Yellow Park",
  "Yellow Park Skatepark" and "Yellow Park " collapse to "yellow".
- Places are compared on human-readable tokens (location/city/country) only;
  the opaque geohash is excluded. An empty place on either side is treated as a
  wildcard, so a geohash-only copy still merges with a "Bangkok" copy.
- Genuinely different spots (different name signatures, or non-empty places with
  no shared token) are still kept separate; single-word names are preserved so
  generic names don't over-collapse.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-09 23:56:00 +07:00
shakespeare.diy
7e7cf0a8bf Sasquatch fast-path: don't dead-end on empty/typos
The local fast-path was stricter than the AI it replaced: a typo like "bangok"
won't substring-match "Bangkok", so the fast-path returned a false "No spots
listed there yet" even though Bangkok has spots.

Two-layer fix:

1. Safety net (most important): if a finder fast-path comes back EMPTY, fall
   through to the AI path instead of rendering "nothing found". The AI normalizes
   spelling and can still find results. Stats/weather always render immediately.
   Net effect: fast when the local match works, correct-always via AI when it
   doesn't — never a false empty.

2. Typo tolerance: findSpots city matching now uses placeMatches() — substring
   OR edit-distance-1 against candidate word tokens (only for queries ≥4 chars,
   so short words can't over-match). So "bangok" matches "Bangkok" on the fast
   path too. Freeform content stays a strict substring check to avoid false hits.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-09 23:52:08 +07:00
shakespeare.diy
8b7d9ca4ea Fix Sasquatch spot results: honest count + collapse duplicates
Two bugs from "spots in bangkok" (said "Found 20" but showed 6, with repeats):

1. Misleading count: formatLocalResults hard-capped the visible list to 6 while
   the headline reported the full count. Now shows up to 10 and appends a
   truthful "…and N more — see them all on the map" line, so the number and the
   list always agree.

2. Duplicate spots: coordinate dedupe (kind:pubkey:d) can't catch the same
   real-world spot re-posted under a different identifier or by another account
   (e.g. "Yellow Park – Sukhumvit 50" appearing twice). Added
   deduplicateByIdentity() — a second-pass dedupe on a normalized
   name + geohash/location signature, keeping the freshest event — applied in
   findSpots so the count and list are clean.

Both fixes flow through the AI tool-call path and the offline fallback path.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-09 23:17:15 +07:00
shakespeare.diy
ada4bfee5e Accelerate Sasquatch custom questions (live-data queries)
Three low-risk speedups focused on the slowest path — questions that hit live
relay data:

1. Relay timeout 10s → 4.5s (6s for the fan-out community stats). The useful
   relays answer in ~2s; the old 10s just let one slow/dead relay stall the
   whole reply.

2. Results-first: for finder tools (spots/events/coaches/gear/crews/shops/
   tours/stats/weather) format the CVM result locally and SKIP the second
   "prettify" AI call. Removes a full model round-trip (~2–4s) — users want the
   list, not extra prose. New toolCallToIntent() maps a tool call to the existing
   formatLocalResults() path. Personal/Pro tools (get_my_*) still use AI synthesis.

3. Faster AI fallback: cap OpenRouter attempts to the top 3 free models before
   the keyless backup, and shorten 429 backoff (≤800ms vs ≤2500ms). Avoids the
   worst-case 15–20s grind through 8 models on a busy free tier.

Conversational/knowledge answers (single AI call) keep Sasquatch's personality
and are untouched.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-09 23:11:14 +07:00
shakespeare.diy
407ba40a33 Sasquatch: full public-data coverage (all Lab crafts + shops + tours)
- findCoaches now covers EVERY Lab craft (coach, filmer, editor, photographer,
  builder, artist, graffiti, tattoo, trainer, musician, judge) via role param;
  reads skills from `t` tags and strips self-tags.
- New findShops (kind 30017, t=skateshop) and findTours (kind 30823) tools.
- getCommunityStats counts all crafts individually + lab_total + shops + tours,
  and filters spots to t=skatespot (drops foreign kind-30818 events).
- Wired new tools + expanded role vocabulary into the Sasquatch brain: system
  prompt, intent parser, keyword detector, and both dispatch/format paths.
- Privacy preserved: the public CVM data layer never queries the encrypted
  Stash (kind 30001) — verified no 30001/decrypt references. Personal 'my
  stash' stays login+Pro gated and decrypts locally with the user's own key.
- Normalized useCVMClient.ts to clean UTF-8 (comment glyphs only; no code change)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-08-27 16:14:20 +07:00
shakespeare.diy
dec2e730d2 CVM find_crews: Sasquatch can now live-search crews
- useCVMClient: add findCrews (queries kind 35006 across data relays, filters by
  city/country/vibe/search, returns CrewResult with member_count, vibes, url);
  add crews to getCommunityStats + CrewResult type
- SasquatchGuide: register find_crews tool in system prompt + switch handler,
  add crew keywords to needsLiveData, update app-facts (crews are searchable +
  mention cross-linking and Zap-the-Crew)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:35:16 +07:00
shakespeare.diy
3a4e4ead05 fix: rewrite useCVMClient to query relays directly instead of NIP-44 round-trip
The encrypted CVM request/response cycle (kind 21000/21001) was too unreliable
in the browser — timeouts on every call. Replace with direct Nostr relay queries
using nostr.group() which is already proven to work in the app. Same filtering
logic as the server. No dependency on CVM server being up for data queries.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:32:59 +07:00
shakespeare.diy
a9c677b58d fix: rewrite useCVMClient to use Relay.connect() instead of SimplePool
nostr-tools v2 SimplePool.subscribeMany() callbacks (onevent/oneose) no
longer fire reliably in browser context, causing the CVM client to always
time out. Switch to raw Relay.connect() which uses the v2 API correctly.
Race across all CVM relays and resolve on first valid response.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-17 12:10:31 +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
c643ddb105 fix: add relay.ditto.pub back to CVM client relay list
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 21:47:14 +07:00
shakespeare.diy
9b50cda191 fix: update CVM client relays - remove dead relay.contextvm.net and relay.ditto.pub
Use goskatespots.nostr1.com as primary (matches CVM server config),
plus relay.nostr.band and relay.damus.io as fallbacks.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-16 21:42:22 +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