Commit graph

1214 commits

Author SHA1 Message Date
SkateSpots
d33f65e68b release: 1.7.9 2026-10-28 09:46:23 +07:00
SkateSpots
f029b5a516 feat(newsletter): weekly generated drafts, covers, and admin preview
- Add a browser-safe editorial generator with rotating satire and shipped highlights.
- Generate a fresh 1200x630 cover from the Drop #006 foundation and upload it to Blossom.
- Publish weekly drafts as NIP-78; add the admin Load draft/Preview composer flow and banner.
- Add the Monday user timer (draft by default) and a manual newsletter:weekly script.
- Remove static/live issue duplicates; translate the new admin strings to all 24 locales.
2026-10-28 09:42:44 +07:00
SkateSpots
dfff2a8c40 docs: record 1.7.8 device/member/dependency work 2026-10-28 09:22:05 +07:00
SkateSpots
b32bd69e4c release: 1.7.8 2026-10-28 09:16:40 +07:00
SkateSpots
630780753f feat(cordn): device QR, member removal, message reply; patch deps 2026-10-28 09:14:03 +07:00
SkateSpots
ec5e63663b docs: record 1.7.7 Cordn unread/pending-join work 2026-10-28 08:45:30 +07:00
SkateSpots
eb63248890 release: 1.7.7 2026-10-28 08:41:46 +07:00
SkateSpots
7da67cc2c0 feat(cordn): unread and join-request badges; persist pending joins 2026-10-28 08:39:01 +07:00
SkateSpots
2cec2b4782 docs: record 1.7.6 auth/security audit tail 2026-10-28 00:12:20 +07:00
SkateSpots
30118de0ce release: 1.7.6 2026-10-28 00:08:13 +07:00
SkateSpots
13ebea685e fix(auth): keep signup alive across page cards; sanitize trip links 2026-10-28 00:05:28 +07:00
SkateSpots
e267b79281 feat(web): add short /community and /c links 2026-10-27 21:00:39 +07:00
SkateSpots
84efaba001 docs: record 1.7.5 auth/menu transition fix 2026-10-27 20:54:40 +07:00
SkateSpots
ed88efcf04 release: 1.7.5 2026-10-27 20:50:53 +07:00
SkateSpots
639afd8550 fix(auth): open sign-in above menus and close the burger first 2026-10-27 20:48:04 +07:00
SkateSpots
7abeb2d030 docs: record 1.7.4 community room and bot 2026-10-27 17:43:33 +07:00
SkateSpots
269c484cd8 release: 1.7.4 2026-10-27 17:39:21 +07:00
SkateSpots
2ec861befd feat(community): add the app-wide Cordn room and always-on bot 2026-10-27 17:37:09 +07:00
SkateSpots
27f3434475 feat(cordn): expose and copy the Cordn group share link 2026-10-27 17:02:43 +07:00
SkateSpots
74249e304e fix(menus): move language into its own mobile view; fit crew tabs 2026-10-27 17:00:19 +07:00
SkateSpots
5ac9e67860 fix(cordn): keep the invite poll alive across re-renders 2026-10-27 16:43:49 +07:00
SkateSpots
7a7b1c4950 docs: record Basque tokenizer fix and Cordn UX polish 2026-10-27 16:42:47 +07:00
SkateSpots
4009dd3a72 release: 1.7.3 2026-10-27 16:40:54 +07:00
SkateSpots
7881bbc50f fix(cordn): share public invite URL from the native app 2026-10-27 16:38:33 +07:00
SkateSpots
ac5ac85004 release: 1.7.2 2026-10-27 16:36:29 +07:00
SkateSpots
8a5ac47a19 fix(translation): repair Basque tokenizer IDs and evict stale cache 2026-10-27 16:32:29 +07:00
SkateSpots
690c9c93bd feat(cordn): polish private chat onboarding, polling and invites 2026-10-27 16:22:25 +07:00
SkateSpots
1fc91d1192 fix(sasquatch): reply in all 24 locales; record translation/Basque state
- Sasquatch UI/guide/FAQ were already 100% in all 24 locales; the AI reply
  language directive only covered es/th/ja. SASQUATCH_LANGUAGES now maps all 24
  app languages (trick names/core vocabulary stay English).
- Document the Sasquatch privacy difference: its AI calls the CVM/AI proxy
  (OpenRouter), unlike the on-device translation.
