Commit graph

183 commits

Author SHA1 Message Date
SkateSpots
118b91188e release: 1.7.1 2026-10-27 09:13:09 +07:00
SkateSpots
ac5ad39515 chore(ops): 16-day deps gate, weekly CVE scan, overrides, release helper
- Dependency job is now 16 days (service env + script default); a separate
  weekly scan-only timer reports npm/OSV findings without changing the lockfile.
- TimeoutStartSec=30min on the deps job and 20min on the deploy job (systemd's
  90s default could kill a legitimate run); both scripts resolve the newest nvm
  Node instead of hardcoding v22.23.1.
- npm override pins @tanstack/query-core to $@tanstack/react-query so a blanket
  npm update cannot create a second copy (the Oct 26 tsc failure).
- Failed runs keep test/smoke logs + attempted package files in failures/
  (rotated, 8 kept) and a last-failure marker; reports rotate (12 kept).
- scripts/release.sh: notes check -> npm test -> bump -> Android build ->
  zsp publish -> relay verify -> commit/push + tag.
- Deploy/deps systemd units are tracked under scripts/systemd/.
2026-10-27 09:09:45 +07:00
SkateSpots
828684cf15 feat(i18n): add Hindi (24 dictionaries, 25 codes, all 100%)
- Full 8,703-key Hindi dictionary in src/i18n/hi (7 namespace batches),
  placeholders verified, only 2% identical strings (brand/protocol names).
- Register hi in Language/LANGUAGE_LOADERS, detectLanguage (hi-IN),
  LanguageToggle (🇮🇳, हिन्दी) and dateFnsI18n (hi-IN).
- Lazy-load Noto Sans Devanagari for hi via lib/localeFonts.ts (renamed from
  cjkFonts.ts) and add it to the CSS font stack; other locales don't download it.
- check-i18n covers hi: 24 dictionaries / 25 codes at 100%; tsc/tests/build green.
2026-10-26 16:35:53 +07:00
SkateSpots
67f21bf1ac release: 1.7.0 (authoritative map, pass-the-app, clearer sign-in, security)
Bump 1.6.8 -> 1.7.0. Notes: canonical map + restored spot; Android share-app
card; 3-card sign-in with per-session desktop welcome; zod 4 + nostrify 0.50 +
react-router 7 + vitest 5 (audit 35 -> 8). APK built + published + verified.
2026-10-26 12:45:10 +07:00
SkateSpots
66e2ac20ac chore(security): react-router 7 + vitest 5; audit 13 -> 8
- react-router-dom/react-router 7.18.4: the app only uses the v6-compatible API
  (Link/NavLink/Routes/HashRouter + hooks), so zero code changes; tsc, tests and
  the full-route boot smoke all pass. Clears the open-redirect advisory.
- vitest 5.0.5 (dev): clears vitest/@vitest/mocker/tinypool criticals. Setup now
  imports @testing-library/jest-dom/vitest for the new expect types.
npm audit: 8 total (0 critical, 1 high = xlsx write-only, 7 moderate = build
tooling).
2026-10-26 12:41:45 +07:00
SkateSpots
37fa5c1f58 chore(security): zod 4 + nostrify 0.50 migration; audit 35 -> 13
- zod 3.25 -> 4.6.7 (only AppProvider uses zod; no zod-3-isms, zero TS changes).
- @nostrify/nostrify 0.47.1 -> 0.50.5, @nostrify/react 0.2.17 -> 0.2.31,
  @nostrify/types 0.36.9 (0.50 moved to zod 4; this clears the nostrify chain).
- npm audit fix applied the safe transitive fixes (react-router 6.30.6,
  dompurify 3.4.17, lodash 4.18.1, @modelcontextprotocol/sdk 1.32.2).
