Skip to content

Windows: music pills (Apple Music/Spotify/any player), volume & battery live activities, Claude plan chat, calendar - #418

Open
MithunSidhaarth wants to merge 7 commits into
Louis-CFM:mainfrom
MithunSidhaarth:windows-plus-pr
Open

MithunSidhaarth wants to merge 7 commits into
Louis-CFM:mainfrom
MithunSidhaarth:windows-plus-pr

Conversation

@MithunSidhaarth

Copy link
Copy Markdown

Hi Louis 👋 This takes the Windows build a few steps further. Everything is in windows/, nothing touches the Mac app, and it follows the repo's rules: no new dependencies (only more windows crate features), pill IDs untouched, keys only in the credential store, nothing polls while the island is hidden, and every new string is translated in all 10 languages.

What's new

Music pills on Windows

  • Apple Music (integration_music), Spotify (integration_spotify, now support: "yes") and a new Now Playing pill (integration_media) for any other player, including browser tabs and VLC.
  • They read from the Windows system media controls (GlobalSystemMediaTransportControls) in media_win.rs, and only react to events (no timers). They emit the same spotify event as the Linux MPRIS client, so the existing card and pill are reused and only take a source and an accent colour.
  • Cover art, seek, shuffle and repeat. The volume slider drives the system volume (Core Audio, audio.rs).
  • On the card: a blurred album-art backdrop, a bigger cover, and the artist shown in full (the album moves to the tooltip).

Live activities in the island (sysevents.rs + island/live.ts)

  • The volume keys show their level in the compact island instead of Windows' popup. A low-level hook is installed only while the setting is on. Laptop Fn keys arrive injected by the maker's hotkey service, so those count too.
  • Brightness, charger plugged in or out, and low battery at 20 % and 10 % come from power-setting notifications.
  • From hidden, the island peeks out silently for as long as the activity lasts. When the island is open, the activity shows as a small toast over the header. Only opacity and transforms animate.
  • The Monday recap is now checked on wake from sleep (PBT_APMRESUMEAUTOMATIC), which closes the "no sleep/wake notification" gap in windows/README.md.

Chat with a Claude plan, no API key (claude_cli.rs)

  • A "Claude (your plan)" provider runs claude -p with stream-json, using a Pro or Max login.
  • Tools, user settings (so Coucou's own hooks don't report the chat as a session), MCP and session persistence are all off, so it only answers and never acts on the PC.

Calendar pill (integration_calendar)

  • Works with any calendar's private iCal link (Google, Outlook, iCloud). The link is stored as a secret, only https/webcal links are accepted, and it's polled every 5 minutes only while the pill is on.

Smaller things

  • The island re-asserts topmost when another app comes forward (EVENT_SYSTEM_FOREGROUND, so no timer).
  • Island extras → Always show the island (on by default): the compact island no longer hides after a minute.
  • 5 s in the auto-close picker.
  • Long pill names (e.g. "Claude Desktop") no longer run under the mini Mochi.
  • Clipboard history, kept in memory only and never on disk. Formats that password managers mark private are skipped. The backend is in place; the Shelf pill UI to show it is not part of this PR.
  • Island extras in Settings (Windows only), stored under a new plus key in settings.json.

Tests

  • npm test: 361 pass. cargo test -p coucou: 223 pass (new tests cover the media session mapping, volume steps, power events, the iCal parser, the CLI stream parser and the settings round trip).
  • dev/live-preview.html previews the live activities in a real island.
  • Tried on Windows 11 with Apple Music, Opera GX (YouTube) and laptop Fn keys.

Notes

  • Known limits are marked with ponytail: comments: the volume slider is system-wide rather than per app, and recurring iCal events show only their first date.
  • Happy to split this into smaller PRs (media / live activities / chat / calendar) or rework anything to fit your plans.

🤖 Generated with Claude Code

MithunSidhaarth and others added 6 commits October 10, 2026 01:04
…edia controls

Reads every player through GlobalSystemMediaTransportControls (event-driven,
no timers) and feeds the existing music card and pill. Apple Music and Spotify
get their own pills; Now Playing follows any other app (browser tabs, VLC).
The card's volume slider drives the system volume through Core Audio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A low-level hook takes the volume keys from Windows' popup (only while the
setting is on; injected keys pass through) and the island shows the level.
Brightness, AC/battery and battery level come from power-setting
notifications; waking from sleep now triggers the Monday recap check. The
clipboard listener keeps recent texts in memory only, skipping anything
password managers mark private. All of it is event-driven, nothing polls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Claude (your plan)" in the chat's model picker answers through the Claude
Code CLI logged in with a Pro or Max account: no tools, no user settings (so
Coucou's hooks don't see it), no MCP, no saved session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aptop volume keys