- Record the Basque status: IR 9->8 and target-side tokenizer fixed; model now
  emits Basque but loops on EOS/generation; remaining gap before 1.7.2.
2026-10-27 16:06:50 +07:00
SkateSpots
e85b9aacb6 feat(chat): all-language on-device translation (M2M100 + Basque Opus)
- M2M100 418M (MIT, 617 MB q8) covers 23 app languages; Basque uses converted
  Opus eu-en/en-eu q8 packs; all self-hosted under relay.skate-spots.org/models.
- Worker uses M2M100 directly and pivots Basque through English; UI targets all
  languages; old pilot restriction/note removed; memory-only + guard unchanged.
- Verified en<->es, ca<->gl, hi<->en from the host. Basque packs are converted
  and hosted; the final MarianTokenizer/ONNX runtime check is still pending.
- 138 tests, 24 locales, build and smoke green. SpotChat deliberately skipped.
2026-10-27 13:06:04 +07:00
SkateSpots
67bc89861d fix(chat): clear translation memory + worker on logout
Translations are memory-only; on logout/account switch we now clear the cache,
reject pending requests and terminate the worker (the model itself is public
and stays in the browser cache).
2026-10-27 10:52:01 +07:00
SkateSpots
d2a24679f0 feat(chat): on-device translation pilot (English ↔ Spanish)
- @xenova/transformers 2.17.2 in a Web Worker; Opus-MT en↔es ONNX q8 packs
  self-hosted on the relay VPS (/models + CORS); ONNX Runtime 1.14 WASM
  self-hosted in public/ort/ (37MB) loaded from ../ort/.
- Hard network guard: only model GET/HEAD (no query) and /ort/ assets allowed.
  Message text travels only via postMessage; 9 tests prove fetch is never called
  with the text and every other request is blocked.
- TranslateMessage in DMs + crew chat; Settings auto-translate off by default;
  memory-only translations; per-model download progress; 12 UI strings in all
  24 locales.
- Both model directions verified from the hosted files; tsc, 138 tests, build
  and smoke green.
2026-10-27 10:49:54 +07:00
SkateSpots
8c7de4d86d feat(chat): on-device language detector (translation Phase 1)
- tinyld (MIT, lazy, local) + script rules + a weighted
  Catalan/Galician/Basque/Spanish/Portuguese rule for the close/short cases
  tinyld confuses. No network, no logs, no storage; conversation/contact prior
  supported.
- Lingua with 24 languages produced a 99 MB WASM, so it was rejected as a
  detector; tinyld + the gl rule covers all 24 at a fraction of the size.
- 28/28 language samples pass, including a test that fetch is never called.
- Phase 2: on-device Opus-MT (English pivot) in a worker, memory-only
  translations, model packs on Blossom, sentinel/network-guard test.
2026-10-27 10:30:50 +07:00
SkateSpots
bf28519e9e feat(ops): push-marked admin alerts, scan-change DMs, deploy/health alerts
- NIP-17 wraps now carry the app's ['skatespots','push'] marker on every admin
  copy (including the sender), so the push service wakes the phone with the app
  closed. Push test wraps 39fbbd4e…/c88c9f55… verified on the community relay.
- The weekly scan-only job DMs only when the OSV summary changes; unchanged
  scans are logged, not messaged.
- auto-deploy alerts on Netlify failure and on a post-deploy production URL
  health-check failure; deploy-failed/health-failed appear in ops-health and
  the daily report.
2026-10-27 09:52:37 +07:00
SkateSpots
b87e81545b fix(ops-report): say 'Monday morning' (the scan timer has jitter) 2026-10-27 09:39:44 +07:00
SkateSpots
8473aaa994 chore(ops): plain-English daily report + NIP-17 alerts to both admins
- scripts/ops-report.sh builds a simple daily report (app, website, deps,
  security, weekly scan); --send DMs it to the two admins from src/lib/admins.ts
  via NIP-17 (scripts/send-ops-report.ts), sender = app identity.
- Delivery discovers kind-10050 inboxes + NIP-65 write relays and always
  includes the community relay; OPS_DRY_RUN=1 previews without publishing.
- scripts/send-ops-alert.sh sends short alerts; wired into auto-deploy
  (preflight/smoke), update-deps (full+fallback failure) and ops-health --notify.