Remaining: dev-only vitest/tinypool (major), xlsx (no fix; write-only export),
react-router moderate (needs v7), build tooling (tailwind/postcss/capacitor-cli).
npm test green.
2026-10-26 12:29:55 +07:00
SkateSpots
f8ec7e35c0 release: 1.6.8 (3-card sign-in, curated deps, AGPL on Zapstore)
- 3-card sign-in chooser + desktop welcome modal (from 2164dd6's LoginDialog
  restyle) ships.
- Curated dependency fixes (vite 6.4.5 / vitest 3.2.7 / unhead 2.1.17 /
  yaml 2.9.1, TS pinned 5.8.3) — OSV 107 -> 59.
- zapstore.yaml license: custom -> AGPL-3.0-only (the listing now shows the real
  licence; verified on the 32267 tag).
Bump 1.6.7 -> 1.6.8, APK built + published + verified.
2026-10-26 11:27:04 +07:00
SkateSpots
221ba5c253 chore(deps): curated fixes (vite, vitest, unhead, yaml) + pin TypeScript
Targeted, tests-green update instead of a blanket npm update:
- vite 6.3.5 -> 6.4.5, vitest 3.1.4 -> 3.2.7, @unhead/react 2.1.17 (unhead
  2.1.17), yaml 2.9.1; npm dedupe.
- typescript pinned to 5.8.3 (exact) so npm i can't drift into the 5.9
  typed-array breakage that failed the last auto-update.
OSV findings: 107 -> 59. Remaining are transitive/major (vitest 4, valibot 1,
uuid 11, zod 4) or xlsx (no fix; write-only export, parse CVEs don't apply).
npm test green.
2026-10-26 11:24:36 +07:00
SkateSpots
4d9389fa48 release: 1.6.7 (Amber result-compression fix)
Bump 1.6.6 -> 1.6.7. Native Amber intents now send compressionType=none and the JS
signer decodes Signer1 gzip results, so long encrypted payloads no longer fail.
APK built + published to Zapstore (verified on relay.zapstore.dev).
2026-10-14 06:31:06 +07:00
SkateSpots
704714583f release: 1.6.6 (crew chat simplification, decrypt cache, i18n, invite)
Bump 1.6.5 -> 1.6.6, notes for the always-NIP-17 crew chat, instant sends +
persisted decrypt cache, the 20-locale i18n backfill, and the private-chat invite.
APK built + published to Zapstore (verified on relay.zapstore.dev).
2026-10-13 20:57:15 +07:00
SkateSpots
c7be44dfb3 release: 1.6.5 (crew chat fixes)
Messages now appear on send; shared DM decrypt cache stops per-view re-decrypts;
double-send guarded. Bump 1.6.4 -> 1.6.5, APK built + published to Zapstore
(verified on relay.zapstore.dev).
2026-10-13 00:31:07 +07:00
SkateSpots
07d4df037d release: 1.6.4 (crew chat sends with Amber no longer fail)
Fix: sending to a crew sequential-ised its per-recipient signer intents, so Amber
approvals land instead of timing out. Bump 1.6.3 -> 1.6.4, APK built + published
to Zapstore (verified on relay.zapstore.dev).
2026-10-13 00:10:12 +07:00
SkateSpots
6c10d880c6 release: 1.6.3 (Amber pop-ups, Crews in Messages, crew-chat UX)
Bump 1.6.2 -> 1.6.3, notes for the Amber navigation fix, the Messages Crews
section, and the crew encrypted-chat card rewrite. APK built + published to
Zapstore (verified on relay.zapstore.dev).
2026-10-12 23:48:08 +07:00
SkateSpots
f73190ab81 release: 1.6.2 (onboarding pop-up fixes)
Bump 1.6.1 -> 1.6.2, release notes for the first-run checklist + backup-reminder
fixes. APK built and published to Zapstore (verified on relay.zapstore.dev).
2026-10-12 23:15:11 +07:00
SkateSpots
bcc3eceeee Cordn native: default crew tab to the private chat + founder nudge; release 1.6.1
- Crew page defaults to the Private-chat (MLS) tab when this device already has
  the group (useCordnGroupExists reads the IndexedDB snapshot — local only, no
  signer prompt); a manual tab click always wins.
- Founder/admin banner ('Set up') points at the tab when the crew has no group.
- Bump 1.6.0 -> 1.6.1 and add release notes for everything since 1.6.0 (private
  crew chat/MLS, self-hosted relay + media, marketplace close-the-deal, trust
  controls, map/weather, Clothing Designer, UI fixes).
2026-10-12 22:52:33 +07:00
SkateSpots
1dcaf8cea3 Cordn native: real MLS client (Level 2 foundation)
Add src/lib/cordn/native/ — a browser-safe Cordn client doing real RFC 9420
MLS over a ContextVM coordinator, mirroring Cordn's wire contract (reimplemented,
not copied from @cordn/cli).