- The island re-asserts topmost whenever another app comes forward (event-driven).
- Volume keys injected by laptop hotkey services are taken too.
- Music card: blurred album-art backdrop, bigger cover, artist in full.
- Auto-close offers 5 s; long pill names no longer run under the mini Mochi.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Calendar: Google, Outlook or iCloud through the calendar's private iCal
  link, kept in the credential store; https/webcal only; next events on the
  card. Polled every 5 minutes only while the pill is on.
- Island extras → Always show the island (on by default): the compact
  island no longer hides after a minute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MithunSidhaarth added a commit to MithunSidhaarth/mithunsidhaarth.github.io that referenced this pull request Oct 9, 2026
…hi preview on hover

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chat passed only a PDF's name, so the CLI answered that no file matched.
It now runs in the inbox with the Read tool allowed for that folder only
(--allowedTools "Read(./**)", dontAsk) and is pointed at ./<file>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MithunSidhaarth

Copy link
Copy Markdown
Author

Hi @Louis-CFM 👋 I've opened a follow-up stacked on this one: #432 adds the iPhone side for Windows users (links through iCloud Drive, phone alerts via ntfy, Phone Link calls & messages in the island), Focus / To-do / Inbox pills, 8 pills on two pages and a mini player in the compact island. Everything stays in windows/, tests pass, all strings translated. Happy to split or rework anything to fit your plans. Thanks again for Coucou!

@shakibbinkabir

Copy link
Copy Markdown
Contributor

@MithunSidhaarth, a heads-up on the music part of this (commit 22a8854, which #432 carries too): the Spotify pill on Windows, read from the system media session, is already in two open PRs, #374 (8 Oct) and #383 (9 Oct). All three turn integration_spotify to support: "yes" and feed #372's spotify event from GlobalSystemMediaTransportControls, so they conflict in spotify.rs, pills.ts and the pill tests.

Yours is not the same PR: it also covers Apple Music and any other player through a new "Now Playing" pill, which neither of the other two does. For the Spotify part that overlaps, this is where it differs from #374:

#374 This one
Players Spotify only, by its two app ids Spotify, Apple Music, and anything else under integration_media
When it reads On the session's events only The same
Volume Spotify's own level in the Windows mixer The system's master volume
Shuffle and repeat Left off the card on Windows Wired, and the card takes the new value as soon as the call answers true
The card #372's, unchanged A blurred cover behind it, a bigger cover, the album moved to the tooltip
Tried with Spotify (Microsoft Store, 1.303.264) Apple Music and Opera GX, from your description

One thing to check with Spotify itself, since your description does not list it among what you tried: here TryChangeShuffleActiveAsync and TryChangeAutoRepeatModeAsync return true and Spotify changes nothing (three seconds later its session still reports them off). With control showing the new value on true, the card would show a shuffle that is not on. It may well be right for Apple Music.

@zrdqns

zrdqns commented Oct 11, 2026

Copy link
Copy Markdown

I tried the Apple Music part of this PR on my machine: Windows 11, Apple Music from the Microsoft Store, built at 7eec171 with npx tauri build --debug --no-bundle, with the Apple Music pill on.

What works: the pill and the card show the track, play/pause and next reach Apple Music, and the progress and duration follow the track.

What I ran into:

  1. The cover is one track behind. After Next, the card shows the new title with the previous track's cover, and it stays that way. Below, "SAD!" has been playing for 17 s with the cover of the track before it. It happened on both track changes I tried. Apple Music seems to publish the new title first and the new thumbnail a moment later, and refresh_from reads the artwork once per track key, right when the title changes.

    Cover one track behind

  2. No cover for the track already loaded when Coucou starts. It stays on the placeholder, also while that track plays, until the track changes. My guess is that the spotify-artwork event goes out before the page is listening and is never sent again for the same key.

    No cover at start

  3. The seek bar, shuffle and repeat do nothing with Apple Music. Its session reports IsPlaybackPositionEnabled, IsShuffleEnabled and IsRepeatEnabled as false. Clicking the bar at about 65 % left the position alone (18 s → 22 s, just playback), and shuffle and repeat showed no change. They could be hidden or disabled from the session's Controls().

  4. The album arrives inside the artist field. Apple Music fills Artist with Harry Nach — Funketon Hits: Baila y Rebola and leaves AlbumTitle empty, so the line gets cut mid-album and there is no album for the tooltip.

Also, the branch no longer merges with main: it is 121 commits behind, with conflicts in windows/src-tauri/src/settings.rs and windows/src/i18n/extra.json.

I only tried Apple Music. I did not touch the volume slider, Spotify or the Now Playing pill.

For context, I hit the same four things while writing a small Apple Music-only pill for my own build, before I found this PR. What fixed them there: re-reading the thumbnail on every MediaPropertiesChanged and keying it on the image bytes instead of the track (1), sending the cover again on spotify_refresh (2), and splitting the artist at — when the album is empty (4). I have not opened that as a PR so there is not one more duplicate, but I am happy to share the branch if it is useful.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants