Commit Graph
7548 Commits
Author SHA1 Message Date
Lotus CIandClaude Opus 5.5 a951e5b1f2 feat(lotus): detailed call summary for the host's Details card (cinny #253)
CI / Build embedded bundle (pull_request) Successful in 3m1s
CI / Publish to Gitea npm registry (pull_request) Skipped
io.lotus.call_summary gains an optional `details`: the other Matrix users
seen and the peak in the call; how long your connection, each other
person's, and everyone at once (likely the server) was poor/lost; RTT
median/p95, outbound and inbound packet loss and jitter (sampled every 5 s
from LiveKit sender/receiver stats); and your talk, mute and screenshare
time. People already present when you connect are recorded on Connected
(LiveKit sends no ParticipantConnected for them), and joins are idempotent
per device. Older hosts ignore the field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-20 19:45:02 -04:00
Lotus CIandClaude Opus 5.5 438d09cde9 chore(lotus): 0.25.0-lotus.28
CI / Build embedded bundle (push) Successful in 2m15s
CI / Publish to Gitea npm registry (push) Successful in 1m8s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.28
2026-10-19 23:36:30 -04:00
jared 0534fa393c Merge pull request 'feat(lotus): soundboard works in voice channels with a call policy (#47)' (#59) from feat/soundboard-mic-mix into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-19 23:36:00 -04:00
Lotus CIandClaude Opus 5.5 e12b3e5979 style(lotus): format LOTUS.md table
CI / Build embedded bundle (pull_request) Successful in 1m41s
CI / Publish to Gitea npm registry (pull_request) Skipped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 23:30:56 -04:00
Lotus CIandClaude Opus 5.5 657271163f feat(lotus): soundboard works in voice channels with a call policy (#47)
CI / Build embedded bundle (pull_request) Failing after 1m1s
CI / Publish to Gitea npm registry (pull_request) Skipped
Clips publish as a separate Unknown-source track, which tokens limited to
listed sources (any room with io.lotus.room_quality) refuse, so #52 could
only answer not_permitted. Where the token allows the microphone, the
clip is now mixed into the published mic for its duration: the track on
the mic's RTCRtpSender (post-denoise) and the clip feed a
MediaStreamAudioDestinationNode, the sender switches to the mix with
replaceTrack, and the original goes back when the clip ends. Muting
mid-clip stops it; a track LiveKit swapped in meanwhile is left alone.
not_permitted remains for tokens without the microphone.

Fixes #47

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 23:23:06 -04:00
Lotus CIandClaude Opus 5.5 60398b0a7d chore(lotus): 0.25.0-lotus.27
CI / Build embedded bundle (push) Successful in 2m0s
CI / Publish to Gitea npm registry (push) Successful in 52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.27
2026-10-19 15:06:39 -04:00
jared 2c8d20ba82 Merge pull request 'feat(lotus): keep your own tile on mobile with the camera off (cinny #265)' (#58) from feat/mobile-self-tile into lotus
CI / Build embedded bundle (push) Successful in 1m52s
CI / Publish to Gitea npm registry (push) Skipped
2026-10-19 14:58:35 -04:00
Lotus CIandClaude Opus 5.5 fbf8e44276 feat(lotus): keep your own tile on mobile with the camera off (cinny #265)
CI / Build embedded bundle (pull_request) Successful in 1m57s
CI / Publish to Gitea npm registry (pull_request) Skipped
Upstream drops the local PiP in the one-on-one mobile layout whenever the
local camera is off. In Lotus voice rooms that is nearly always, so on a
phone you never saw yourself or your own speaking ring. Show it as the
desktop layout does; the tile falls back to your avatar. Tests updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 14:40:25 -04:00
jared 5693e81bb9 Merge pull request 'feat(lotus): report remote screenshare audio to the host (cinny #277)' (#57) from feat/screenshare-audio-state into lotus
CI / Build embedded bundle (push) Successful in 1m57s
CI / Publish to Gitea npm registry (push) Skipped
2026-10-19 14:28:57 -04:00
Lotus CIandClaude Opus 5.5 5f4844cad5 feat(lotus): report remote screenshare audio to the host (cinny #277)
CI / Build embedded bundle (pull_request) Successful in 1m55s
CI / Publish to Gitea npm registry (pull_request) Skipped
New fromWidget action io.lotus.screenshare_audio_state { present }: each
LivekitRoomAudioRenderer reports whether a remote participant's
ScreenShareAudio track is being received; the combined answer is sent to
the host on change, and cleared when a renderer unmounts. cinny uses it to
show "Mute Screenshare Audio" only when there is something to mute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 14:21:52 -04:00
Lotus CIandClaude Opus 5.5 848dcaafa9 chore(lotus): 0.25.0-lotus.26
CI / Build embedded bundle (push) Successful in 1m55s
CI / Publish to Gitea npm registry (push) Successful in 1m0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.26
2026-10-19 12:41:55 -04:00
jared 1ad32e56c7 Merge pull request 'feat(lotus): accept decorations from chat.lotusguild.org (matrix #22)' (#56) from feat/decorations-origin into lotus
CI / Build embedded bundle (push) Canceled after 1m46s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-19 12:40:07 -04:00
Lotus CIandClaude Opus 5.5 090edc5c2c feat(lotus): accept decorations from chat.lotusguild.org (matrix #22)
CI / Build embedded bundle (pull_request) Successful in 1m42s
CI / Publish to Gitea npm registry (pull_request) Skipped
Decorations moved off Nextcloud to https://chat.lotusguild.org/decorations.
Add that origin to ALLOWED_DECORATION_ORIGINS (first, so tests use it);
keep drive.lotusguild.org until no host build points there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 12:37:53 -04:00
jared dbf77cdc60 Merge pull request 'docs(lotus): LOTUS.md lists io.lotus.call_error and io.lotus.reconnect (#50)' (#55) from docs/lotus-call-error into lotus
CI / Build embedded bundle (push) Successful in 2m8s
CI / Publish to Gitea npm registry (push) Skipped
2026-10-19 01:36:12 -04:00
Lotus CIandClaude Opus 5.5 2ef80cef2c docs(lotus): LOTUS.md lists io.lotus.call_error and io.lotus.reconnect (#50)
CI / Build embedded bundle (pull_request) Successful in 2m1s
CI / Publish to Gitea npm registry (pull_request) Skipped
Regenerate the action table from lotusActions.ts: add the two actions
from #50, and note which cinny PR handles each one still in flight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-19 00:01:18 -04:00
Lotus CIandClaude Opus 5.5 88c648ba8b chore(lotus): 0.25.0-lotus.25
CI / Build embedded bundle (push) Successful in 2m35s
CI / Publish to Gitea npm registry (push) Successful in 55s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.25
2026-10-18 15:27:50 -04:00
jared 0aa543cc7d Merge pull request 'docs(lotus): LOTUS.md: the io.lotus.* widget protocol, URL flags and release flow (#43)' (#53) from docs/lotus-protocol into lotus
CI / Build embedded bundle (push) Successful in 3m6s
CI / Publish to Gitea npm registry (push) Skipped
2026-10-18 07:49:15 -04:00
jared cc57292bf4 Merge pull request 'fix(lotus): soundboard says "not permitted" in audio-only rooms instead of failing silently (#47)' (#52) from lotus-soundboard-not-permitted into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-18 07:42:09 -04:00
jared 22f9083768 Merge pull request 'fix(lotus): restart the shared mic sampler only when the LiveKit rooms change (#45)' (#51) from lotus-mic-sampler-churn into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-18 07:38:41 -04:00
jared d7d75cbba5 Merge pull request 'feat(lotus): tell the host when the call drops, and let it press Reconnect (cinny #318)' (#50) from lotus-call-error into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-18 07:32:17 -04:00
jared 4be3e92eb6 Merge pull request 'fix(lotus): a homeserver stall shorter than the delayed-leave window no longer ends the call (#46)' (#54) from lotus-stall-retry into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-18 04:52:15 -04:00
Lotus CIandClaude Opus 5.5 a1dd0e254c fix(lotus): a homeserver stall shorter than the delayed-leave window no longer ends the call (#46)
CI / Build embedded bundle (pull_request) Successful in 3m33s
CI / Publish to Gitea npm registry (pull_request) Skipped
maximumNetworkErrorRetryCount was sized to min(sync grace period,
leave delay), i.e. 10 s, so the membership manager gave up 20-35 s into
a homeserver stall and showed "Connection lost", even when the server
would keep the membership for 60 s (prod config). Size it to the leave
delay instead: the embedded call has no /sync loop for the grace period
to describe, and the server's delayed leave is what actually ends the
membership.

Fixes #46

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 02:47:36 -04:00
Lotus CIandClaude Opus 5.5 167ffc2440 docs(lotus): LOTUS.md: the io.lotus.* widget protocol, URL flags and release flow (#43)
CI / Build embedded bundle (pull_request) Successful in 4m5s
CI / Publish to Gitea npm registry (pull_request) Skipped
Everything the host relies on was documented only in src/lotus comments.
Add a table of the 22 io.lotus.* actions (generated from lotusActions.ts,
with direction, payload and whether cinny handles each), the URL flags,
fork-only behaviour and the release/publish steps.

Fixes #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 01:24:22 -04:00
Lotus CIandClaude Opus 5.5 888ed1a66c fix(lotus): soundboard says "not permitted" in audio-only rooms instead of failing silently (#47)
CI / Build embedded bundle (pull_request) Successful in 3m20s
CI / Publish to Gitea npm registry (pull_request) Skipped
Clips publish as an Unknown-source track. In audio-only rooms the guard
signs a microphone-only token, LiveKit refuses the publish, and since
the fork had already replied {} the host never heard. Check the grants
up front and reply { played: false, reason: "not_permitted" }.

Refs #47

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 01:22:49 -04:00
Lotus CIandClaude Opus 5.5 73bf2133dc fix(lotus): restart the shared mic sampler only when the LiveKit rooms change (#45)
CI / Build embedded bundle (pull_request) Successful in 3m16s
CI / Publish to Gitea npm registry (pull_request) Skipped
observeLocalMicSample$ switchMapped on every allConnections$ emission,
which re-emits far more often than the set of rooms changes. Each one
stopped the clone, closed the AudioContext and emitted null, and the
null reset the muted-speech gate, so the "You're muted" nudge could
never stay true long enough to fire. Map to the room list and only
restart when it actually changes.

Fixes #45

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 01:17:06 -04:00
Lotus CIandClaude Opus 5.5 07e1506dd8 feat(lotus): tell the host when the call drops, and let it press Reconnect (cinny #318)
CI / Build embedded bundle (pull_request) Successful in 3m2s
CI / Publish to Gitea npm registry (pull_request) Skipped
After a homeserver stall the frame shows "Connection lost · Reconnect"
while the host kept showing the call as joined, with controls that did
nothing. While the error page is up, report io.lotus.call_error
{ code, recoverable } (and { code: null } when it clears), and accept
io.lotus.reconnect to run the page's own Reconnect / Try again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 00:54:48 -04:00
Lotus CIandClaude Opus 5.5 58625c86b0 chore(lotus): 0.25.0-lotus.24
CI / Build embedded bundle (push) Successful in 3m14s
CI / Publish to Gitea npm registry (push) Successful in 1m19s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.24
2026-10-17 20:47:48 -04:00
jared e3ac9a96d6 Merge pull request 'feat(lotus): report the frame's audio outputs to the host (cinny #310)' (#49) from fix/audio-output-list into lotus
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-10-17 20:45:10 -04:00
Lotus CIandClaude Opus 5.5 34d541b707 feat(lotus): report the frame's audio outputs to the host (cinny #310)
CI / Build embedded bundle (pull_request) Successful in 3m28s
CI / Publish to Gitea npm registry (pull_request) Skipped
Browsers hash deviceIds per frame/origin, so ids from the host's own
enumerateDevices() are unknown in here and select() fell back to the
default. io.lotus.audio_output_state now also carries
available: [{id,label}] (frame-valid ids), so the host's call-bar menu
can offer real choices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-17 19:48:33 -04:00
Lotus CIandClaude Opus 5.5 eb59fd5b3f chore(lotus): 0.25.0-lotus.23
CI / Build embedded bundle (push) Successful in 2m51s
CI / Publish to Gitea npm registry (push) Successful in 1m9s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
v0.25.0-lotus.23
2026-10-17 17:53:24 -04:00
jared fea233f5e1 Merge pull request 'feat(lotus): sendNotificationType=none turns the call-start notification off (cinny #295)' (#48) from lotus-notify-none into lotus
CI / Build embedded bundle (push) Successful in 3m18s
CI / Publish to Gitea npm registry (push) Skipped
2026-10-16 23:13:46 -04:00
Lotus CIandClaude Opus 5.5 93905c5bc1 feat(lotus): sendNotificationType=none turns the call-start notification off (cinny #295)
CI / Build embedded bundle (pull_request) Successful in 3m55s
CI / Publish to Gitea npm registry (pull_request) Skipped
The widget intent presets default sendNotificationType to "notification",
and the URL param could only switch it to ring/notification, so the host
had no way to say "don't notify". In persistent voice channels and space
rooms that notification carries an @room mention: every member got a
highlighted ping (and phone push) whenever a moderator joined first, and
other clients showed it as a missed call.

`sendNotificationType=none` now clears it after the presets are applied.
Unit test added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-16 22:06:12 -04:00
Lotus CIandClaude Opus 5.5 3b0050e8bb chore(lotus): 0.25.0-lotus.22
CI / Build embedded bundle (push) Successful in 4m12s
CI / Publish to Gitea npm registry (push) Successful in 1m11s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.22
2026-09-27 13:05:01 -04:00
jared 41b45bef25 Merge pull request #42: in-frame "Share your screen?" prompt (cinny #43)
CI / Build embedded bundle (push) Canceled after 0s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-09-27 13:05:01 -04:00
Lotus CIandClaude Opus 5.5 bb675fa50e feat(lotus): in-frame "Share your screen?" prompt replaces the corner button (cinny #43)
CI / Build embedded bundle (pull_request) Successful in 3m25s
CI / Publish to Gitea npm registry (pull_request) Skipped
Where the host can't delegate the user's click (Firefox, Safari, WebKitGTK),
lotus.20 showed EC's own screenshare button floating in the frame's corner,
apart from the host's call bar. Now the host keeps its bar button and sends
the new toWidget io.lotus.prompt_screenshare; the fork shows a small
"Share your screen?" card inside the frame, just above the bar, and its
Share button starts the share with the frame's own click. Same two clicks as
the host's confirm on Chromium.

- The card focuses Share; Cancel and Escape close it; it closes if a share
  starts some other way or the room's call policy stops allowing sharing,
  and never opens where the policy forbids it (set_frame_screenshare).
- Picture-in-picture (~158 px tall): compact card without the description.
- controls_state: frameScreenshare is now always false (the corner button is
  gone), screensharePrompt says the host should use the prompt, and
  screensharePromptOpen lets the host stop covering the frame meanwhile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-27 12:48:12 -04:00
Lotus CIandClaude Opus 5.5 9e4ddb3eb6 chore(lotus): 0.25.0-lotus.21
CI / Build embedded bundle (push) Successful in 4m16s
CI / Publish to Gitea npm registry (push) Successful in 1m10s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.21
2026-09-27 01:30:40 -04:00
jared 9d57d104b4 Merge pull request #41: work when served from its own origin (cinny #43)
CI / Build embedded bundle (push) Canceled after 6s
CI / Publish to Gitea npm registry (push) Canceled after 0s
2026-09-27 01:30:31 -04:00
Lotus CIandClaude Opus 5.5 a93bd9d7d8 feat(lotus): work when served from its own origin (cinny #43)
CI / Build embedded bundle (pull_request) Successful in 3m43s
CI / Publish to Gitea npm registry (pull_request) Skipped
Two things tied EC to the host's origin:

- Widget message check: matrix-widget-api's strictOriginCheck compares
  ev.origin with THIS frame's origin, so on call.chat.lotusguild.org every
  message from chat.lotusguild.org would be dropped and calls would not
  start. restrictToHost() instead requires ev.source === window.parent and
  ev.origin === parentUrl's origin. Same-origin deployments keep working
  (the host origin is our own origin there), and it is stricter than
  before: the sender must also be our parent window.
- Soundboard: the host's blob: clip URL is origin-bound. io.lotus.inject_audio
  now accepts the clip's bytes (`audio`, ArrayBuffer, <= 8 MiB) and prefers
  them over `url`; hosts that only send `url` are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-26 23:24:32 -04:00
Lotus CIandClaude Opus 5.5 43a5e93c37 chore(lotus): 0.25.0-lotus.20
CI / Build embedded bundle (push) Successful in 4m17s
CI / Publish to Gitea npm registry (push) Successful in 52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.20
2026-09-26 21:48:22 -04:00
Lotus CIandClaude Opus 5.5 0f93368a7e feat(lotus): in-frame screenshare button where the host can't delegate (cinny #43)
Firefox, Safari and WebKitGTK have no Capability Delegation, so the host
can't start a share from its call bar: getDisplayMedia needs the click in
this frame. Until now the host clicked EC's hidden footer button through
the DOM, which only works while the frame is same-origin.

With lotusHostControls + lotusFrameScreenshare the fork now shows EC's own
screenshare button (floating bottom-right, footer still hidden), so the
click is native. controls_state reports frameScreenshare so the host hides
its own button. New toWidget io.lotus.set_frame_screenshare { visible }
lets the host hide it while the room's call policy forbids screensharing
(never while a share is live, so it can still be stopped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-26 21:48:22 -04:00
Lotus CIandClaude Opus 5.5 dfb72bd9a5 chore(lotus): 0.25.0-lotus.19
CI / Build embedded bundle (push) Successful in 3m27s
CI / Publish to Gitea npm registry (push) Successful in 1m16s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.19
2026-09-26 13:59:34 -04:00
Lotus CIandClaude Opus 5.5 e0eecc5271 feat(lotus): report host call hotkeys from inside the frame (cinny #43)
The host used to add PTT/deafen key listeners to this frame's window,
which needs same-origin access. Now it sends `io.lotus.set_hotkeys
{ codes }` and the fork reports those keys as `io.lotus.hotkey`
(keydown/keyup with modifiers + whether the target is a text field or a
button), plus window focus changes so a held PTT is released. The
default action is cancelled here with the host's rules (not while typing,
not on a focused button). `controls_state` carries `hotkeys: true`.

Fixes a live bug: EC's own shortcuts (M = toggle mic, Space = PTT) also
fired for the host's keys, so with focus in the call and the default
deafen key M, the first press turned the MIC ON instead of deafening
(even in push-to-talk mode). EC's shortcuts now ignore keys the host owns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-26 13:59:34 -04:00
Lotus CIandClaude Opus 5.5 c4f6193888 chore(lotus): 0.25.0-lotus.18
CI / Build embedded bundle (push) Successful in 3m9s
CI / Publish to Gitea npm registry (push) Successful in 1m17s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.18
2026-09-26 13:39:18 -04:00
Lotus CIandClaude Opus 5.5 7855a0c22f feat(lotus): hide the footer + root color-scheme natively (cinny #43)
- `lotusHostControls=1`: body.lotus-host-controls hides EC's footer
  (position absolute + visibility hidden, still in the DOM so a host on an
  engine without Capability Delegation can click its screenshare button).
- With lotusTheme/lotusTransparent, `:root` color-scheme follows the
  theme, so the transparent frame gets no opaque backdrop.
Together these replace the CSS the host injected into this frame.

Also fixes unreadable tile name tags in the light theme: the Lotus
near-black canvas override now applies to dark themes only (it sat behind
light-theme dark text).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-26 13:39:18 -04:00
Lotus CIandClaude Opus 5.5 aeb72c22b9 chore(lotus): 0.25.0-lotus.17
CI / Build embedded bundle (push) Successful in 2m45s
CI / Publish to Gitea npm registry (push) Successful in 1m17s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.17
2026-09-26 12:49:58 -04:00
Lotus CIandClaude Opus 5.5 6fa34911ef feat(lotus): io.lotus.set_screenshare for the host call bar (cinny #43)
toWidget `io.lotus.set_screenshare { on?: boolean }` (omit to toggle)
starts/stops sharing via the view model instead of the host clicking EC's
hidden button. The host sends it with Capability Delegation
(`delegate: "display-capture"`) where supported, so getDisplayMedia keeps
the user's click on engines that require it. `controls_state` now carries
`screenshareAction: true` so the host only uses it on a fork that has it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-26 12:49:58 -04:00
Lotus CIandClaude Opus 5.5 35bc7a1e98 chore(lotus): 0.25.0-lotus.16
CI / Build embedded bundle (push) Successful in 2m4s
CI / Publish to Gitea npm registry (push) Successful in 56s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.16
2026-09-25 12:08:57 -04:00
Lotus CIandClaude Opus 5.5 cee6bab9a6 feat(lotus): report the local mic level to the host (cinny #146)
The host had only a boolean `speaking` for yourself, throttled to 500 ms, so
nothing on the call bar showed that the mic was actually picking you up.

- lotusMicLevel.ts: one shared local mic sampler (a clone of the published
  track, ~10 Hz RMS, while a mic is published, muted or not), shared per
  call view model so there is one AudioContext.
- MicLevelQuantizer: 0–3 bars (≈ −46/−36/−26 dBFS), rising at once and
  falling one bar per sample so it doesn't flicker between words.
- fromWidget io.lotus.mic_level { bars } only when the value changes; 0 while
  muted or with no mic. Opt-in with the host state stream (lotusCallState=1).
- "Talking while muted" (#37) now reads the same sampler instead of running
  its own; same gate and behaviour.

Verified in a local call with a fake-tone mic: the host receives 0–3 as the
tone rises/falls (about 4 messages/s while it changes), 0 on mute and levels
again on unmute; muted + tone still raises speakingWhileMuted and the host's
"You're muted" notice. Lotus/room suites pass on Node 22 (148 tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-25 12:08:57 -04:00
Lotus CIandClaude Opus 5.5 44023a4c84 style(lotus): oxfmt the volume memory change (#36)
CI / Build embedded bundle (push) Successful in 1m51s
CI / Publish to Gitea npm registry (push) Successful in 1m5s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
v0.25.0-lotus.15
2026-09-25 10:03:49 -04:00
Lotus CIandClaude Opus 5.5 3086edc64a chore(lotus): 0.25.0-lotus.15
CI / Build embedded bundle (push) Failing after 48s
CI / Publish to Gitea npm registry (push) Skipped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-25 09:57:55 -04:00