Commit Graph

62 Commits

Author SHA1 Message Date
Cosmo
89d8140014 feat: smart-home voice tools (get_state + control_air_purifier)
Some checks failed
Deploy / deploy (push) Failing after 1m18s
2026-05-01 06:57:43 +00:00
Cosmo
7b5f76576f refactor: tool plugin registry - each tool in separate file
All checks were successful
Deploy / deploy (push) Successful in 1m25s
2026-04-30 20:58:11 +00:00
Cosmo
4ba1aa43d5 feat: switch voice chat from Anthropic to Groq (llama-3.3-70b) + proxy support
All checks were successful
Deploy / deploy (push) Successful in 1m26s
2026-04-30 20:48:02 +00:00
Cosmo
04b7d1f104 feat: switch from Anthropic to Groq API (llama-3.3-70b-versatile)
All checks were successful
Deploy / deploy (push) Successful in 2m47s
- route.ts: replace @anthropic-ai/sdk with groq-sdk, rewrite chat loop
- voice-tool-schemas.ts: convert from Anthropic format to OpenAI/Groq function tools
- voice-history.ts: extend HistoryMessage type to include tool role, simplify cache stubs

No prompt caching (Groq does not support it), tool calling preserved.
2026-04-30 20:43:30 +00:00
Cosmo
96fa78bd5c fix(calendar): GOOGLE_SA_JSON_B64 поддержка (env-file friendly)
All checks were successful
Deploy / deploy (push) Successful in 2m7s
docker --env-file не поддерживает многострочные значения и не парсит
кавычки. Сырой JSON service-account ломается на newline'ах в private_key
поле → docker пытается парсить '-----END PRIVATE KEY-----' как имя
переменной и валится с 'contains whitespaces'.

Решение: base64 GOOGLE_SA_JSON_B64 (одна строка ASCII, никаких кавычек).
Старая GOOGLE_SA_JSON оставлена как fallback. Третий fallback на файл —
для локальной разработки.
2026-04-27 12:59:17 +00:00
Cosmo
05b300d472 chore(voice): security, cleanup, resilience
All checks were successful
Deploy / deploy (push) Successful in 1m47s
Безопасность:
- Rate-limit на /api/voice/chat (20/мин per cookie/IP, env VOICE_RATE_LIMIT).
  Защищает от случайных циклов и утечки PIN.