- mls.ts: identity, key packages, group create/add/join, application messages,
  the ChaCha20-Poly1305 coordinator wrapper, causal prev tags.
- coordinator.ts: ContextVM/MCP-over-Nostr client on @contextvm/sdk, validated
  with @cordn/core schemas.
- session.ts: CordnSession (key packages, createGroup, addMember->Welcome,
  joinGroup, send, fetch) with persistence behind an injectable CordnStore
  (MemoryCordnStore today; IndexedDB adapter TODO).
- Verified end-to-end against our own coordinator: a two-member round trip
  (CORDN_LIVE=1 vitest run native.live.test.ts) — create, add, join, and
  bidirectional encrypted messages with proven senders.

Deps: @cordn/core, @contextvm/mcp-sdk, @noble/ciphers pinned 2.2.0 (fixes the
previously invalid tree: ts-mls wants 2.2.0, a stale root copy was 0.5.3).
src/test/setup.ts is now guarded for node-environment test files. Not wired to
any UI yet; nothing imports the module, so the web bundle is unchanged.
2026-10-12 22:14:20 +07:00
SkateSpots
71ecb03ae8 chore(license): use the canonical AGPL-3.0 verbatim
Replace the license file with the unedited AGPL-3.0 text (copied in full
from the teambtcmap/btcmap-android LICENSE, byte-identical). No project
header and no 'or later' grant, so SPDX is AGPL-3.0-only. AGENTS.md records
the rationale and the section-13 source-offer implication.
2026-10-09 17:33:39 +07:00
SkateSpots
30903eadb0 chore(license): adopt AGPL-3.0-or-later
Add the canonical AGPL-3.0 text at /LICENSE (with the project copyright
notice on top) and set package.json license to AGPL-3.0-or-later. Chosen
because the trust work reviews AGPL reference implementations and we
reimplement rather than copy; AGPL section 13 source-offer is covered by
the public repo + the License page's source link. Recorded in AGENTS.md.
2026-10-09 17:30:01 +07:00
SkateSpots
0f01eb1bc6 chore: bump to 1.6.0 (10 new languages) 2026-10-08 17:21:57 +07:00
SkateSpots
1460b06277 i18n: lazy-load locales + register 8 new (pt fr de it nl pl ru ko) with fonts 2026-10-07 21:23:39 +07:00
SkateSpots
ab05973ff0 i18n(ja): add Japanese as fourth locale (plumbing + font + batch 1 shell) 2026-10-07 17:21:18 +07:00
SkateSpots
b8c306125c i18n(th): batch 2 — map (mapUi + mapPage) + AGENTS note 2026-10-06 13:35:20 +07:00
SkateSpots
39572998a0 feat(clink): real bech32+TLV decode/validation (lib/clink.ts), spec-correct raw QR/copy, show decoded pricing; validate scanner 2026-10-06 11:16:20 +07:00
SkateSpots
fb16ea74c0 fix(dev): self-healing lazyWithRetry (retries + cooldown reload); add dev:fresh; auto-restart dev on dep changes 2026-10-05 23:37:46 +07:00
SkateSpots
cc50eaad18 chore(release): bump to 1.5.13 + release notes 2026-10-05 21:52:18 +07:00
SkateSpots
1a8c483682 Deck cost calculator: quote PDF, PNG, XLSX, copy, supplier import
Export ▾ now offers: PDF (full sheet), PDF (client quote — uses an optional
businessName), PNG summary card (canvas), XLSX multi-sheet workbook (lazy
SheetJS), CSV, Markdown, JSON, and Copy summary (clipboard).

