Skip to content

A control strip, a message log, sessions of its own, and lists that read a page - #34

Closed
MRafStudio wants to merge 1 commit into
timoncool:mainfrom
MRafStudio:feat/top-control-panel-journal
Closed

MRafStudio wants to merge 1 commit into
timoncool:mainfrom
MRafStudio:feat/top-control-panel-journal

Conversation

@MRafStudio

Copy link
Copy Markdown

This is our fork's work, squashed into one commit on top of main. It comes from daily use on
this machine, and every piece of it answers something the window did not have. Nothing here is
a rewrite: new pieces are separate components, and your files carry small, commented seams.

Why sessions - the part we most want you to weigh

A session is the answer to "where did this track come from, and what belongs with it". Without
one we kept meeting the same three problems:

  1. A track made outside the window had no home. An agent, a curl, an old tab - the track
    landed in the library and belonged to nothing. Our service route gathers such tracks once
    into a session of the studio's own, and the mark is data, not a name: session_kinds says
    kind='import', so no window ever has to guess a localised word. Two windows used to create
    two "Импорт" sessions with different contents - precisely because each looked the name up in
    its own language. That cannot happen now, and the route is idempotent.
  2. A session name is not an identity. The window draws the words, the service keeps the
    mark; renaming one is the person's own business, and doing so turns it into an ordinary
    session.
  3. A person needs to browse many, and see the one in use first. The session browser is a
    list (search, count, "open / close session"), not a modal - the active session always stands
    first, and opening a session from the library offers to switch to editing.

Sessions also keep an agent honest: the makers take a session word (each / current /
new:<name>), the guide says where each tool puts its work, and workspace_get says where a
track really landed.

The message log tells a person what happened

The bell in the strip opens it: every change - the studio's own or an agent's - leaves a line,
quietly, with no toast in the middle of the work. The service sends facts, not tool names: what
was done, to what kind of thing, and that thing's own name (a deletion through the same lookup
the delete question already uses), and the window builds the sentence in the person's language.
The header can clear the log.

