Turn status card into a live stream with @micro AI mentions#562
Merged
Conversation
Users were already using the status card as chat — everyone posting updates that read like replies to each other. Instead of fighting it, make the stream the thing. The card is now a live scrollable feed of every status from everyone, and the AI is a first-class participant you can summon with @micro. Data model: - user.UpdateProfile now always pushes the previous status onto the history (not just on change), and merges the stored history with whatever the caller passed so a freshly-constructed *Profile{} can't accidentally drop history. History cap raised 20 → 100 per user. - user.StatusStream(max) is new: flattens every user's current + history into one chronological feed, newest first, within the existing 7-day cutoff. Home card: - Replaced the "latest status per user" render with a shared RenderStatusStream helper used by both the home page and a new /user/status/stream fragment endpoint. - The card body is wrapped in #home-status-wrap and followed by an inline <script> that polls /user/status/stream every 10 seconds, pauses when the tab is hidden, refreshes on focus, and preserves whatever the user is typing in the compose input. - The compose form submits via fetch with the CSRF header, then refreshes the stream in place — no full page reload. Falls back to a native submit on network error. - Removed the hover "clear status" button. Every post is appended to history, so clearing just trims the current entry and is functionally meaningless for a stream. - Removed the "hide card when there's nothing" branch in favour of an empty-state line so the card is discoverable on new instances. @micro AI participant: - Posting a status containing @micro (word-bounded, so @microsoft and email@micro.xyz don't match) fires a background agent call whose answer is posted as a status from the existing app. SystemUserID ("micro") account. user.AIReplyHook is wired from main.go to agent.Query so the asker's wallet pays for the reply. - user.PostSystemStatus posts as the system user without going through CanPost / CheckPostRate, and trims to MaxStatusLength. - containsMention enforces word boundaries so mentions inside URLs or longer words don't trigger. UX / mobile: - MaxStatusLength raised 100 → 512 (tweet-ish). - #home-statuses is capped at min(55vh, 420px) with overflow-y: auto and -webkit-overflow-scrolling so the card can never take the whole screen on mobile. - .home-status-text now wraps properly (pre-wrap + overflow-wrap: anywhere) and the row uses align-items: flex-start so the avatar stays put when text wraps. - Added a .home-status-system variant to tint @micro replies green. Tests: - user/status_test.go covers containsMention word boundaries, StatusStream chronological order across users and history, StatusStream max cap, and UpdateProfile always appending history (including repeat text). The production /mu --serve deployment is unaffected — this touches handlers and renderers only, no startup or config changes.
Limit how many statuses are shown on the home card to stop the feed from becoming a scroll-wall. Two caps apply: - StatusStreamMax (default 30, STATUS_STREAM_LIMIT to override) — total entries in the visible stream. Past ~30 the scroll becomes noise rather than signal and the card stops feeling live. - StatusStreamPerUser (default 10, STATUS_STREAM_LIMIT_PER_USER to override) — how many entries any one user can contribute to the visible window. Without this, a single chatty user or a long @micro conversation would flood the feed and push everyone else off. Applied to each user's list (newest-first) BEFORE the chronological merge so older entries from flooders can't displace more recent entries from quieter users. Exposed via StatusStreamCapped(maxTotal, maxPerUser) so future callers (profile history pages, admin views) can pick different shapes without re-implementing. Test coverage: new TestStatusStream_PerUserCapPreventsFlood builds a profile for Alice with 20 recent entries and Bob with 1, verifies Alice contributes at most 3 when cap is 3/user and that Bob's single entry still appears.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Users were already using the status card as chat — everyone posting updates that read like replies to each other. Instead of fighting it, make the stream the thing. The card is now a live scrollable feed of every status from everyone, and the AI is a first-class participant you can summon with @micro.
Data model:
Home card:
@micro AI participant:
UX / mobile:
Tests:
The production /mu --serve deployment is unaffected — this touches handlers and renderers only, no startup or config changes.