Import auto-detects the CSV shape: a `name,order_cost,…` header is treated as a
supplier price list and replaces the Materials table; otherwise the CSV
round-trips the whole sheet. JSON still loads a backup.
2026-10-05 10:54:37 +07:00
SkateSpots
71f53bcc51 Deck cost calculator: export a PDF by default
The toolbar's primary Export now generates a real PDF (lazy-loaded jspdf) — a
formatted one-page summary: labour, equipment, operations, materials, processes,
packaging, margins and the selling prices, plus the date/currency. Print-to-PDF
was rejected because window.print() doesn't work in the Capacitor WebView.

A secondary JSON export stays (for Import/backup); Import still reads JSON.
jspdf is dynamically imported so it never enters the initial bundle.
2026-10-05 10:36:25 +07:00
SkateSpots
ef5a30eb5f chore(release): v1.5.12 2026-10-03 22:50:48 +07:00
SkateSpots
89ec54cb23 chore(release): v1.5.11 2026-10-03 19:36:24 +07:00
SkateSpots
7d51fc60a5 feat(nfc): native Android tag-writer plugin (APK) + Web NFC on web
Web NFC isn't exposed in Capacitor's WebView, so the APK needs a native writer.
Adds packages/skatespots-nfc — a local Capacitor Android plugin (Kotlin,
enableReaderMode + NDEF URL record), registered BY NAME (not bundled). lib/nfc.ts
now uses the plugin on native and Web NFC on the web. iOS can't write tags.
⚠️ UNVERIFIED (needs cap sync + a device). README documents it.
2026-10-02 14:14:31 +07:00
SkateSpots
09735375c2 feat(i18n): Spanish (Castellano) — infra + Map/Spots, Marketplace, Lab (batch 1)
- First-visit language auto-detect (Spanish devices land in es; stored choice wins).
- Sasquatch AI replies in the app language (skate trick names kept English).
- i18n safety net: scripts/check-i18n.mjs wired into npm test — fails on any t()
  key missing from en/es or any en/es key drift.