- Усечение user prompt'а до 4000 символов в /api/voice/chat.
- Tool-loop защита от циклов: если LLM дважды просит тот же tool с теми же
  args — прерываем (раньше мог уйти в бесконечный цикл при tool error'ах).

Чистка кода:
- lib/debug.ts — vlog/vwarn/verror гейтят браузерные логи за
  NEXT_PUBLIC_VOICE_DEBUG=1 (или localStorage 'voice-debug=1').
  Серверные console.log оставлены — полезны в Docker logs.
- lib/audio-wav.ts — вынесена дублированная floatToWav из VoiceController.
- Удалены orphan компоненты FocusCard.tsx и CountdownCard.tsx
  (не подключены, отвергнуты по UX-фидбеку).

Resilience:
- WakeWordDetector: drop-on-busy в onChunk — на медленных устройствах
  (Android, бюджетный CPU) backlog inference больше не копится.
- voice-history fallback на /tmp/voice-history если /data не примонтирован
  (локальная разработка / нестандартная конфигурация).
2026-04-27 12:44:18 +00:00
Cosmo
93bf34f216 feat(voice): push-to-talk button — браузерный mic+VAD pipeline
All checks were successful
Deploy / deploy (push) Successful in 6m53s
Шаг 2 миграции: убираем зависимость от Python-агента для базового
голосового сценария. Тап на круглую кнопку-микрофон в правом нижнем
углу → MicVAD (Silero v5) ловит речь → автостоп по тишине → /api/voice/stt
→ /api/voice/chat → ответ через SSE и TTS как раньше.

- components/VoiceController.tsx — push-to-talk UI + MicVAD orchestration
- VoiceOverlay теперь слушает window CustomEvent('voice-local'), чтобы
  орб моргал ещё до round-trip на сервер (wake/listening мгновенно).
- public/vad/ — silero v5/legacy onnx + ort wasm + audio worklet,
  раздаются через baseAssetPath: '/vad/' (не зависит от внешнего CDN,
  важно если планшет без интернета или с RU-блоком).

Что осталось от home-voice-assistant: только wake-word. После Шага 3
(onnxruntime-web + перенос openwakeword .onnx) Python-агент уйдёт целиком.
2026-04-27 08:48:22 +00:00
Cosmo
eeac2eefb3 feat(voice): server-side LLM/STT — porting Python satellite into tablet
All checks were successful
Deploy / deploy (push) Successful in 5m44s
Шаг 1 миграции голосового стека из home-voice-assistant в сам tablet:

- /api/voice/chat — Claude Haiku 4.5 с tool-loop (max 4 раунда), prompt
  caching на system + старой истории, история в /data/voice-history/.
  Эмитит command/response/error в voice-bus → орб моргает как раньше.
- /api/voice/stt — Groq whisper-large-v3-turbo, multipart или raw audio.
- lib/voice-text.ts — порт clean_for_speech (без pymorphy3, время в
  именительном падеже) и strip_fillers + RESET_PATTERNS.
- lib/voice-executors.ts — tool executors через loopback fetch на
  существующие /api/voice/tools/* и /api/voice/timer.
- Поддержка ANTHROPIC_PROXY/GROQ_PROXY (fallback на HTTPS_PROXY).

После деплоя нужны GROQ_API_KEY и ANTHROPIC_API_KEY в tablet.env.
Шаги 2 (push-to-talk в браузере) и 3 (wake-word) — отдельно.
2026-04-27 08:24:19 +00:00
Cosmo
a97dd11f25 revert(home): restore weather hero with anim + details, drop Countdown from home
All checks were successful
Deploy / deploy (push) Successful in 3m24s
Focus/Countdown не лежат по high-density. На Home вернул старый
weather-hero: WeatherAnimation (фон + иконка), feelsLike/humidity/wind,
76px display-цифра (чуть крупнее прежних 64). FocusCard и CountdownCard
файлы оставляем для будущего, но на главной не подключаем. Убрал
сопутствующие state/fetch (tramNext, countdowns, nextEvent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 19:35:01 +00:00
Cosmo
e328055851 feat(design): FocusCard hero, CountdownCard, data-* palette, swipe, touch-targets
All checks were successful
Deploy / deploy (push) Successful in 3m8s
Big design pass across Home + tokens + components.

— globals.css: new data-* palette (cool/warm/hot/good/info/rose/violet/mood)
  with theme-aware variants, .grain overlay utility, .num-display
  typography helper, .hit-zone 44px wrapper, .eyebrow label, .focus-card
  base, focus-visible outline-offset 3px, space/touch scale vars.
— FocusCard.tsx: context engine — пять состояний (morning-outfit,
  tram-imminent, event-upcoming, countdown, bill-due, night, quiet).
  Auto-rotates by hour + live data. 96px display numbers, accent-mixed
  surfaces, grain overlay.
— CountdownCard.tsx + /api/countdowns: rotating 8s list, persistent
  /data/tablet-countdowns.json, full CRUD. Default seeded with Токио.
— HomeTab: replaced plain Weather hero with FocusCard, added Row 4
  with CountdownCard. Pulls trams + countdowns for the Focus context.
— Swipe between tabs: pointer-level detection on <main>, data-swipe-ignore
  bails out inside modals + note swipe-to-delete + voice overlay.
— Touch-target sweep: TopBar HA dot → 44px hit-zone, sensor chip 44px
  min-height, forecast day buttons 92px min, DeviceCard toggle 60x36,
  CalendarTab prev/next/close/list all 44x44, NotesTab buttons 44x44,
  TimerHomeWidget + 44x44, WeatherDayModal chevrons 48x48, close 48.
— Hardcoded hex → data-* tokens: TopBar sensors, TransportWidget routes
  (via color-mix), DeviceCard full rewrite (per-kind accent, glass
  removed in favor of color-mix surfaces + proper mock-state treatment),
  NotesTab palette refreshed to match dark theme.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 18:24:23 +00:00
Cosmo
56844a539d feat(voice/events): full CRUD — POST/PUT/DELETE with owner routing
All checks were successful
Deploy / deploy (push) Successful in 2m57s
Голосовой ассистент теперь может создавать, изменять и удалять события
в календарях Даниила и Светы.

- POST  /api/voice/tools/events — create (title, date, start_time, end_time,
  all_day, owner). Маппит owner (daniil/sveta) в calendar_id и проксирует
  в /api/calendar POST.
- PUT   — update (event_id, owner, fields). Передаёт только изменённые
  поля + нужный calendarId.
- DELETE ?event_id=X&owner=Y — удаление.
- GET   — теперь возвращает id события и owner (daniil/sveta), чтобы
  скрипт мог их передать в update/delete.
- range=month поддержан с year/month query params.

Все три метода под bearer auth (VOICE_API_KEY), как остальные voice tools.
Loopback к /api/calendar идёт через internalHeaders() x-voice-internal.
2026-04-23 14:34:32 +00:00
Cosmo
0c677df558 feat(voice): hero TimerHomeWidget + timer cancel/adjust by label
All checks were successful
Deploy / deploy (push) Successful in 3m25s
UI:
- Replace Notes column on Home bento with TimerHomeWidget. Shows all
  active timers as stacked cards with big 30px countdowns, per-timer
  +1/-1 minute buttons and cancel. Colors: indigo default, amber in
  last 10s, red when expired. Empty state suggests voice command.
- Existing chip TimerWidget (bottom-right) kept for ambient view on
  other tabs — redundant on Home, but harmless.

API:
- /api/voice/timer accepts cookie OR bearer (browser widget cancel
  works with user's auth_token cookie; Python script uses bearer).
- New action 'adjust' — shifts endsAt by delta_seconds. Clamps so
  endsAt never goes into the past.
- Cancel now supports {label} in addition to {id} (fuzzy substring
  match, most-recently-started wins). Emits timer_cancel with id+label
  so clients can refresh.
- findByLabel / adjustTimer helpers in lib/timers.ts.
2026-04-23 13:51:25 +00:00
Cosmo
7fb05181e6 fix(voice/tools): use x-voice-internal header for loopback fetches
All checks were successful
Deploy / deploy (push) Successful in 3m10s
Tool endpoints (events, notes, transport, weather) call other /api/*
routes via loopback (http://localhost:3000). Those routes are
middleware-protected — cookie-less loopbacks were getting 401, which
surfaced to the voice agent as get_today_events → tool_http_502.

Add internal header bypass: middleware lets the request through when
x-voice-internal matches VOICE_API_KEY. Only our own tool endpoints
use this header, from inside the same container, so the blast radius
is limited to loopback traffic.

- middleware.ts: check x-voice-internal before cookie
- lib/voice-tools.ts: internalHeaders() helper
- app/api/voice/tools/{weather,transport,events,notes}: use it
2026-04-23 13:41:57 +00:00
Cosmo
e96e7a1342 feat(voice): tool endpoints, timer widget, clean Siri-style overlay
All checks were successful
Deploy / deploy (push) Successful in 3m18s
Adds the infrastructure for Claude tool use + visual timer.

Tablet API surface (all bearer-authed with VOICE_API_KEY, middleware bypassed):
- /api/voice/tools/weather    — current + short forecast via Open-Meteo
- /api/voice/tools/transport  — tram arrivals by direction / route filter
- /api/voice/tools/events     — Google Calendar today/week
- /api/voice/tools/notes      — notes + shopping lists
- /api/voice/timer            — start (with seconds+label), cancel; GET list (cookie ok)
  Active timers persisted at /data/tablet-timers.json

UI:
- VoiceOverlay stripped to minimal Siri look: no agent emoji/name, just the
  pulsing orb (3-layer radial gradient, independent breath animations),
  subtle status label on wake only, transcription/response text centered.
  Agents distinguished by orb color (Cosmo indigo/violet, Люся pink).
- TimerWidget: bottom-right chip stack with countdown, progress bar, turns
  amber in last 10s. On expiry, fires fullscreen alarm overlay with beep
  (WebAudio osc) + Остановить button.

Other:
- lib/timers.ts — persistent timer store in /data
- lib/voice-tools.ts — shared bearer-auth helper
- middleware — bypass list now covers /api/voice/tools/* and /api/voice/timer
2026-04-23 13:33:31 +00:00
Cosmo
c29da75c19 feat(voice/tts): route ElevenLabs through HTTP proxy for non-RU egress
All checks were successful
Deploy / deploy (push) Successful in 4m3s
ElevenLabs Cloudflare returns 302 to a region-restricted help page
when requested from a Russian IP. Tablet host (.60) is in RU, so the
Stage 2 call was failing with 502 upstream.

Fix: use https-proxy-agent when ELEVENLABS_PROXY (or generic HTTPS_PROXY
/ HTTP_PROXY) env var is set. Tinyproxy on .103 (non-RU egress host)
acts as the tunnel.

- package.json: add https-proxy-agent ^7.0.6
- app/api/voice/tts: switch from global fetch to node:https with
  explicit Agent (either direct or HttpsProxyAgent). Still streams
  MP3 back via Readable.toWeb so Next.js Response pipes it to the
  browser as audio arrives.

Operational: set ELEVENLABS_PROXY=http://192.168.31.103:8888 in
tablet.env after bringing tinyproxy up on .103.
2026-04-23 13:00:55 +00:00
Cosmo
a780fc7bd5 feat(voice): play TTS through tablet speakers via ElevenLabs proxy
All checks were successful
Deploy / deploy (push) Successful in 2m58s
Stage 2 of voice integration — centralizes TTS on the tablet so the
Python satellite no longer needs ElevenLabs credentials or mpv.

- app/api/voice/tts — POST {text, agent}, proxies to ElevenLabs
  streaming endpoint with flash_v2_5 default, returns audio/mpeg.
  Per-agent voice id via COSMO_TTS_VOICE / LUSYA_TTS_VOICE env.
- VoiceOverlay — on response/error events fetches TTS and plays via
  HTMLAudioElement; on wake event stops playback (barge-in). Dismiss
  timer extended by text length so long responses do not cut off.
- Autoplay caveat: browser may block first playback until user taps
  anywhere on the page (FKB: enable Force Autoplay to bypass).
2026-04-23 12:52:26 +00:00
Cosmo
51c3d6016a feat(voice): SSE bridge + Siri-blob overlay for wake-word script
All checks were successful
Deploy / deploy (push) Successful in 3m12s
Adds the tablet side of voice assistant integration. External Python
script (openWakeWord + Groq STT + OpenClaw) will POST state transitions
to /api/voice/event with a bearer token, and the tablet shows a
fullscreen overlay with Siri-style animated blob + current agent +
recognized text / response text.

- lib/voice-bus.ts — in-process EventEmitter singleton, preserved
  across hot reloads via globalThis
- app/api/voice/event — POST, bearer-auth via VOICE_API_KEY env,
  validates event kind, broadcasts on voiceBus
- app/api/voice/stream — GET, SSE endpoint, per-connection listener
  with 15s keep-alive ping and abort-signal cleanup
- components/VoiceOverlay — full-screen overlay, 3-layer pulsing
  Siri blob, per-agent palette (cosmo indigo/violet, lusya pink/rose),
  auto-dismiss timeouts (wake=20s safety, response=6s, error=4s),
  auto-reconnect on SSE drop
- middleware bypasses /api/voice/event so the script does not need
  a user auth cookie
- VoiceOverlay mounted in HomePageInner outside tab routing so it
  appears on every view
2026-04-23 12:36:26 +00:00
Cosmo
9fec9bca99 fix(calendar): all-day end.date must be next day, clear opposite field
All checks were successful
Deploy / deploy (push) Successful in 2m50s
Google Calendar API rejects all-day events where start.date == end.date
(end is exclusive). POST/PUT were sending the same date for both,
producing Invalid start time when toggling Весь день on edit.

- Added nextDayISO helper (UTC-safe +1d arithmetic)
- all-day: start = { date }, end = { date: nextDay, dateTime: null }
- timed: also explicitly nulls start.date/end.date so patching a
  timed-only event over a previously all-day one doesnt leave stale
  date fields that also trigger Invalid start time
2026-04-23 09:29:21 +00:00
Cosmo
dc5c9b3673 fix(home): remove black flash between tab switches
All checks were successful
Deploy / deploy (push) Successful in 2m40s
- AnimatePresence mode=wait keeps the DOM empty while the outgoing tab
  finishes its exit transition (200ms) before mounting the incoming
  tab. On touch devices this shows as a brief black frame — reported
  as экран остается черным.
- Switch to mode=sync: outgoing fades out while incoming fades in,
  no gap. initial=false suppresses the enter animation on first render.
- Drop the y: 12 → -8 slide (cheap jank on hydration), keep just
  opacity. Duration 200ms → 150ms for snappier feel.
2026-04-23 09:22:55 +00:00
Cosmo
8d32e7ebb0 feat: forecast swipe nav, note swipe-to-delete, night-shift tint
All checks were successful
Deploy / deploy (push) Successful in 2m45s
- WeatherDayModal now accepts the full forecast array and an onChange
  callback; supports horizontal drag (framer-motion) plus prev/next
  chevrons and a dot-indicator. Drag > 60px switches day; style uses
  semantic tokens (shadow-xl, surface-1).
- NotesTab list items wrap each note in a motion.button with drag=x,
  constrained to -80px. Below it a gradient+trash reveal layer. Drag
  past 60px opens the existing confirmDelete modal.
- HomePageInner adds a night-shift overlay (fixed, mixBlendMode multiply,
  rgba(255,120,40,0.12)) active 22:00-06:00, auto-checked each minute,
  fades in/out over 800ms. No user toggle yet — fully automatic.
2026-04-23 09:17:22 +00:00
Cosmo
0908ad93de fix(home): prevent bento grid overflow on narrow viewports
All checks were successful
Deploy / deploy (push) Successful in 2m40s
CSS grid items default min-width to min-content; the tram widget 3-col
subgrid plus its баbadges and long затем text forced its cell wider
than 1.1fr, collapsing the outer layout on tablet. Fixes:

- outer bento row → gridTemplateColumns: minmax(0, 1fr) minmax(0, 1.1fr)
- events+notes row same treatment
- TransportWidget inner subgrids: 58px → 52px badge, 1fr → minmax(0, 1fr)
- Cell: minWidth: 0, overflow: hidden, затем text trimmed with ellipsis
  and short м suffix (5м instead of 5 мин)
- big number 32→28px, badge 22→20px to fit in denser columns
2026-04-23 08:46:00 +00:00
Cosmo
e967924f1f ui(topbar): move greeting from Home body to TopBar center
All checks were successful
Deploy / deploy (push) Successful in 2m43s
The big Доброе утро line on Home ate one row for marginal value.
Moved it into TopBar as a center column via 3-col grid (1fr auto 1fr),
so it appears on all tabs and leaves the Home body denser.
2026-04-23 08:38:41 +00:00
Cosmo
09185c2a2a fix(home): drop greeting date; fix touch scroll; tokenize TopBar icons
Some checks failed
Deploy / deploy (push) Has been cancelled
- Removes the date label from the greeting row (user request — тoo dense
  on tablet and redundant with TopBar clock).
- Scrolling: drops overflowY: auto on the inner Events/Notes cards and
  removes flex: 1 / minHeight: 0 from their grid. On iPad-class touch
  nested scroll containers fought the root scroll; now only the root
  scrolls, which the browser handles natively.
- TopBar: replaces hardcoded rgba(255,255,255,X) on sensor icons, chip
  background, chip border and header bottom-border with semantic tokens
  (--text-tertiary, --surface-2, --border-subtle, --hairline) so the
  thermometer/humidity/wind icons are visible in light theme.
2026-04-23 08:36:56 +00:00
Cosmo
121bf30ab1 redesign: bento home + semantic tokens + solid cards
All checks were successful
Deploy / deploy (push) Successful in 2m43s
- introduces semantic CSS tokens (--surface-1/2/3, --border-subtle/strong,
  --hairline, --shadow-sm/md/lg/xl) with distinct dark and light values;
  fixes broken light theme caused by hardcoded rgba(255,255,255,X)
- drops glassmorphism on cards — solid var(--surface-1) with 1px border
  and layered shadows; glass kept only for aurora page background
- introduces .card/.card-raised/.card-hero utility classes
- Home page restructured into a bento grid:
  * greeting row with inline day/date
  * hero weather (64px number, large icon, ощущается/влажность/ветер)
    next to the tram widget (1fr 1.1fr)
  * forecast as a single hairline-separated band (no per-day cards)
  * events+notes in a 2-column grid; events card combines today and
    tomorrow with a divider; notes card styled via surface tokens
- TransportWidget repainted to use tokens, larger numbers (32px for the
  next arrival), imminent highlight uses color-mix against surface-2
2026-04-23 08:30:03 +00:00
Cosmo
9ad758174d style(home): drop weather-hint block; recolor trams 23 green, 27 blue, 39 red
All checks were successful
Deploy / deploy (push) Successful in 2m47s
Weather hint (оденьтесь потеплее / не забудьте зонт) was pushing the
home screen past one viewport on the tablet — removed the block and its
helper fn. New tram color palette per user preference.
2026-04-23 08:21:09 +00:00
Cosmo
43dff776f5 fix(transport): use node:https instead of undici (module not exported)
All checks were successful
Deploy / deploy (push) Successful in 2m47s
Next.js could not resolve undici as a top-level import even though it
ships internally. Drop that path and call the ORGP endpoint via the
built-in node:https with a per-request Agent(rejectUnauthorized: false).
Adds runtime = nodejs on the route so Node APIs are guaranteed.
2026-04-23 08:13:52 +00:00
Cosmo
c25e15e697 fix(transport): accept ORGP self-signed cert via undici Agent
Some checks failed
Deploy / deploy (push) Failing after 1m20s
ORGP SPb uses a TLS chain Node rejects by default (curl works with -k
but Node fetch doesnt). Use an undici Agent with rejectUnauthorized
false for this one hop. Also drop the conflicting next.revalidate: 0
option — cache: no-store already covers it.
2026-04-23 08:11:16 +00:00
Cosmo
0523482aa1 feat(home): tram arrival widget for Ул. Антонова-Овсеенко
All checks were successful
Deploy / deploy (push) Successful in 3m10s
Adds a live transit widget on the home screen showing upcoming trams
at both directions of the stop: toward Новочеркасская (stopID 16226)
and toward пр. Большевиков (stopID 16354).

- /api/transport proxies the СПб ORGP endpoint /stop/{id}/arriving
  (DataTables POST format, JSON response with route number + minutes).
  No auth required, free.
- TransportWidget renders two glassmorphism cards with route badges,
  minutes-to-arrival, wheelchair indicator; imminent (<=2 min) arrivals
  get a colored highlight. Filters to trams 23/27/39; refreshes every 30s.
- Route colors: 23 blue, 27 amber, 39 purple.
2026-04-23 08:05:15 +00:00
Cosmo
b0fb9d0c54 fix: 4 bugs — MSK today events, settings scroll, note dates, persistent notes volume
All checks were successful
Deploy / deploy (push) Successful in 4m35s
- calendar API: today/week ranges use Moscow time (UTC+3) instead of UTC — previously today events did not appear until 03:00 MSK
- settings tab: add -webkit-overflow-scrolling: touch + touchAction pan-y for tablet scroll
- NotesTab: add date picker (pinDate) in editor header + date badge in list
- home: pinnedNotes now filters by pinDate (today or future), falls back to latest
- notes/auth: storage moved from /tmp to /data (falls back to /tmp if /data missing)
- deploy workflow: mount /opt/digital-home/smart-home-tablet-data:/data so notes survive redeploys
2026-04-23 06:13:16 +00:00
Cosmo
3a93d5bbea feat: remove weather from TopBar, clickable forecast days with detail modal (feels like, humidity, wind, precip)
All checks were successful
Deploy / deploy (push) Successful in 3m8s
2026-04-22 21:00:37 +00:00
Cosmo
bce9578fa1 feat: redesigned Home (weather+forecast bar, today+tomorrow, pinned notes), fix snow animation, scrollable weather modal, weather hints
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-04-22 20:58:05 +00:00
Cosmo
4bcfff775c fix: remove slice(0,3) in weather API — return all 7 forecast days
All checks were successful
Deploy / deploy (push) Successful in 2m52s
2026-04-22 20:36:40 +00:00
Cosmo
bc01443f03 feat: Notes tab (notes + shopping lists), fix 7-day forecast layout, fix screensaver dismiss
All checks were successful
Deploy / deploy (push) Successful in 2m54s
2026-04-22 20:29:33 +00:00
Cosmo
a7611b46c4 fix: date input overflow, 7-day forecast on Home, screensaver button in settings
All checks were successful
Deploy / deploy (push) Successful in 2m45s
2026-04-22 20:19:04 +00:00
Cosmo
494126c7d4 feat: animated SVG weather icons + dynamic gradient background by weather/time
Some checks failed
Deploy / deploy (push) Failing after 2m6s
2026-04-22 20:09:13 +00:00
Cosmo
408be1d0c4 fix: restore template literals in POST handler dateTime fields
Some checks failed
Deploy / deploy (push) Failing after 2m6s
2026-04-22 20:03:31 +00:00
Cosmo
8c60590ed0 fix: restore template literals in calendar PUT handler
Some checks failed
Deploy / deploy (push) Failing after 1m1s
2026-04-22 20:00:22 +00:00
Cosmo
89382bef95 fix: PIN -> getPin() in auth check endpoint
Some checks failed
Deploy / deploy (push) Failing after 1m5s
2026-04-22 19:56:58 +00:00
Cosmo
690db4c6cf feat: event editing, light/dark theme, device animations, 7-day forecast
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-04-22 19:56:38 +00:00
Cosmo
1d330f0f41 feat: settings (PIN change, city selector, logout), greeting, screensaver, tab animations, HA status
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-04-22 19:48:53 +00:00
Cosmo
eed8db5865 fix: wind speed in m/s, redesigned weather modal with hero section and forecast cards
All checks were successful
Deploy / deploy (push) Successful in 2m55s
2026-04-22 19:35:46 +00:00
Cosmo
868d35ba3e feat: redesigned add-event modal with calendar selector (Даниил/Света)
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-04-22 19:33:38 +00:00
Cosmo
4e4d434c0b fix: client-side auth check instead of middleware rewrite
All checks were successful
Deploy / deploy (push) Successful in 2m38s
2026-04-22 19:19:33 +00:00
Cosmo
c7fc4d6e8e fix: use Web Crypto API in middleware (Edge Runtime compat)
All checks were successful
Deploy / deploy (push) Successful in 2m34s
2026-04-22 19:12:19 +00:00
Cosmo
1a529fc23e feat: add PIN lock screen auth + calendar owner filter toggles
All checks were successful
Deploy / deploy (push) Successful in 2m49s
2026-04-22 18:50:56 +00:00
Cosmo
eb644ff341 feat: premium UI redesign — glassmorphism, gradient accents, ambient background
All checks were successful
Deploy / deploy (push) Successful in 2m40s
2026-04-22 18:38:31 +00:00
Cosmo
4874466985 feat: add calendar event deletion with confirmation
All checks were successful
Deploy / deploy (push) Successful in 4m37s
2026-04-22 18:28:13 +00:00
Cosmo
57441ad898 fix: CI pipeline alpine+docker-cli, calendar redesign + POST API
Some checks failed
Deploy / deploy (push) Failing after 4s
2026-04-22 13:29:53 +00:00
Cosmo
444239a5e5 fix: switch to service account auth for Google Calendar
Some checks failed
Deploy to VM / deploy (push) Failing after 1s
2026-04-22 13:10:06 +00:00
Cosmo
38a64ff9c8 feat: google calendar integration, calendar tab, redesign home/devices tabs
Some checks failed
Deploy to VM / deploy (push) Failing after 1s
2026-04-22 12:44:15 +00:00