The rest

  • a control strip (ToolStrip) above the list: the sessions button, the view switch, the sort
    control, a refresh button and the journal bell;
  • lists read a page at a time (10 / 25 / 50, the person's choice) and sort by created /
    updated / name - now on every tab, library and sessions alike;
  • a track's card keeps its own lines: the card-wide icons on top, the playing time under them,
    the moment it was made beside the description, the actions in a row of their own;
  • a stem (a part) is shown inside the song it came from and is never counted as a song;
  • an offer to switch to editing when a session is opened from the library;
  • tooltips for the like button - in the card and in all four player layouts.

House rules followed

One commit on top of your latest main, with a conventional subject and a body that says what
changed and why. We did not copy your own habit of a bare one-line subject with no body: a pull
request we are asking you to review is no place to be lazy, and the first paragraph of the body
reads as news, since scripts/changelog.mjs builds the news page from the subject and that
paragraph. The skill the server serves (docs/mcp-skill.md) is updated with the same work:
sessions, the leash, the message log and the stems archive are all described for a connecting
agent.

Five languages for every string a person reads (app/i18n/yue2.ts), English comments, no Python
or Node anywhere in the runtime path, and everything else in separate components with commented
seams. tsc --noEmit, vitest run (35) and the service's own tests (232) are green.

A hello from RafStudio, Timon: glad to have worked alongside you - this fork is built with love
and appreciation for the studio you made, and every line of it is meant to be worth your review.

…wn, and lists that read a page

The window had no way to say where a track came from, and no place to say what an agent did.
This adds both: a ToolStrip above the list, a message log behind the bell, and sessions that live
in the service instead of the window's localStorage. New pieces are components of their own; the
author's files carry small, commented seams and none of his behaviour is rewritten.

Sessions live in library.sqlite (CREATE TABLE IF NOT EXISTS, as the rest of the schema asks): one
is open at a time, the active one stands first in the list, opening one from the library offers to
switch to editing, and the routes for generation, stems, karaoke, processing, MIDI and import take
an explicit workspace_id instead of trusting whatever happens to be open. A track made outside any
session is gathered once into a session the studio keeps for itself, marked kind='import' in
session_kinds - a mark in the data, not a name, so two windows can no longer end up with two
sessions named in the same language and holding different tracks. The repeat mode of a context is
stored in the library too.

The makers take a session word - each (a session of its own for every track, named after the
track), current, or new:<name> - and without a word the window asks the person once for the whole
pack; the answer can be remembered for the work or for good. A track is bound to the session that
was named, not to the active one, and workspace_get says where it really landed. The makers refuse
to run while nothing is open and nobody has chosen, so no track is ever made behind a person's
back.

The message log says what happened in the person's own language: the service sends facts - the
action, the kind of thing, and that thing's own name, read from the library for a deletion -
rather than a tool's name, and the window builds the sentence in all five languages. Every change
leaves a line quietly, the window's or an agent's; reads do not. Clearing the log asks first.

The agent's leash (free, risky, all) and its remembered answers live in the settings rather than
in the agent's hands: "in this session" is kept with the session itself, "always" is one switch,
"never" is a list of forbidden tools, and a deletion is put to the person as one plain question.
The skill the server serves now describes sessions, the leash and the stems archive for a
connecting agent.

Lists read a page at a time and sort by created, updated or name; a stem is shown inside the song
it came from and is never counted as a song; the like button has tooltips in the card and in all
four player layouts, and every string a person reads lives in all five languages.

Gates: tsc --noEmit, vitest (35) and cargo test -p music-server --lib (232) pass; preflight
reports READY for a pull request.
timoncool added a commit that referenced this pull request Sep 30, 2026
…ideos with the same picture window, Activity and a tidy library, and the credits for Wikimedia Commons, DiceBear and pull request #34
@timoncool

Copy link
Copy Markdown
Owner

Спасибо за PR — прочитали его целиком (37 файлов, +5176/−301) и разобрали по пунктам: какую задачу решает каждая идея, как это устроено у нас, как это принято делать, что в итоге взять. Код PR как есть не вливаем: всё полезное перенесено своим кодом, и сразу в три студии — YuE2, MiniMax Music3 и ACE-Step. Вышло в 3.3.0.

Что взяли

  • Лайки в песне. liked / liked_at в метаданных, отдельный маршрут, MCP работает без открытого окна, старые лайки один раз переезжают из localStorage — как у тебя. Сверху добавили две вещи: правка песни не снимает и не ставит лайк, а «Понравившиеся» идут от последнего лайка.
  • Журнал действий агента. Записи делает сервис, а не окно, поэтому они не теряются, когда окно закрыто. Окно строит фразу на своём языке из фактов (действие, вид, имя), имя удаляемого читается до удаления, тосты студии попадают туда же. Это лог, поэтому без счётчика и колокольчика: последний пункт боковой панели.
  • Команды агента идут в окно, на которое смотрят, а не в открытое последним.
  • Стемы под своей песней. Сворачиваются только стемы, каверы и перерендеры остаются отдельными песнями. Счётчик считает песни, очередь состоит из песен списка, стем играет один. «Разделить» у стема отключено с объяснением, и сервис тоже отказывает агенту. Повторное разделение сначала спрашивает и называет стемы, которые заменит.
  • Сортировка. Явное меню «Сортировка ▾» со всеми вариантами вместо одной кнопки, перебирающей их по кругу. Порядок запоминается для каждого списка отдельно.
  • Подписи кнопок. aria-label вместе с title на всех иконках плеера (все четыре раскладки) и карточки.
  • Когда сделана песня. Под длительностью — «сколько назад», точное время в подсказке, в деталях — дата со временем.
  • Отметка играющего трека в «Моей библиотеке».
  • Аннотации MCP. Инструменты, которые перезаписывают сохранённое, помечены destructiveHint, и клиент агента спрашивает сам.
  • Задача сессий решена через плейлист: список на «Создать» показывает плейлист, выбранный в «В плейлист», как Workspace у Suno.

Что не взяли и почему

  • Сессии как второе понятие рядом с плейлистом. Обязательная открытая сессия (409 на генерацию), сессия «Импорт», each/current/new. Плейлист уже решает эту задачу, а сессия на каждый трек — прямой антипаттерн из гайда Suno по Workspaces.
  • Второй слой разрешений агента (поводок, запреты, модалки с ожиданием до 300 с). По спецификации MCP спрашивать человека должен клиент. Мы вместо этого исправили аннотации, и клиенты спрашивают перед разрушающими вызовами.
  • Пагинация 10/25/50. Для личной библиотеки принят непрерывный список с поиском, фильтрами и сортировкой (NN/G). Если библиотеки дорастут до тысяч песен, нужна виртуализация, а не страницы.
  • Режимы повтора и перемешивания по контексту на сервере. Это состояние плеера.
  • Архив стемов и переписывание меток при старте. Это скрытые данные на диске без интерфейса. Вместо них подтверждение перед заменой.
  • Кнопка «Обновить» и перечитывание всего на фокус. Вместо них сервис сам оповещает окна, и изменения плейлистов теперь тоже доходят сразу.
  • Перестановка карточки, прижатая колонка, дата лайка на карточке, комментарии-приветствия в коде.

Коммиты (ветка feedback-3-2):

В MiniMax Music3 и ACE-Step то же самое в их ветках feedback-3-2.

Идеи отмечены в новости, в CHANGELOG 3.3.0 и в разделе благодарностей README всех трёх студий со ссылкой на этот PR. Спасибо!

@timoncool timoncool closed this Sep 30, 2026
SilentBob347 pushed a commit to SilentBob347/YuE2-Studio that referenced this pull request Sep 30, 2026
…d, every icon button named

What PR timoncool#34 set out to solve, done the way the studio already works (timoncool#34):

- A like is kept in the song's metadata with the moment it was given, not in one
  window's storage: every window and the agent read the same mark, and it survives
  a profile or machine change. PUT /v1/library/songs/{id}/liked and GET
  /v1/library/liked; library_liked and library_song_like no longer need an open
  window. An edit never undoes a like, a like does not change updated_at (the song's
  audio address, so a song liked while it plays keeps playing), and likes an earlier
  version kept in the window move into the library once; Liked reads from the
  latest like.
- A stem is shown under the song it was separated from, behind "Stems · N" with the
  parts' icons, wherever the song is shown; covers, re-renders and processed songs
  stay songs of their own. A list plays its songs in the order shown, a stem plays
  alone, and nothing falls back to a queue of every stem in the library. Stem names
  are translated; separating a stem is disabled with the reason, and separating a
  song again asks first, naming the stems it replaces.
- "Sort" beside Filters on the Create page and beside the tabs in the library:
  newest, oldest, title A-Z and Z-A, longest, shortest, and recently liked in Liked;
  each list keeps its own. Songs being made stay on top.
- Every icon button of the player's four layouts, the song card and the library rows
  has a name for a screen reader and the same words as its tooltip; the library row
  of the song in the player shows its state.
- Playlist changes reach every window, as song changes did; an agent's command goes
  to the window the person turned to last; tools that write over stored content
  (song, playlist, dataset and LoRA edits, stems, karaoke, covers, the OpenRouter
  key) are marked destructive, and reading the liked songs is marked read-only.
SilentBob347 pushed a commit to SilentBob347/YuE2-Studio that referenced this pull request Sep 30, 2026
…go into; the playlist page reads the shared library

- "To playlist" above Create is the project the songs go into, and the list beside the
  form now shows it, the way a workspace does: the playlist's songs with their stems,
  and the songs being made for it. "Nowhere" is the whole library, as before. The
  header names the playlist, and an empty one says the new songs go there. A song
  that finishes is in its playlist at once, so its row does not jump while the
  playlists are read again (timoncool#34).
- The playlist page reads the library's shared playlists and songs instead of a copy
  of its own, so a deletion, an edit or a new song made anywhere shows at once, and
  a playlist deleted elsewhere says so. Deleting asks in the studio's own dialog
  instead of the browser's; the page's icon buttons have names.
SilentBob347 pushed a commit to SilentBob347/YuE2-Studio that referenced this pull request Sep 30, 2026
…r every window

A message used to flash past as a toast and be gone, and nothing showed what an
agent had done to the library (timoncool#34). The service now keeps a journal in the
library, its latest 500 lines:

- every change an agent makes through the MCP server - a song made, edited or
  deleted, a playlist, stems, karaoke, a dataset, a LoRA, a download - is written as
  facts (what was done, to what kind of thing, and its name, read before a deletion);
  reads, moving the window around and playing leave no line;
- every message a window shows is written beside them.

"Activity" in the sidebar, on every page, counts what came since it was last read and
opens the journal: each line says in the window's language what happened, the agent's
and the studio's told apart by their icon, with how long ago and the exact moment in
its tooltip; a line or the whole journal can be cleared. Every window reads the same
journal and hears of a new line at once.

While the library is being read, the list says so instead of "no songs match".
SilentBob347 pushed a commit to SilentBob347/YuE2-Studio that referenced this pull request Sep 30, 2026
…e exact moment on hover; the details give the date with the time (timoncool#34)
SilentBob347 pushed a commit to SilentBob347/YuE2-Studio that referenced this pull request Sep 30, 2026
@MRafStudio

Copy link
Copy Markdown
Author

Тимон, спасибо. Такой разбор - редкость: 37 файлов, по пунктам, с причинами, да ещё и перенос в три студии своим кодом. Спорить тут не с чем: про плейлист вместо Workspace и про то, что спрашивать человека должен клиент, а не сервер, - принято, согласен.

Форк и рабочая ветка уже выровнены под твой main: в ветке теперь ровно твой код, ничего своего. Спасибо, что отметил нас в новости, в CHANGELOG и в благодарностях README - было честью поработать рядом. Дальше только пользоваться студией, а если что-то надумаем - начнём с чистого листа. Удачи!

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.

2 participants