- ~1,680 new keys (2,297 total) across mapUi / spotUi / marketUi / labUi and
  ~65 files wired to t(): Map, spots (detail/create/edit/chat), marketplace,
  trades, offers, escrow, shipping, The Lab, /become/* forms, coaches, skaters.
- Policy: only skate TRICK names stay English; user-generated content untouched.
2026-10-01 23:57:20 +07:00
SkateSpots
3ad214683a feat(android): native background poller plugin (no Google) - Cordn pattern
packages/skatespots-background: a local Capacitor Android plugin that polls our
own push-service /pending and raises local notifications. Modes: off / standard
(WorkManager ~15 min) / fast (foreground service ~5 min). Kotlin +
AndroidManifest (POST_NOTIFICATIONS, FOREGROUND_SERVICE_DATA_SYNC, WAKE_LOCK,
battery-exemption) + Gradle module. Client: useBackgroundDelivery (registers a
poll token via NIP-98, seeds the plugin) + a Background delivery (Android)
control in NotificationSettingsCard. The app registers by NAME, not by importing
the package, so the web bundle is unaffected. UNVERIFIED - needs cap sync + a
device.
2026-10-01 19:51:56 +07:00
SkateSpots
68c12a2297 Revert "feat(push): Android FCM (Phase 2) - native device support"
This reverts commit 5f0a9537b0.
2026-10-01 19:31:24 +07:00
SkateSpots
5f0a9537b0 feat(push): Android FCM (Phase 2) - native device support
Server: /native/subscribe + /native/unsubscribe (NIP-98 proof), FCM device store,
and FCM HTTP v1 sending (service-account OAuth2, cached ~1h); /health reports
native + device count. 503 without PUSH_FIREBASE_SERVICE_ACCOUNT_JSON.
Client: @capacitor/push-notifications (lazily imported, native-only) in
usePushNotifications - request permission, register, store the FCM token, and
subscribe via /native/subscribe; tap deep-links into the app.
Needs a Firebase project: google-services.json + the Gradle plugin (android/),
and the service-account JSON in the host .env.
2026-10-01 19:28:54 +07:00
SkateSpots
807037ee9b feat(push): self-hosted closed-app push service (Phase 1 backend)
Our own keyless Bun service (not Linky's): watches relays for kind-1059 wraps
carrying the plaintext marker ["skatespots","push"] on the recipient copy,
extracts only {recipient, wrapId}, and sends a Web Push. NEVER decrypts - the
client fetches + decrypts the named wrap itself.

Endpoints: GET /health, GET /vapid-public-key, POST /auth/challenge ->
/subscribe|/unsubscribe with a one-time NIP-98 (kind 27235) challenge proof.
State is a JSON file; VAPID keys from env. Wired like the other standalone
servers (typecheck:push + check:push in npm test, deploy:push, Caddyfile +
systemd unit). Verified locally end-to-end: auth -> subscribe -> marked wrap ->
watcher -> push attempt, and proof replay rejected.

Client half (service worker, subscribe hook + Settings toggle, marker on DM
sends) is the next step.
2026-10-01 15:34:43 +07:00
SkateSpots
c84f0bdeb9 release: v1.5.10 (versionCode 10510) — directions rework, mint info, offers/barter, Trades tab
Rebuilds the APK with everything shipped since 1.5.9 (all previously web-only):
destination search + bigger follow map, MintRadar ratings/reliability in a mint
detail sheet, counter-offers + barter with notifications and a Trades bell tab,
the crews type control, one-close spot sheet, and the floating map toolbar.
2026-09-29 18:53:14 +07:00
SkateSpots
1c7bd2aa6e release: v1.5.9 (versionCode 10509) — voice navigation + floating map controls
Rebuilt the APK so the phone gets:
- voice turn prompts (device TTS) + arrival, wake lock, bigger follow map
- floating map controls (map fills the screen)
Web was already deployed; this only bumps the Android version.
2026-09-29 17:20:15 +07:00
SkateSpots
c14b19aee1 release: v1.5.8 (versionCode 10508) — coordinator settings, discovery, crew bridge
Rebuilt the release APK so the phone gets what shipped this session:
- Settings -> Coordinator (pick/add/health, run-your-own hand-off)
- crew form accepts a phone-run coordinator (nprofile/cordn link) + 'Use my coordinator'
- profile discovery: publish your coordinator, one-tap add on profiles
- Edit Profile preview + 'finish your profile' checklist

Web was already deployed; this only bumps the Android version.
2026-09-29 16:27:30 +07:00
SkateSpots
d966bca148 feat(notify): scheduled event reminders (Phase 1b) + v1.5.7
An OS alarm an hour before each upcoming event the user RSVP'd going or
interested to. Because the OS holds the alarm it fires with the app fully
closed — the only closed-app notification achievable without a server.

- src/lib/reminders.ts: schedule/cancel via @capacitor/local-notifications,
  tracking handed-out ids in localStorage so withdrawn RSVPs and passed events
  are cancelled without disturbing one-off notifications. Web is a no-op.
- src/hooks/useLocalReminders.ts: reuses the existing upcoming-events and
  my-RSVPs queries; no new relay destination, no signing.
- Bridge mounts the hook only on native and only when the new 'reminders'
  pref is on; unmount cancels everything (opt-out/logout).
- Skipped the Pro-expiry reminder on purpose: it would drag the heavy
  useSasquatchPro query into a nudge.

Bumps to v1.5.7 (versionCode 10507); APK rebuilt.
2026-09-29 14:12:55 +07:00
SkateSpots
a4b79adadd release: v1.5.6 (versionCode 10506) — notifications, faster map pins, badges
Rebuilt the release APK so the phone gets everything currently on main:
opt-in on-device notifications (incl. the @capacitor/local-notifications
native plugin), the batched/smoother map markers, profile badges, the
'closest spot to me' Sasquatch intent, and the 'Keep the map free' support
element. Bumps only package.json (version sync script derives versionCode).
2026-09-29 13:08:16 +07:00
SkateSpots
63dc4bee7d feat(notify): opt-in on-device OS notifications (Phase 1)
Mirrors the activity the app already computes (bell, crews, DMs, newsletter)
to the OS notification shade, with no new relay traffic and no new network
destination.

- src/lib/osNotify.ts: one delivery API. Web uses the Notification API; native
  uses @capacitor/local-notifications (lazily imported, so the web bundle never
  pays for it). Tap-through navigates in-app.
- src/components/OsNotificationBridge.tsx: mounted once in Layout, inert until
  opted in. Per-source silent priming + a seen-id set means history is never
  replayed as a flood, and it stays quiet while the app is visible (the bell
  already covers that).
- DMs notify from the gift-wrap ENVELOPE only (src/hooks/useDmEnvelopes.ts,
  no decryption) — so Amber is never prompted just to be told you have a
  message. Preview is honestly generic.
- src/lib/notificationPrefs.ts + useNotificationPrefs: device-local, opt-in,
  default off, per-category toggles. Settings -> Notifications UI.

Deliberately local-only: a fully closed app needs a server push, which is not
built (Phase 2 = on-device background runner; Phase 3 = content-free FCM).
2026-09-29 12:59:13 +07:00
SkateSpots
9846b3756a release: v1.5.5 (versionCode 10505)
Bump 1.5.4 -> 1.5.5 and give today's ships their own release block: offline map
tiles, photo mirror fallback, the DM 'No messages yet' fix, and free
name@skate-spots.org handles. 1.5.4's notes are restored below.

APK rebuilt: versionName 1.5.5 / versionCode 10505, and its bundle carries the
ai.skate-spots.org base.
2026-09-28 14:35:42 +07:00
SkateSpots
40799e1453 fix: homepage is skate-spots.org (not .com) + skip no-op deploys
The package.json homepage pointed at skate-spots.com — a different domain on a
different host, not this app.

Also adds a deploy guard: auto-deploy.sh now hashes exactly what would be
uploaded (dist/ + netlify/ + netlify.toml) and skips the Netlify deploy when it
is byte-identical to what is already live, so metadata-only commits (version
bumps, homepage) stop costing 15 credits.
2026-09-28 14:00:06 +07:00
SkateSpots
ec06a63b01 feat(ai-proxy): run the AI proxy on the CVM host, ready to switch over
Same proxy as netlify/functions/ai.mjs, rebuilt as a standalone Bun service on
the CVM host so AI calls stop spending Netlify compute/bandwidth credits and
the sats-paid Routstr key lives on our box.

- ai-proxy/server.ts: Bun.serve on 127.0.0.1:8787 — NIP-98 + Pro gate, model
  allowlist, per-IP throttle, /api/ai + /api/ai/status. Own tsconfig
  (typecheck:ai in npm test); eslint-ignored like cvm-server.
- ai-proxy/{package.json,.env.example,skatespots-ai.service,Caddyfile,DEPLOY.md}.
- scripts/deploy-ai-proxy.sh (npm run deploy:ai): scp + bun install + unit +
  restart, mirroring deploy-cvm.sh.
- Client: one place decides the AI base, src/lib/sasquatchAi.ts (also the NIP-98
  u tag). Defaults unchanged (/api/ai on Netlify); set VITE_SASQUATCH_AI_BASE to
  move it. Fully reversible.

Deployed and verified on the host: /api/ai/status returns the live Routstr
balance. Public TLS (DNS + Caddy) is the remaining step before switching the app
over, so no client behaviour changes yet.
2026-09-28 13:32:05 +07:00
SkateSpots
3c7c8bd87e feat(nip05): free name@skate-spots.org handles, claimed at signup
SkateSpots now runs its own NIP-05 registry, so a new skater gets a human
handle from minute one instead of an npub.

- netlify/functions/nip05.mjs: /.well-known/nostr.json plus
  /api/nip05/{check,claim,release}, backed by Netlify Blobs (first-party,
  no new vendor). Claims are NIP-98 signed and written onlyIfNew, so only
  the owner can claim a name for themselves. Platform names are seeded in
  code and cannot be taken or released.
- src/lib/skateNip05.ts + src/hooks/useSkateNip05.ts +
  src/components/SkateNip05Input.tsx: shared validation, debounced
  availability, and the claim control.
- SignupDialog: a 'SkateSpots name' field, prefilled from the display
  name. Claimed best-effort before the profile publish; a failure never
  blocks signup, and the profile only advertises nip05 once confirmed.
- EditProfileForm: claim a free handle from the NIP-05 field.

Verified on a draft deploy: claim -> resolves -> a second key gets 409 ->
release -> gone. tsc/eslint/101 tests green.
2026-09-28 12:13:34 +07:00
SkateSpots
9aa5a9ca4e release: v1.5.4
1.5.3 shipped at 19:22, before the DM fix, the directions UI rework and the
newsletter reader fix. Bump to 1.5.4 so those can actually reach people.

- package.json 1.5.4 (-> versionName 1.5.4 / versionCode 10504).
- release-notes.txt: new v1.5.4 section (DM persistence + parallel send/read,
  bigger-map/app-like directions, underscore italics in the issue reader);
  trimmed v1.5.3 back to what was actually published.
2026-09-27 20:43:16 +07:00
SkateSpots
dff3ccc6f8 release: v1.5.3
1.5.2 is already published to Zapstore (verified: org.skatespots.app@1.5.2 on
relay.zapstore.dev), so the post-publish work needs a new version.

- package.json 1.5.3 (-> versionName 1.5.3 / versionCode 10503).
- release-notes.txt: new v1.5.3 section (real per-mode routing + steps + follow
  mode + choose-your-start + offline saved routes + Amber scoping); trimmed the
  v1.5.2 section back to what was actually published.
2026-09-27 19:16:53 +07:00
SkateSpots
e2d367efab release: v1.5.2
Bump package.json (single source of truth → versionName 1.5.2 / versionCode
10502 via scripts/sync-android-version.mjs) and add the v1.5.2 release notes:
marketplace deck ratings + seller dashboard, working in-app directions, nav
fixes (desktop More / mobile Marketplace), the native mints fix, and the
newsletter CPU + relay fixes.
2026-09-27 17:46:00 +07:00
SkateSpots
4ed4e6f6fb release: v1.5.1
Patch bump over the unreleased 1.5.0, folding in today's mobile fixes: Mints in
the phone nav, instant Directions, and no stray signer prompt for the AI balance.
2026-09-27 16:04:53 +07:00
SkateSpots
7969e8e9de release: v1.5.0
Sasquatch Pro (AI), in-app directions (transit/bike/moto/car), Barbers &
Hairstylists in The Lab, and a smoother app shell (no remounts, no stray
signer pop-ups).
2026-09-27 15:42:52 +07:00