Fetch and display the next 14 days of events in the briefing right column,
grouped by day with color dots, time, and location. Fills the empty space
below the weather card.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a refresh button (↻) to the weather section header in BriefingView so
users can manually re-fetch weather data (needed after deploying the hourly
precip changes to populate the cache). Update the existing POST
/api/briefing/weather/refresh endpoint to return full card data instead of
just location keys.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RSS is now off by default. When disabled:
- Scheduler skips RSS feed sync during compilation slot
- Briefing pipeline skips RSS item gathering
- RSS LLM tools (get_rss_items, add_rss_feed) are hidden
- API routes return empty results for feeds/news
- Frontend hides News nav link, RSS Feeds and News Preferences in settings
- Briefing view hides news sidebar section
Toggle in Settings > Briefing > RSS / News.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove border-top from .input-wrapper in ChatPanel directly instead
of overriding per-view. Applies to chat, workspace, and briefing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch sidebar from fixed px to proportional 35% so it resizes with
the viewport. Remove border between chat and input bar and between
weather and news. Use container query units for weather/forecast icons
so they scale with column width.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add location tabs when multiple weather sources configured. Weather
section stays pinned at top of sidebar while news scrolls independently.
Bump sidebar width from 420px to 620px max for better readability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collapse briefing from 3-column to 2-column grid (chat + sidebar).
Weather moves to top of news column, forecast uses an HTML table so
rows align cleanly. Drop verbose condition text from forecast days
(emoji already conveys it). Switch CI node_modules cache to npm
download cache to avoid tar size error from onnxruntime-web.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The standalone current-conditions div showed just a bare temperature with no
forecast context, making the weather panel look incomplete. Now the live
temperature from /weather/current is patched directly into the WeatherCard's
current_temp so it stays fresh without a second display block.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
POST /api/briefing/articles/<id>/discuss injects stored article content
as a persisted read_article tool exchange before triggering generation.
The LLM sees the article as already read; follow-ups retain context via
the fixed history builder. Frontend Discuss button now calls the new
endpoint instead of inlining article text in the user message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs:
1. Manual 'Refresh' button didn't refresh weather/RSS before compiling.
The daily scheduler calls refresh_all_feeds + refresh_location_cache
before run_compilation; the manual trigger route called run_compilation
directly, reading a stale cache. Manual trigger now mirrors the
scheduler: refresh feeds and all configured weather locations first.
2. Navigating to WorkspaceView during a long briefing compilation caused
the workspace chat to show the briefing content. triggerNow awaits
~30-60s; on completion it called loadAll() → chatStore.fetchConversation
which overwrote the workspace's currentConversation in the shared store.
Fixed with a _mounted flag — all post-async state writes in BriefingView
are now guarded so they no-op if the component has been unmounted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract listen mode into a shared useListenMode() composable backed by
localStorage ('fa_listen_mode'). ChatView and BriefingView both use it,
so toggling auto-read on in one view keeps it on after navigation or
page refresh — no need to re-enable it each visit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three bugs in discussArticle():
- Scroll selector was '.briefing-chat' (doesn't exist) → '.briefing-center';
the panel never scrolled into view so the response was invisible until refresh
- Only 300-char snippet was sent to the LLM; now passes the full stored
content (up to 2000 chars) from the backend
- User message wasn't shown until streaming ended; now added optimistically
to messages[] immediately on click so it appears straight away
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- KnowledgeView mini-chat: replace harsh border-top with upward box-shadow
and rounded top corners (16px); remove padding-bottom from content area
so widget truly overlays cards without pushing layout; add collapse
toggle (chevron) that hides messages without closing the conversation
- WeatherCard: show precip_mm as fallback when precipitation_probability_max
is null but actual rainfall is expected (Open-Meteo omits probability for
some forecast days even when rain is shown)
- Pass precip_mm through weather service → frontend type definitions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Explicitly instruct the LLM to respond conversationally and not use any
research/search tools when summarizing a shared article excerpt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ChatView: listen mode toggle (auto-reads new responses via TTS), volume popup
with range slider persisted per-device in localStorage via GainNode
- useVoiceAudio: shared module-level _volume ref with localStorage persistence,
GainNode for volume control, exported setVoiceVolume()
- tts.py: pre-warm all Kokoro voices at pipeline load to eliminate HuggingFace
HEAD requests at synthesis time (reduces TTS latency)
- BriefingView: discuss article button now auto-sends instead of just filling input;
prompt capped to 15 sentences; send() accepts optional overrideText
- llm.py: instruct LLM not to proactively search notes or comment on note absence
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fetch precipitation_probability_max from Open-Meteo (replaces precip_sum
in the card display — probability is more useful at a glance than mm)
- Show WMO condition description text on each forecast day
- Convert wind speed to mph when temp unit is F; pass wind_unit in response
- Display 💧 X% chance of rain; 💨 X mph/km/h wind per day
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Clicking 💬 on a news card in the briefing panel pre-fills the briefing
chat input with the article title, snippet, and source so the user can
ask the briefing LLM to summarize or discuss it directly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move voice status into settings store (voiceSttReady, voiceTtsReady),
checked once at login and refreshed after admin model reload
- ChatView, BriefingView, DashboardChatInput now use computed refs from
the store — mic buttons appear reactively without needing a page reload
- BriefingView: separate STT-only guard for mic PTT vs TTS-only guard for
listen mode / speak buttons
- Add ▶ Preview button to Voice & Speed section in Settings for single-
voice testing without enabling blend mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- WeatherCard: show precipitation (mm) and max wind speed per forecast day
- DashboardChatInput: add PTT mic button (transcribe-to-input, voice-gated)
- Remove global VoiceOverlay floating button and Space PTT shortcut from
App.vue — inline mic buttons in chat/briefing/dashboard are the right UX;
global overlay had focus/latency/context issues
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pressing push-to-talk now immediately stops any ongoing TTS audio before
opening the microphone, preventing the assistant from hearing itself.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ChatView: add PTT mic button in input bar (hold to speak → transcribe → send)
- BriefingView: restyle input bar to match ChatView (floating pill, circle send)
- BriefingView: move listen/mic controls into input bar, remove from header
- BriefingView: consistent icon-button style for speaker/mic matching ChatView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Left column: weather loaded independently via /api/briefing/weather
- Center column: chat messages with input bar (unchanged behavior)
- Right column: news panel loaded from /api/briefing/news (last 2 days)
- Auto-scroll to bottom on mount and after streaming
- Background refresh also refreshes news panel
- Responsive: stacks to single column on narrow screens
- Fix TaskCard.vue to include 'cancelled' in status records
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously metadata only stored rss_item_ids (integers); the full item data
was discarded after LLM synthesis. Now rss_items (id, title, url, source,
snippet, published_at) is also stored so clients can render per-story cards
without additional API calls.
Web BriefingView: replaces bare reaction-row buttons with news cards showing
source, headline (linked), 2-line snippet, and 👍/👎 per card.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract milestoneColor to utils/palette.ts; remove duplicate in HomeView + ProjectListView
- Create useBackgroundRefresh composable; wire into HomeView + BriefingView (removes manual setInterval/clearInterval boilerplate)
- Extract _loadTabContent() in SettingsView so watch and onMounted share one tab→loader mapping
- Move raw fetch() api-key calls to typed helpers in api/client.ts (listApiKeys, createApiKey, revokeApiKey)
- Drop unused onUnmounted import from BriefingView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HomeView: setInterval every 90s refreshes events, orphan tasks/notes,
and hero next-up task. Never touches loading ref, so the page content
stays stable — only the data silently swaps when the fetch completes.
Skips when document.hidden or initial load is still in progress.
BriefingView: setInterval every 60s refetches today's messages, but
only when viewing today's conversation and not currently streaming.
Compares message count and last message content before updating to
avoid unnecessary re-renders.
Both timers are cleared on unmount.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>