- skatespots-ops-report.timer daily 07:00 + installer.
- Signer moved into the 0600 zsp.env; old history copies removed.
2026-10-27 09:36:44 +07:00
SkateSpots
39c388a6d7 chore(ops): pre-push/pre-deploy test gate + patch-only deps fallback
- scripts/preflight.sh: app+server tsc, eslint, i18n, vitest; installed as
  .githooks/pre-push (scripts/install-hooks.sh) and run by auto-deploy before
  Netlify. Failures record preflight-failed and ops-health flags them.
- update-deps.sh: if the blanket npm update fails, restore the lock and retry
  patch-level packages one at a time, keeping those that pass a fast gate; the
  final npm test + smoke still gates the result, otherwise revert + 3-day retry.
- release.sh/deps set SKIP_PREFLIGHT=1 (they run the full npm test themselves).
2026-10-27 09:23:07 +07:00
SkateSpots
16ad6ad882 chore(ops): ops-health deps status, release --deploy flag, .nvmrc 2026-10-27 09:17:04 +07:00
SkateSpots
ab3ceb0363 docs(release): record 1.7.1; release.sh reads protected zsp.env by default 2026-10-27 09:15:01 +07:00
SkateSpots
118b91188e release: 1.7.1 2026-10-27 09:13:09 +07:00
SkateSpots
5fa0ae2903 fix(release): tolerant Zapstore version match; --force bump with dirty notes 2026-10-27 09:10:48 +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
d53b8cd0cc fix(ui): harden menus for all locales
- LanguageSelector was still rendering the new SVG flag paths as text; use
  <Flag> there too and give every flag a fixed 24px slot (SVG/emoji align).
- Language dropdown w-48 -> w-72 with truncate + hover titles, so
  'Português (Brasil)' / 'Português (Portugal)' no longer clip.
- Settings language grid 1 column on phones / 2 on sm+.
- Header More menu w-48 -> w-64; header nav keeps its scroll, bottom nav keeps
  truncation.
- :lang(hi/th/ja/ko/zh) disables uppercase/tracking-wide so Devanagari, Thai
  and CJK menu labels are not letter-spaced.
- tsc, 101 tests, build and full-route smoke green.
2026-10-26 21:44:16 +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
7e48884eb9 feat(map,i18n): single-copy world clamp + regional flags + pt-PT
- Map: min zoom = smallest integer zoom whose 256*2^z world covers the
  viewport (no grey bands, no duplicated continents). Horizontal wrap is
  restored (worldCopyJump, no longitude maxBounds) so Hawaii/Pacific are
  reachable by dragging; vertical panning stays clamped.
- Flags: real SVGs for Catalonia, Basque Country, Galicia and England
  (no Unicode region flags exist; English is not the UK). Portuguese now has
  Brasil (pt) and Portugal (pt-PT).
- pt-PT shares the pt dictionary with a European drift for the visible chrome
  (Guardar, Palavra-passe, Autocarro, Utilizador, ...).
- check-i18n covers pt-PT: 24 codes at 100%; tsc/tests/build green.
2026-10-26 16:09:21 +07:00
SkateSpots
d4c6261b81 feat(i18n): add Catalan, Basque and Galician (23 locales, all 100%)
- Full dictionaries (8,703 keys each) in src/i18n/{ca,eu,gl}, 7 namespace
  batches, composed with deepMerge; placeholders verified, 2-4% identical
  strings are only brand/protocol names.
- Register in Language/LANGUAGE_LOADERS, detectLanguage (before es),
  LanguageToggle (CA/EU/GL text badges - no Unicode region flags exist) and
  dateFnsI18n (ca-ES/eu-ES/gl-ES).
- check-i18n.mjs now covers ca/eu/gl: all 23 locales at 100%, tsc/tests/build
  green.
2026-10-26 15:56:56 +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
93abe599f9 a11y: label the language trigger + settings icon; record security/menu audit
- aria-label on the language dropdown trigger (flag-only) and the header
  settings icon (title-only) so screen readers announce them.
- AGENTS: final security scan (audit 35->13, zod 4/nostrify 0.50, APK manifest
  and CSP verified) + menu/a11y conclusions.
2026-10-26 12:31:47 +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
8badbeacf1 fix(auth): show the desktop welcome sign-in once per session
The dismissal was stored in localStorage, so one early ✕ suppressed the prompt
forever. Switch to sessionStorage (key skatespots:desktop-welcome-snoozed): it
reappears in a new tab/session but respects 'keep browsing' for the current one.
2026-10-26 12:19:52 +07:00