@audiofool/moondog 0.3.0-beta.11 → 0.3.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/package.json +2 -2
- package/src/core/capability-catalog.mjs +11 -0
- package/src/core/library-store.mjs +48 -4
- package/src/core/moondog-application.mjs +95 -2
- package/src/i18n/screen/es.mjs +16 -4
- package/src/i18n/screen/ja.mjs +16 -4
- package/src/i18n/screen/pt.mjs +16 -4
- package/src/i18n/screen/zh.mjs +16 -4
- package/src/integrations/playlist-links.mjs +19 -7
- package/src/integrations/public-playlists.mjs +4 -2
- package/src/integrations/spotify/service.mjs +6 -1
- package/src/integrations/spotify/web-api-client.mjs +8 -2
- package/src/runtime/pi/agent-runtime.mjs +38 -5
- package/src/surfaces/cli/brand-components.mjs +1 -1
- package/src/surfaces/cli/command-completions.mjs +42 -3
- package/src/surfaces/cli/format-output.mjs +1 -1
- package/src/surfaces/cli/tui.mjs +2 -2
package/src/i18n/screen/pt.mjs
CHANGED
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
"What have you been listening to?": "O que você tem ouvido?",
|
|
23
23
|
"A song, a playlist, or what to play next.": "Uma música, uma playlist ou o que tocar depois.",
|
|
24
24
|
"Your personal music agent.": "Seu agente pessoal de música.",
|
|
25
|
-
"# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.": "# Sua sala de escuta\n\n## 01 / Ouça e descubra\n\nDigite para conversar sobre música, pedir uma playlist ou explorar.\nPara conversar, o Moondog precisa de um modelo: `/auth` faz o login e `/model` escolhe um.\nEnquanto a resposta chega, cada passo aparece na conversa, e o rodapé mostra o que está em andamento.\n\n- `/taste` - seu perfil: abra qualquer música ou artista para ver por que está ali\n- `/taste report` - o panorama completo em uma página\n- `/import` - traga seu histórico, sua biblioteca ou uma playlist\n- `/lyrics` - a letra na capa; `/lyrics sync` busca mais\n- `/service` - escolha onde eu toco a música: Spotify, Apple Music ou NetEase\n- `/spotify` - toque, adicione à fila e crie playlists no Spotify\n- Peça para passar a reprodução para o seu iPhone, computador ou outro dispositivo do Spotify pelo nome\n- `/web search <busca>` ou `/web read <url>` - pesquise em sites públicos de música\n\n## 02 / Deixe com a sua cara\n\n- `/profile` - o mesmo perfil de `/taste`\n- `/profile corrections` - tudo o que você me disse\n- `/profile retract <id>` - desfaça uma dessas escolhas\n- `/profile help` - todos os comandos do perfil\n- `/remember <texto>`, `/memory`, `/forget <id>` - o que eu lembro entre conversas\n\n## 03 / Pela sala\n\n- `/home` - volta para a capa do disco; a conversa continua\n- `/theme paper|charcoal|terminal|auto` - muda o visual\n- `/art braille|ascii|off` - muda a ilustração\n- `/motion on|off` - liga ou desliga a animação\n- `/commands` ou Ctrl+P - busca qualquer comando; sua mensagem não se perde\n- Page Up e Page Down rolam a conversa. O cabeçalho e o rascunho ficam no lugar\n- Para cima e para baixo no rascunho recuperam o que você digitou nesta conversa\n- `/resume` - retome uma conversa salva (digite para filtrar, Enter abre)\n- `/new` - comece do zero; esta conversa fica salva\n- `/status`, `/sources`, `/tools`, `/doctor` - veja o que está conectado e funcionando\n- `/reload` - recarrega as configurações do modelo e os logins\n- `/update [--check] [--channel latest|beta]` - procura uma versão nova, ou fecha esta sala e instala\n- `/help all` - todos os comandos, inclusive os do terminal\n- `/language` - escolha o idioma do Moondog\n- `/quit` - sair\n\nNa tela inicial, Tab vai para o menu. Esc volta para a digitação.\nEnter envia, e Shift+Enter começa uma nova linha.\nTab ou Enter aceitam uma sugestão.\nCtrl+C interrompe um pedido ao modelo ou à web, ou sai quando nada está rodando.\nNo perfil, digite para filtrar, Tab troca de lista e Enter mostra o que você pode fazer.\nCtrl+R atualiza e Ctrl+O abre o relatório completo.\nSeu perfil funciona sem modelo.\nColoque entre aspas caminhos, títulos e nomes com espaços.",
|
|
25
|
+
"# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/library` - your saved songs and playlists\n- `/generation on|off` - let Moondog make music on this Mac, or stop\n- `/onair` - go on air, or come off it\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/model roles` - see what side tasks use: the model that reads images and the web search service\n- `/effort` - choose how hard the model thinks\n- `/endpoint add` or `/endpoint remove <id>` - add a model service by its address, or remove it\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.": "# Sua sala de escuta\n\n## 01 / Ouça e descubra\n\nDigite para conversar sobre música, pedir uma playlist ou explorar.\nPara conversar, o Moondog precisa de um modelo: `/auth` faz o login e `/model` escolhe um.\nEnquanto a resposta chega, cada passo aparece na conversa, e o rodapé mostra o que está em andamento.\n\n- `/taste` - seu perfil: abra qualquer música ou artista para ver por que está ali\n- `/taste report` - o panorama completo em uma página\n- `/import` - traga seu histórico, sua biblioteca ou uma playlist\n- `/library` - suas músicas salvas e playlists\n- `/generation on|off` - deixe o Moondog fazer música neste Mac, ou pare\n- `/onair` - entre no ar, ou saia\n- `/lyrics` - a letra na capa; `/lyrics sync` busca mais\n- `/service` - escolha onde eu toco a música: Spotify, Apple Music ou NetEase\n- `/spotify` - toque, adicione à fila e crie playlists no Spotify\n- Peça para passar a reprodução para o seu iPhone, computador ou outro dispositivo do Spotify pelo nome\n- `/web search <busca>` ou `/web read <url>` - pesquise em sites públicos de música\n\n## 02 / Deixe com a sua cara\n\n- `/profile` - o mesmo perfil de `/taste`\n- `/profile corrections` - tudo o que você me disse\n- `/profile retract <id>` - desfaça uma dessas escolhas\n- `/profile help` - todos os comandos do perfil\n- `/remember <texto>`, `/memory`, `/forget <id>` - o que eu lembro entre conversas\n\n## 03 / Pela sala\n\n- `/home` - volta para a capa do disco; a conversa continua\n- `/theme paper|charcoal|terminal|auto` - muda o visual\n- `/art braille|ascii|off` - muda a ilustração\n- `/motion on|off` - liga ou desliga a animação\n- `/commands` ou Ctrl+P - busca qualquer comando; sua mensagem não se perde\n- Page Up e Page Down rolam a conversa. O cabeçalho e o rascunho ficam no lugar\n- Para cima e para baixo no rascunho recuperam o que você digitou nesta conversa\n- `/resume` - retome uma conversa salva (digite para filtrar, Enter abre)\n- `/new` - comece do zero; esta conversa fica salva\n- `/rewind` ou Alt+R - edita uma mensagem anterior nesta conversa; as mensagens seguintes são substituídas\n- `/branch` - continua daqui em uma conversa nova; esta fica salva\n- `/status`, `/sources`, `/tools`, `/doctor` - veja o que está conectado e funcionando\n- `/reload` - recarrega as configurações do modelo e os logins\n- `/model roles` - veja o que as tarefas auxiliares usam: o modelo que lê imagens e o serviço de busca na web\n- `/effort` - escolha quanto o modelo pensa\n- `/endpoint add` ou `/endpoint remove <id>` - adicione um serviço de modelos pelo endereço, ou remova-o\n- `/update [--check] [--channel latest|beta]` - procura uma versão nova, ou fecha esta sala e instala\n- `/help all` - todos os comandos, inclusive os do terminal\n- `/language` - escolha o idioma do Moondog\n- `/quit` - sair\n\nNa tela inicial, Tab vai para o menu. Esc volta para a digitação.\nEnter envia, e Shift+Enter começa uma nova linha.\nTab ou Enter aceitam uma sugestão.\nCtrl+C interrompe um pedido ao modelo ou à web, ou sai quando nada está rodando.\nNo perfil, digite para filtrar, Tab troca de lista e Enter mostra o que você pode fazer.\nCtrl+R atualiza e Ctrl+O abre o relatório completo.\nSeu perfil funciona sem modelo.\nColoque entre aspas caminhos, títulos e nomes com espaços.",
|
|
26
26
|
"Listening profile": "Perfil de escuta",
|
|
27
27
|
"Profile": "Perfil",
|
|
28
28
|
"See what your listening reveals. Tell me what I missed.": "Veja o que a sua escuta revela. Me diga o que eu deixei passar.",
|
|
@@ -176,7 +176,7 @@ export default {
|
|
|
176
176
|
"Memory": "Memória",
|
|
177
177
|
"Right now I can't change anything in your music accounts.": "No momento não consigo mudar nada nas suas contas de música.",
|
|
178
178
|
"I can make changes in your connected accounts, and I always ask first.": "Posso fazer mudanças nas suas contas conectadas, e sempre pergunto antes.",
|
|
179
|
-
"# Every command\n\nFrom your shell:\n\n- `moondog --version` - show the installed version\n- `moondog update [--check] [--channel latest|beta]` - check for or install a published release\n- `moondog web status|search|read [arguments] [--json]` - look things up on public music sites through DeepSeek, Brave Search or the Codex CLI\n- `moondog demo-history --output <absolute-file.zip> [--json]` - make a fictional Spotify history ZIP to try the importer with\n- `moondog auth login <provider>` - sign in to a model provider; the key is typed out of sight; `openai --chatgpt` signs in with your ChatGPT subscription\n- `moondog auth status [provider]` - see which sign-ins are saved\n- `moondog auth logout <provider>` - sign out of a provider\n- `moondog spotify help` - set up and control Spotify\n- `moondog spotify login [client-id]` - connect Spotify in your browser\n- `moondog spotify now|devices|queue` - see what Spotify is playing, where, and what's next\n- `moondog spotify recent` - see what you played lately\n- `moondog spotify sync-recent` - add your latest plays to your profile\n- `moondog spotify sync-library` - add your Spotify library to your profile\n- `moondog spotify play|pause|next|previous` - control Spotify playback\n- `moondog listenbrainz import-history <listen-history.json>` - add a ListenBrainz listens file to your profile\n- `moondog catalog latest-single --artist <name> [--known-release <title> | --from <spotify-history.zip>]` - find an artist's latest single on Apple Music (US), no model needed\n- `moondog status [--json]` - see where things stand\n- `moondog taste [--json]` - your listening report\n- `moondog taste --html [--output <file.html>]` - save your report as a web page that works offline\n- `moondog taste --card [--output <file.html>]` - save a short recap you can check before sharing\n- `moondog taste --from <spotify-history.zip> --html` - a one-off report from a Spotify ZIP, without saving it\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - a one-off report from both Spotify exports together\n- `moondog taste --from <spotify-history.zip> --save --html` - save the Spotify history, then show your full report\n- `moondog data inspect --scope <listening|apple|profile>` - see what's stored, and get the code needed to reset it\n- `moondog data export --scope <listening|apple|profile> --output <directory>` - export a copy, leaving the original alone\n- `moondog data reset --scope <listening|apple|profile> --confirm <token>` - set stored data aside (it is archived, not deleted)\n- `moondog profile build [--force]` - build or resume a saved profile with your connected model\n- `moondog profile saved [offset]` - read your saved profile\n- `moondog profile explain <number>` - trace a saved finding to its evidence\n- `moondog profile corrections [--all]` - everything you've told me, including earlier choices\n- `moondog profile correct --artist <name> (--like|--avoid)` - like an artist, or keep them out\n- `moondog profile correct --track <title> --by <artist> (--like|--avoid)` - like a track, or keep it out\n- `moondog profile retract <correction-id>` - undo one of your choices\n- `moondog demo --offline [--json]` - a demo with made-up data, no sign-in needed\n- `moondog demo [prompt] [--json]` - the same demo, talking through your model\n- `moondog ask <prompt>` - ask one question and exit\n- `moondog remember <text>` - ask me to remember something\n- `moondog forget <memory-id>` - forget something\n- `moondog memory reflect [--dry-run] [--json]` - let me think over recent conversations now\n- `moondog` - open the listening room\n\nInside the listening room:\n\n- `/update [--check] [--channel latest|beta]` - check for updates, or save and close this session to install one\n- `/status` or `/sources` - see where things stand\n- `/profile` or `/taste` - your profile, and why each song or artist is there\n- `/taste report` - the whole report on one page\n- `/profile build [--force]` - build or resume a saved reading; Ctrl+C keeps progress\n- `/profile saved [offset]` - read your saved profile\n- `/profile explain <number>` - inspect a saved finding's evidence\n- `/profile corrections [--all]` - everything you've told me\n- `/profile correct --track \"<title>\" --by \"<artist>\" (--like|--avoid)` - like a track, or keep it out\n- `/profile correct --artist \"<name>\" (--like|--avoid)` - like an artist, or keep them out\n- `/profile retract <correction-id>` - undo a choice\n- `/memory` - what I remember\n- `/tools` - what I can do right now\n- `/doctor` - check your setup\n- `/model` - pick the model I talk through\n- `/model <provider> <model>` - switch straight to a model\n- `/model refresh [provider]` - update public model choices; keep the selected model\n- `/auth [provider]` - sign in to a model provider\n- `/web status|search|read` - look things up on public music sites\n- `/import [path]` - bring in your history, library, or a playlist\n- `/language` - choose the language Moondog uses\n- `/service [spotify|apple_music|netease]` - choose where I play music\n- `/spotify` - Spotify commands\n- `/spotify login [client-id]` - connect Spotify\n- `/spotify now|devices|queue` - see what's playing, where, and what's next\n- `/spotify recent|sync-recent` - see or save your latest plays\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - add a Spotify ZIP, no sign-in needed\n- `/skip` or `/stop` - move to the next song preview, or stop them\n- `/reload` - reload model settings and sign-ins\n- `/remember [kind] <text>` - ask me to remember something\n- `/forget <memory-id>` - forget something\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/rewind latest` - edit the most recent message\n- `/resume` - pick up a saved conversation\n- `/resume <session-id>` - go straight to one\n- `/new` - start fresh; the last one stays saved\n- `/quit` - exit\n\nAnything you type that isn't a command goes to the model you picked with `/model`, or the one set in `MOONDOG_PROVIDER` and `MOONDOG_MODEL`.\nSign in with `/auth`, or set the provider's API key in your environment. `/auth openai` signs in with your ChatGPT subscription or an API key.\nOnce your profile is ready, I can search your library, explain what I see, and plan playlists with you.\nI can only control Spotify after `moondog spotify login`, and I never post, send messages, delete anything, or spend money.\nAsk me to move playback onto a device by name, such as your iPhone.": "# Todos os comandos\n\nNo seu terminal:\n\n- `moondog --version` - mostra a versão instalada\n- `moondog update [--check] [--channel latest|beta]` - procura ou instala uma versão publicada\n- `moondog web status|search|read [argumentos] [--json]` - pesquisa em sites públicos de música pelo DeepSeek, pelo Brave Search ou pelo Codex CLI\n- `moondog demo-history --output <arquivo-absoluto.zip> [--json]` - cria um ZIP fictício de histórico do Spotify para testar a importação\n- `moondog auth login <provedor>` - faz login em um provedor de modelos; a chave é digitada sem aparecer, e o `openai --chatgpt` entra com sua assinatura do ChatGPT\n- `moondog auth status [provedor]` - mostra quais logins estão salvos\n- `moondog auth logout <provedor>` - sai de um provedor\n- `moondog spotify help` - configura e controla o Spotify\n- `moondog spotify login [client-id]` - conecta o Spotify no navegador\n- `moondog spotify now|devices|queue` - mostra o que o Spotify está tocando, onde e o que vem depois\n- `moondog spotify recent` - mostra o que você ouviu ultimamente\n- `moondog spotify sync-recent` - adiciona suas últimas reproduções ao perfil\n- `moondog spotify sync-library` - adiciona sua biblioteca do Spotify ao perfil\n- `moondog spotify play|pause|next|previous` - controla a reprodução do Spotify\n- `moondog listenbrainz import-history <listen-history.json>` - adiciona um arquivo de escutas do ListenBrainz ao perfil\n- `moondog catalog latest-single --artist <nome> [--known-release <título> | --from <spotify-history.zip>]` - encontra o último single de um artista no Apple Music (EUA), sem modelo\n- `moondog status [--json]` - mostra como estão as coisas\n- `moondog taste [--json]` - seu relatório de escuta\n- `moondog taste --html [--output <arquivo.html>]` - salva o relatório como página web que funciona offline\n- `moondog taste --card [--output <arquivo.html>]` - salva um resumo curto que você pode conferir antes de compartilhar\n- `moondog taste --from <spotify-history.zip> --html` - um relatório único de um ZIP do Spotify, sem salvar\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - um relatório único das duas exportações do Spotify juntas\n- `moondog taste --from <spotify-history.zip> --save --html` - salva o histórico do Spotify e mostra o relatório completo\n- `moondog data inspect --scope <listening|apple|profile>` - mostra o que está guardado e o código para redefinir\n- `moondog data export --scope <listening|apple|profile> --output <pasta>` - exporta uma cópia sem mexer no original\n- `moondog data reset --scope <listening|apple|profile> --confirm <código>` - deixa de lado os dados guardados (são arquivados, não apagados)\n- `moondog profile build [--force]` - cria ou retoma um perfil salvo com o modelo conectado\n- `moondog profile saved [deslocamento]` - lê seu perfil salvo\n- `moondog profile explain <número>` - rastreia uma descoberta salva até a evidência\n- `moondog profile corrections [--all]` - tudo o que você me disse, inclusive escolhas anteriores\n- `moondog profile correct --artist <nome> (--like|--avoid)` - marca que você curte um artista, ou tira ele das sugestões\n- `moondog profile correct --track <título> --by <artista> (--like|--avoid)` - marca que você curte uma música, ou tira ela das sugestões\n- `moondog profile retract <correction-id>` - desfaz uma das suas escolhas\n- `moondog demo --offline [--json]` - uma demonstração com dados inventados, sem login\n- `moondog demo [pedido] [--json]` - a mesma demonstração, conversando pelo seu modelo\n- `moondog ask <pedido>` - faz uma pergunta e sai\n- `moondog remember <texto>` - pede para eu lembrar de algo\n- `moondog forget <memory-id>` - esquece algo\n- `moondog memory reflect [--dry-run] [--json]` - me deixa repassar agora as conversas recentes\n- `moondog` - abre a sala de escuta\n\nDentro da sala de escuta:\n\n- `/update [--check] [--channel latest|beta]` - procura atualizações, ou salva e fecha esta sessão para instalar uma\n- `/status` ou `/sources` - mostra como estão as coisas\n- `/profile` ou `/taste` - seu perfil, e por que cada música ou artista está ali\n- `/taste report` - o relatório completo em uma página\n- `/profile build [--force]` - cria ou retoma uma leitura salva; Ctrl+C guarda o progresso\n- `/profile saved [deslocamento]` - lê seu perfil salvo\n- `/profile explain <número>` - mostra a evidência de uma descoberta salva\n- `/profile corrections [--all]` - tudo o que você me disse\n- `/profile correct --track \"<título>\" --by \"<artista>\" (--like|--avoid)` - marca que você curte uma música, ou tira ela das sugestões\n- `/profile correct --artist \"<nome>\" (--like|--avoid)` - marca que você curte um artista, ou tira ele das sugestões\n- `/profile retract <correction-id>` - desfaz uma escolha\n- `/memory` - o que eu lembro\n- `/tools` - o que eu consigo fazer agora\n- `/doctor` - verifica sua configuração\n- `/model` - escolhe o modelo com que eu converso\n- `/model <provedor> <modelo>` - troca direto para um modelo\n- `/model refresh [provedor]` - atualiza as opções públicas de modelos; mantém o modelo escolhido\n- `/auth [provedor]` - faz login em um provedor de modelos\n- `/web status|search|read` - pesquisa em sites públicos de música\n- `/import [caminho]` - traz seu histórico, sua biblioteca ou uma playlist\n- `/language` - escolha o idioma do Moondog\n- `/service [spotify|apple_music|netease]` - escolha onde eu toco a música\n- `/spotify` - comandos do Spotify\n- `/spotify login [client-id]` - conecta o Spotify\n- `/spotify now|devices|queue` - mostra o que está tocando, onde e o que vem depois\n- `/spotify recent|sync-recent` - mostra ou salva suas últimas reproduções\n- `/spotify import-history \"/caminho/para/spotify-history.zip\"` - adiciona um ZIP do Spotify, sem login\n- `/skip` ou `/stop` - pula para a próxima prévia, ou interrompe as prévias\n- `/reload` - recarrega as configurações do modelo e os logins\n- `/remember [tipo] <texto>` - pede para eu lembrar de algo\n- `/forget <memory-id>` - esquece algo\n- `/rewind` ou Alt+R - edita uma mensagem anterior nesta conversa; as mensagens seguintes são substituídas\n- `/branch` - continua daqui em uma conversa nova; esta fica salva\n- `/rewind latest` - edita a mensagem mais recente\n- `/resume` - retoma uma conversa salva\n- `/resume <session-id>` - vai direto para uma\n- `/new` - começa do zero; a anterior fica salva\n- `/quit` - sair\n\nTudo o que você digitar que não for comando vai para o modelo escolhido com `/model`, ou o definido em `MOONDOG_PROVIDER` e `MOONDOG_MODEL`.\nFaça login com `/auth`, ou defina a chave de API do provedor no seu ambiente. `/auth openai` entra com sua assinatura do ChatGPT ou com uma chave de API.\nQuando seu perfil estiver pronto, posso buscar na sua biblioteca, explicar o que vejo e planejar playlists com você.\nSó consigo controlar o Spotify depois de `moondog spotify login`, e nunca publico, mando mensagens, apago nada ou gasto dinheiro.\nPeça para eu passar a reprodução para um dispositivo pelo nome, como o seu iPhone.",
|
|
179
|
+
"# Every command\n\nFrom your shell:\n\n- `moondog --version` - show the installed version\n- `moondog update [--check] [--channel latest|beta]` - check for or install a published release\n- `moondog web status|search|read [arguments] [--json]` - look things up on public music sites through DeepSeek, Brave Search or the Codex CLI\n- `moondog demo-history --output <absolute-file.zip> [--json]` - make a fictional Spotify history ZIP to try the importer with\n- `moondog auth login <provider>` - sign in to a model provider; the key is typed out of sight; `openai --chatgpt` signs in with your ChatGPT subscription\n- `moondog auth status [provider]` - see which sign-ins are saved\n- `moondog auth logout <provider>` - sign out of a provider\n- `moondog spotify help` - set up and control Spotify\n- `moondog spotify login [client-id]` - connect Spotify in your browser\n- `moondog spotify now|devices|queue` - see what Spotify is playing, where, and what's next\n- `moondog spotify recent` - see what you played lately\n- `moondog spotify sync-recent` - add your latest plays to your profile\n- `moondog spotify sync-library` - add your Spotify library to your profile\n- `moondog spotify play|pause|next|previous` - control Spotify playback\n- `moondog listenbrainz import-history <listen-history.json>` - add a ListenBrainz listens file to your profile\n- `moondog catalog latest-single --artist <name> [--known-release <title> | --from <spotify-history.zip>]` - find an artist's latest single on Apple Music (US), no model needed\n- `moondog status [--json]` - see where things stand\n- `moondog taste [--json]` - your listening report\n- `moondog taste --html [--output <file.html>]` - save your report as a web page that works offline\n- `moondog taste --card [--output <file.html>]` - save a short recap you can check before sharing\n- `moondog taste --from <spotify-history.zip> --html` - a one-off report from a Spotify ZIP, without saving it\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - a one-off report from both Spotify exports together\n- `moondog taste --from <spotify-history.zip> --save --html` - save the Spotify history, then show your full report\n- `moondog data inspect --scope <listening|apple|profile>` - see what's stored, and get the code needed to reset it\n- `moondog data export --scope <listening|apple|profile> --output <directory>` - export a copy, leaving the original alone\n- `moondog data reset --scope <listening|apple|profile> --confirm <token>` - set stored data aside (it is archived, not deleted)\n- `moondog profile build [--force]` - build or resume a saved profile with your connected model\n- `moondog profile saved [offset]` - read your saved profile\n- `moondog profile explain <number>` - trace a saved finding to its evidence\n- `moondog profile corrections [--all]` - everything you've told me, including earlier choices\n- `moondog profile correct --artist <name> (--like|--avoid)` - like an artist, or keep them out\n- `moondog profile correct --track <title> --by <artist> (--like|--avoid)` - like a track, or keep it out\n- `moondog profile retract <correction-id>` - undo one of your choices\n- `moondog demo --offline [--json]` - a demo with made-up data, no sign-in needed\n- `moondog demo [prompt] [--json]` - the same demo, talking through your model\n- `moondog ask <prompt>` - ask one question and exit\n- `moondog remember <text>` - ask me to remember something\n- `moondog forget <memory-id>` - forget something\n- `moondog memory reflect [--dry-run] [--json]` - let me think over recent conversations now\n- `moondog` - open the listening room\n\nInside the listening room:\n\n- `/update [--check] [--channel latest|beta]` - check for updates, or save and close this session to install one\n- `/status` or `/sources` - see where things stand\n- `/profile` or `/taste` - your profile, and why each song or artist is there\n- `/taste report` - the whole report on one page\n- `/profile build [--force]` - build or resume a saved reading; Ctrl+C keeps progress\n- `/profile saved [offset]` - read your saved profile\n- `/profile explain <number>` - inspect a saved finding's evidence\n- `/profile corrections [--all]` - everything you've told me\n- `/profile correct --track \"<title>\" --by \"<artist>\" (--like|--avoid)` - like a track, or keep it out\n- `/profile correct --artist \"<name>\" (--like|--avoid)` - like an artist, or keep them out\n- `/profile retract <correction-id>` - undo a choice\n- `/memory` - what I remember\n- `/tools` - what I can do right now\n- `/doctor` - check your setup\n- `/model` - pick the model I talk through\n- `/model <provider> <model>` - switch straight to a model\n- `/model refresh [provider]` - update public model choices; keep the selected model\n- `/model roles` - see what side tasks use: the model that reads images and the web search service\n- `/model vision auto|<provider> <model>` - choose the model that reads images\n- `/model web auto|deepseek|brave|codex` - choose the web search service\n- `/effort` - choose how hard the model thinks\n- `/auth [provider]` - sign in to a model provider\n- `/endpoint add` or `/endpoint remove <id>` - add a model service by its address, or remove it\n- `/web status|search|read` - look things up on public music sites\n- `/import [path]` - bring in your history, library, or a playlist\n- `/library` - your saved songs and playlists\n- `/library play <name>` - play a playlist\n- `/library save [playlist]` - keep the song playing now\n- `/library import <link>` - copy a playlist from a link\n- `/generation on|off` - let Moondog make music on this Mac, or stop\n- `/generation download|use|remove|cancel` - set up a Stable Audio 3 model\n- `/onair` - go on air, or come off it\n- `/language` - choose the language Moondog uses\n- `/service [spotify|apple_music|netease]` - choose where I play music\n- `/spotify` - Spotify commands\n- `/spotify login [client-id]` - connect Spotify\n- `/spotify now|devices|queue` - see what's playing, where, and what's next\n- `/spotify recent|sync-recent` - see or save your latest plays\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - add a Spotify ZIP, no sign-in needed\n- `/skip` or `/stop` - move to the next song preview or stream track, or stop them\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/reload` - reload model settings and sign-ins\n- `/remember [kind] <text>` - ask me to remember something\n- `/forget <memory-id>` - forget something\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/rewind latest` - edit the most recent message\n- `/resume` - pick up a saved conversation\n- `/resume <session-id>` - go straight to one\n- `/new` - start fresh; the last one stays saved\n- `/quit` - exit\n\nAnything you type that isn't a command goes to the model you picked with `/model`, or the one set in `MOONDOG_PROVIDER` and `MOONDOG_MODEL`.\nSign in with `/auth`, or set the provider's API key in your environment. `/auth openai` signs in with your ChatGPT subscription or an API key.\nOnce your profile is ready, I can search your library, explain what I see, and plan playlists with you.\nI can only control Spotify after `moondog spotify login`. I ask before I remove anything from your library, and I never post, send messages, or spend money.\nAsk me to move playback onto a device by name, such as your iPhone.": "# Todos os comandos\n\nNo seu terminal:\n\n- `moondog --version` - mostra a versão instalada\n- `moondog update [--check] [--channel latest|beta]` - procura ou instala uma versão publicada\n- `moondog web status|search|read [argumentos] [--json]` - pesquisa em sites públicos de música pelo DeepSeek, pelo Brave Search ou pelo Codex CLI\n- `moondog demo-history --output <arquivo-absoluto.zip> [--json]` - cria um ZIP fictício de histórico do Spotify para testar a importação\n- `moondog auth login <provedor>` - faz login em um provedor de modelos; a chave é digitada sem aparecer, e o `openai --chatgpt` entra com sua assinatura do ChatGPT\n- `moondog auth status [provedor]` - mostra quais logins estão salvos\n- `moondog auth logout <provedor>` - sai de um provedor\n- `moondog spotify help` - configura e controla o Spotify\n- `moondog spotify login [client-id]` - conecta o Spotify no navegador\n- `moondog spotify now|devices|queue` - mostra o que o Spotify está tocando, onde e o que vem depois\n- `moondog spotify recent` - mostra o que você ouviu ultimamente\n- `moondog spotify sync-recent` - adiciona suas últimas reproduções ao perfil\n- `moondog spotify sync-library` - adiciona sua biblioteca do Spotify ao perfil\n- `moondog spotify play|pause|next|previous` - controla a reprodução do Spotify\n- `moondog listenbrainz import-history <listen-history.json>` - adiciona um arquivo de escutas do ListenBrainz ao perfil\n- `moondog catalog latest-single --artist <nome> [--known-release <título> | --from <spotify-history.zip>]` - encontra o último single de um artista no Apple Music (EUA), sem modelo\n- `moondog status [--json]` - mostra como estão as coisas\n- `moondog taste [--json]` - seu relatório de escuta\n- `moondog taste --html [--output <arquivo.html>]` - salva o relatório como página web que funciona offline\n- `moondog taste --card [--output <arquivo.html>]` - salva um resumo curto que você pode conferir antes de compartilhar\n- `moondog taste --from <spotify-history.zip> --html` - um relatório único de um ZIP do Spotify, sem salvar\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - um relatório único das duas exportações do Spotify juntas\n- `moondog taste --from <spotify-history.zip> --save --html` - salva o histórico do Spotify e mostra o relatório completo\n- `moondog data inspect --scope <listening|apple|profile>` - mostra o que está guardado e o código para redefinir\n- `moondog data export --scope <listening|apple|profile> --output <pasta>` - exporta uma cópia sem mexer no original\n- `moondog data reset --scope <listening|apple|profile> --confirm <código>` - deixa de lado os dados guardados (são arquivados, não apagados)\n- `moondog profile build [--force]` - cria ou retoma um perfil salvo com o modelo conectado\n- `moondog profile saved [deslocamento]` - lê seu perfil salvo\n- `moondog profile explain <número>` - rastreia uma descoberta salva até a evidência\n- `moondog profile corrections [--all]` - tudo o que você me disse, inclusive escolhas anteriores\n- `moondog profile correct --artist <nome> (--like|--avoid)` - marca que você curte um artista, ou tira ele das sugestões\n- `moondog profile correct --track <título> --by <artista> (--like|--avoid)` - marca que você curte uma música, ou tira ela das sugestões\n- `moondog profile retract <correction-id>` - desfaz uma das suas escolhas\n- `moondog demo --offline [--json]` - uma demonstração com dados inventados, sem login\n- `moondog demo [pedido] [--json]` - a mesma demonstração, conversando pelo seu modelo\n- `moondog ask <pedido>` - faz uma pergunta e sai\n- `moondog remember <texto>` - pede para eu lembrar de algo\n- `moondog forget <memory-id>` - esquece algo\n- `moondog memory reflect [--dry-run] [--json]` - me deixa repassar agora as conversas recentes\n- `moondog` - abre a sala de escuta\n\nDentro da sala de escuta:\n\n- `/update [--check] [--channel latest|beta]` - procura atualizações, ou salva e fecha esta sessão para instalar uma\n- `/status` ou `/sources` - mostra como estão as coisas\n- `/profile` ou `/taste` - seu perfil, e por que cada música ou artista está ali\n- `/taste report` - o relatório completo em uma página\n- `/profile build [--force]` - cria ou retoma uma leitura salva; Ctrl+C guarda o progresso\n- `/profile saved [deslocamento]` - lê seu perfil salvo\n- `/profile explain <número>` - mostra a evidência de uma descoberta salva\n- `/profile corrections [--all]` - tudo o que você me disse\n- `/profile correct --track \"<título>\" --by \"<artista>\" (--like|--avoid)` - marca que você curte uma música, ou tira ela das sugestões\n- `/profile correct --artist \"<nome>\" (--like|--avoid)` - marca que você curte um artista, ou tira ele das sugestões\n- `/profile retract <correction-id>` - desfaz uma escolha\n- `/memory` - o que eu lembro\n- `/tools` - o que eu consigo fazer agora\n- `/doctor` - verifica sua configuração\n- `/model` - escolhe o modelo com que eu converso\n- `/model <provedor> <modelo>` - troca direto para um modelo\n- `/model refresh [provedor]` - atualiza as opções públicas de modelos; mantém o modelo escolhido\n- `/model roles` - veja o que as tarefas auxiliares usam: o modelo que lê imagens e o serviço de busca na web\n- `/model vision auto|<provedor> <modelo>` - escolha o modelo que lê imagens\n- `/model web auto|deepseek|brave|codex` - escolha o serviço de busca na web\n- `/effort` - escolha quanto o modelo pensa\n- `/auth [provedor]` - faz login em um provedor de modelos\n- `/endpoint add` ou `/endpoint remove <id>` - adicione um serviço de modelos pelo endereço, ou remova-o\n- `/web status|search|read` - pesquisa em sites públicos de música\n- `/import [caminho]` - traz seu histórico, sua biblioteca ou uma playlist\n- `/library` - suas músicas salvas e playlists\n- `/library play <nome>` - toque uma playlist\n- `/library save [playlist]` - salve a música que está tocando\n- `/library import <link>` - copie uma playlist de um link\n- `/generation on|off` - deixe o Moondog fazer música neste Mac, ou pare\n- `/generation download|use|remove|cancel` - configure um modelo do Stable Audio 3\n- `/onair` - entre no ar, ou saia\n- `/language` - escolha o idioma do Moondog\n- `/service [spotify|apple_music|netease]` - escolha onde eu toco a música\n- `/spotify` - comandos do Spotify\n- `/spotify login [client-id]` - conecta o Spotify\n- `/spotify now|devices|queue` - mostra o que está tocando, onde e o que vem depois\n- `/spotify recent|sync-recent` - mostra ou salva suas últimas reproduções\n- `/spotify import-history \"/caminho/para/spotify-history.zip\"` - adiciona um ZIP do Spotify, sem login\n- `/skip` ou `/stop` - pula para a próxima prévia ou faixa da transmissão, ou as interrompe\n- `/home` - volta para a capa do disco; a conversa continua\n- `/theme paper|charcoal|terminal|auto` - muda o visual\n- `/art braille|ascii|off` - muda a ilustração\n- `/motion on|off` - liga ou desliga a animação\n- `/lyrics` - a letra na capa; `/lyrics sync` busca mais\n- `/reload` - recarrega as configurações do modelo e os logins\n- `/remember [tipo] <texto>` - pede para eu lembrar de algo\n- `/forget <memory-id>` - esquece algo\n- `/rewind` ou Alt+R - edita uma mensagem anterior nesta conversa; as mensagens seguintes são substituídas\n- `/branch` - continua daqui em uma conversa nova; esta fica salva\n- `/rewind latest` - edita a mensagem mais recente\n- `/resume` - retoma uma conversa salva\n- `/resume <session-id>` - vai direto para uma\n- `/new` - começa do zero; a anterior fica salva\n- `/quit` - sair\n\nTudo o que você digitar que não for comando vai para o modelo escolhido com `/model`, ou o definido em `MOONDOG_PROVIDER` e `MOONDOG_MODEL`.\nFaça login com `/auth`, ou defina a chave de API do provedor no seu ambiente. `/auth openai` entra com sua assinatura do ChatGPT ou com uma chave de API.\nQuando seu perfil estiver pronto, posso buscar na sua biblioteca, explicar o que vejo e planejar playlists com você.\nSó consigo controlar o Spotify depois de `moondog spotify login`. Antes de tirar algo da sua biblioteca eu pergunto, e nunca publico, mando mensagens ou gasto dinheiro.\nPeça para eu passar a reprodução para um dispositivo pelo nome, como o seu iPhone.",
|
|
180
180
|
"Apple Music library": "Biblioteca do Apple Music",
|
|
181
181
|
"Model": "Modelo",
|
|
182
182
|
"Finding similar music": "Encontrar música parecida",
|
|
@@ -817,8 +817,8 @@ export default {
|
|
|
817
817
|
"Choose the model Moondog talks through": "Escolha o modelo com que o Moondog conversa",
|
|
818
818
|
"Look things up on public music sites": "Pesquise em sites públicos de música",
|
|
819
819
|
"Connect and control Spotify": "Conecte e controle o Spotify",
|
|
820
|
-
"Skip to the next song preview": "Pula para a próxima prévia",
|
|
821
|
-
"Stop the song previews": "Interrompe as prévias",
|
|
820
|
+
"Skip to the next song preview or stream track": "Pula para a próxima prévia ou faixa da transmissão",
|
|
821
|
+
"Stop the song previews or the stream": "Interrompe as prévias ou a transmissão",
|
|
822
822
|
"Reload model settings and sign-ins": "Recarrega as configurações do modelo e os logins",
|
|
823
823
|
"Ask Moondog to remember something": "Peça ao Moondog para lembrar de algo",
|
|
824
824
|
"Forget one memory by ID": "Esqueça uma lembrança pelo ID",
|
|
@@ -979,6 +979,17 @@ export default {
|
|
|
979
979
|
"Saved the {service} key. Web search goes through {provider}.": "Salvei a chave do {service}. A pesquisa na web passa pelo {provider}.",
|
|
980
980
|
"Saved the {service} key, but web search still isn't ready. Run `/web status` to see why.": "Salvei a chave do {service}, mas a pesquisa na web ainda não está pronta. Use `/web status` para ver o motivo.",
|
|
981
981
|
"Add an endpoint by its address": "Adicionar um endpoint pelo endereço",
|
|
982
|
+
"See what side tasks use": "Veja o que as tarefas auxiliares usam",
|
|
983
|
+
"Choose the model that reads images": "Escolha o modelo que lê imagens",
|
|
984
|
+
"Choose the web search service": "Escolha o serviço de busca na web",
|
|
985
|
+
"Let the chat model read images when it can": "Deixe o modelo do chat ler as imagens quando puder",
|
|
986
|
+
"Take the first service that is set up": "Use o primeiro serviço configurado",
|
|
987
|
+
"Search with DeepSeek": "Busque com o DeepSeek",
|
|
988
|
+
"Search with Brave Search": "Busque com o Brave Search",
|
|
989
|
+
"Search with the Codex CLI": "Busque com a CLI do Codex",
|
|
990
|
+
"Play a playlist by name": "Toque uma playlist pelo nome",
|
|
991
|
+
"Keep the song playing now": "Salve a música que está tocando",
|
|
992
|
+
"Copy a playlist from a link": "Copie uma playlist de um link",
|
|
982
993
|
"Remove an endpoint and its key": "Remover um endpoint e a chave dele",
|
|
983
994
|
"ChatGPT sign-in or API key": "Login do ChatGPT ou chave de API",
|
|
984
995
|
"ChatGPT subscription": "Assinatura do ChatGPT",
|
|
@@ -1136,6 +1147,7 @@ export default {
|
|
|
1136
1147
|
"Your saved songs and playlists": "Suas músicas salvas e playlists",
|
|
1137
1148
|
"Look in the library": "Olhar na biblioteca",
|
|
1138
1149
|
"Save to the library": "Salvar na biblioteca",
|
|
1150
|
+
"Change a playlist": "Alterar uma playlist",
|
|
1139
1151
|
"Play from the library": "Tocar da biblioteca",
|
|
1140
1152
|
"Paste a playlist link after /library import.": "Cole um link de playlist depois de /library import.",
|
|
1141
1153
|
"Reading the playlist…": "Lendo a playlist…",
|
package/src/i18n/screen/zh.mjs
CHANGED
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
"What have you been listening to?": "最近在听什么?",
|
|
23
23
|
"A song, a playlist, or what to play next.": "一首歌、一个歌单,或者接下来放什么。",
|
|
24
24
|
"Your personal music agent.": "你的私人音乐助手。",
|
|
25
|
-
"# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.": "# 你的聆听室\n\n## 01 / 听歌与发现\n\n直接输入就能聊音乐、要一个歌单,或者随便逛逛。\n对话需要一个模型:`/auth` 登录,然后用 `/model` 选一个。\n回答生成时,每一步都会显示在对话里,底栏会标出正在进行的那一步。\n\n- `/taste` - 你的资料:打开任意歌曲或艺人,看看它为什么在这里\n- `/taste report` - 一页看完整体情况\n- `/import` - 导入你的历史、曲库或一个歌单\n- `/lyrics` - 封套上的歌词;`/lyrics sync` 找更多\n- `/service` - 选择我在哪里放音乐:Spotify、Apple Music 或网易云音乐\n- `/spotify` - 在 Spotify 里播放、加入队列、建歌单\n- 说出设备名,就能把播放切到你的 iPhone、电脑或其他 Spotify 设备\n- `/web search <关键词>` 或 `/web read <网址>` - 在公开音乐网站上查资料\n\n## 02 / 变成你的\n\n- `/profile` - 和 `/taste` 是同一份资料\n- `/profile corrections` - 你告诉过我的所有选择\n- `/profile retract <id>` - 撤销其中一项\n- `/profile help` - 资料相关的全部命令\n- `/remember <内容>`、`/memory`、`/forget <id>` - 我在对话之间记住的内容\n\n## 03 / 在房间里转转\n\n- `/home` - 回到唱片封套;对话还在\n- `/theme paper|charcoal|terminal|auto` - 换外观\n- `/art braille|ascii|off` - 换插画\n- `/motion on|off` - 打开或关闭动画\n- `/commands` 或 Ctrl+P - 搜索全部命令;你正在写的消息不会丢\n- Page Up 和 Page Down 滚动对话,顶栏和草稿保持不动\n- 在草稿里按上下键,可以找回本次对话中输入过的内容\n- `/resume` - 继续一段保存的对话(输入筛选,Enter 打开)\n- `/new` - 重新开始;这段对话会保存下来\n- `/status`、`/sources`、`/tools`、`/doctor` - 看看哪些已连接、正常工作\n- `/reload` - 重新加载模型设置和登录\n- `/update [--check] [--channel latest|beta]` - 检查新版本,或关闭聆听室并安装\n- `/help all` - 全部命令,包括终端里的\n- `/language` - 选择 Moondog 使用的语言\n- `/quit` - 离开\n\n在首页按 Tab 进入菜单,按 Esc 回到输入。\nEnter 发送,Shift+Enter 换行。\nTab 或 Enter 接受补全建议。\nCtrl+C 停止模型或网页请求;没有任务在运行时则退出。\n在资料页里,输入即可筛选,Tab 切换列表,Enter 查看可做的操作。\nCtrl+R 刷新,Ctrl+O 打开完整报告。\n没有模型,资料页也能用。\n路径、标题和名字里有空格时,请加上引号。",
|
|
25
|
+
"# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/library` - your saved songs and playlists\n- `/generation on|off` - let Moondog make music on this Mac, or stop\n- `/onair` - go on air, or come off it\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/model roles` - see what side tasks use: the model that reads images and the web search service\n- `/effort` - choose how hard the model thinks\n- `/endpoint add` or `/endpoint remove <id>` - add a model service by its address, or remove it\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.": "# 你的聆听室\n\n## 01 / 听歌与发现\n\n直接输入就能聊音乐、要一个歌单,或者随便逛逛。\n对话需要一个模型:`/auth` 登录,然后用 `/model` 选一个。\n回答生成时,每一步都会显示在对话里,底栏会标出正在进行的那一步。\n\n- `/taste` - 你的资料:打开任意歌曲或艺人,看看它为什么在这里\n- `/taste report` - 一页看完整体情况\n- `/import` - 导入你的历史、曲库或一个歌单\n- `/library` - 你收藏的歌和播放列表\n- `/generation on|off` - 让 Moondog 在这台 Mac 上做音乐,或停下\n- `/onair` - 开播,或下播\n- `/lyrics` - 封套上的歌词;`/lyrics sync` 找更多\n- `/service` - 选择我在哪里放音乐:Spotify、Apple Music 或网易云音乐\n- `/spotify` - 在 Spotify 里播放、加入队列、建歌单\n- 说出设备名,就能把播放切到你的 iPhone、电脑或其他 Spotify 设备\n- `/web search <关键词>` 或 `/web read <网址>` - 在公开音乐网站上查资料\n\n## 02 / 变成你的\n\n- `/profile` - 和 `/taste` 是同一份资料\n- `/profile corrections` - 你告诉过我的所有选择\n- `/profile retract <id>` - 撤销其中一项\n- `/profile help` - 资料相关的全部命令\n- `/remember <内容>`、`/memory`、`/forget <id>` - 我在对话之间记住的内容\n\n## 03 / 在房间里转转\n\n- `/home` - 回到唱片封套;对话还在\n- `/theme paper|charcoal|terminal|auto` - 换外观\n- `/art braille|ascii|off` - 换插画\n- `/motion on|off` - 打开或关闭动画\n- `/commands` 或 Ctrl+P - 搜索全部命令;你正在写的消息不会丢\n- Page Up 和 Page Down 滚动对话,顶栏和草稿保持不动\n- 在草稿里按上下键,可以找回本次对话中输入过的内容\n- `/resume` - 继续一段保存的对话(输入筛选,Enter 打开)\n- `/new` - 重新开始;这段对话会保存下来\n- `/rewind` 或 Alt+R - 就地编辑之前的一条消息;之后的消息会被替换\n- `/branch` - 从这里在新对话中继续;这段对话会保留\n- `/status`、`/sources`、`/tools`、`/doctor` - 看看哪些已连接、正常工作\n- `/reload` - 重新加载模型设置和登录\n- `/model roles` - 看看副任务在用什么:读图的模型和网页搜索服务\n- `/effort` - 选择模型思考的程度\n- `/endpoint add` 或 `/endpoint remove <id>` - 按地址添加模型服务,或移除它\n- `/update [--check] [--channel latest|beta]` - 检查新版本,或关闭聆听室并安装\n- `/help all` - 全部命令,包括终端里的\n- `/language` - 选择 Moondog 使用的语言\n- `/quit` - 离开\n\n在首页按 Tab 进入菜单,按 Esc 回到输入。\nEnter 发送,Shift+Enter 换行。\nTab 或 Enter 接受补全建议。\nCtrl+C 停止模型或网页请求;没有任务在运行时则退出。\n在资料页里,输入即可筛选,Tab 切换列表,Enter 查看可做的操作。\nCtrl+R 刷新,Ctrl+O 打开完整报告。\n没有模型,资料页也能用。\n路径、标题和名字里有空格时,请加上引号。",
|
|
26
26
|
"Listening profile": "聆听资料",
|
|
27
27
|
"Profile": "资料",
|
|
28
28
|
"See what your listening reveals. Tell me what I missed.": "看看你的聆听透露了什么,告诉我哪里没看到。",
|
|
@@ -176,7 +176,7 @@ export default {
|
|
|
176
176
|
"Memory": "记忆",
|
|
177
177
|
"Right now I can't change anything in your music accounts.": "目前我不能修改你音乐账号里的任何内容。",
|
|
178
178
|
"I can make changes in your connected accounts, and I always ask first.": "我可以修改你已连接的账号,并且每次都会先问你。",
|
|
179
|
-
"# Every command\n\nFrom your shell:\n\n- `moondog --version` - show the installed version\n- `moondog update [--check] [--channel latest|beta]` - check for or install a published release\n- `moondog web status|search|read [arguments] [--json]` - look things up on public music sites through DeepSeek, Brave Search or the Codex CLI\n- `moondog demo-history --output <absolute-file.zip> [--json]` - make a fictional Spotify history ZIP to try the importer with\n- `moondog auth login <provider>` - sign in to a model provider; the key is typed out of sight; `openai --chatgpt` signs in with your ChatGPT subscription\n- `moondog auth status [provider]` - see which sign-ins are saved\n- `moondog auth logout <provider>` - sign out of a provider\n- `moondog spotify help` - set up and control Spotify\n- `moondog spotify login [client-id]` - connect Spotify in your browser\n- `moondog spotify now|devices|queue` - see what Spotify is playing, where, and what's next\n- `moondog spotify recent` - see what you played lately\n- `moondog spotify sync-recent` - add your latest plays to your profile\n- `moondog spotify sync-library` - add your Spotify library to your profile\n- `moondog spotify play|pause|next|previous` - control Spotify playback\n- `moondog listenbrainz import-history <listen-history.json>` - add a ListenBrainz listens file to your profile\n- `moondog catalog latest-single --artist <name> [--known-release <title> | --from <spotify-history.zip>]` - find an artist's latest single on Apple Music (US), no model needed\n- `moondog status [--json]` - see where things stand\n- `moondog taste [--json]` - your listening report\n- `moondog taste --html [--output <file.html>]` - save your report as a web page that works offline\n- `moondog taste --card [--output <file.html>]` - save a short recap you can check before sharing\n- `moondog taste --from <spotify-history.zip> --html` - a one-off report from a Spotify ZIP, without saving it\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - a one-off report from both Spotify exports together\n- `moondog taste --from <spotify-history.zip> --save --html` - save the Spotify history, then show your full report\n- `moondog data inspect --scope <listening|apple|profile>` - see what's stored, and get the code needed to reset it\n- `moondog data export --scope <listening|apple|profile> --output <directory>` - export a copy, leaving the original alone\n- `moondog data reset --scope <listening|apple|profile> --confirm <token>` - set stored data aside (it is archived, not deleted)\n- `moondog profile build [--force]` - build or resume a saved profile with your connected model\n- `moondog profile saved [offset]` - read your saved profile\n- `moondog profile explain <number>` - trace a saved finding to its evidence\n- `moondog profile corrections [--all]` - everything you've told me, including earlier choices\n- `moondog profile correct --artist <name> (--like|--avoid)` - like an artist, or keep them out\n- `moondog profile correct --track <title> --by <artist> (--like|--avoid)` - like a track, or keep it out\n- `moondog profile retract <correction-id>` - undo one of your choices\n- `moondog demo --offline [--json]` - a demo with made-up data, no sign-in needed\n- `moondog demo [prompt] [--json]` - the same demo, talking through your model\n- `moondog ask <prompt>` - ask one question and exit\n- `moondog remember <text>` - ask me to remember something\n- `moondog forget <memory-id>` - forget something\n- `moondog memory reflect [--dry-run] [--json]` - let me think over recent conversations now\n- `moondog` - open the listening room\n\nInside the listening room:\n\n- `/update [--check] [--channel latest|beta]` - check for updates, or save and close this session to install one\n- `/status` or `/sources` - see where things stand\n- `/profile` or `/taste` - your profile, and why each song or artist is there\n- `/taste report` - the whole report on one page\n- `/profile build [--force]` - build or resume a saved reading; Ctrl+C keeps progress\n- `/profile saved [offset]` - read your saved profile\n- `/profile explain <number>` - inspect a saved finding's evidence\n- `/profile corrections [--all]` - everything you've told me\n- `/profile correct --track \"<title>\" --by \"<artist>\" (--like|--avoid)` - like a track, or keep it out\n- `/profile correct --artist \"<name>\" (--like|--avoid)` - like an artist, or keep them out\n- `/profile retract <correction-id>` - undo a choice\n- `/memory` - what I remember\n- `/tools` - what I can do right now\n- `/doctor` - check your setup\n- `/model` - pick the model I talk through\n- `/model <provider> <model>` - switch straight to a model\n- `/model refresh [provider]` - update public model choices; keep the selected model\n- `/auth [provider]` - sign in to a model provider\n- `/web status|search|read` - look things up on public music sites\n- `/import [path]` - bring in your history, library, or a playlist\n- `/language` - choose the language Moondog uses\n- `/service [spotify|apple_music|netease]` - choose where I play music\n- `/spotify` - Spotify commands\n- `/spotify login [client-id]` - connect Spotify\n- `/spotify now|devices|queue` - see what's playing, where, and what's next\n- `/spotify recent|sync-recent` - see or save your latest plays\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - add a Spotify ZIP, no sign-in needed\n- `/skip` or `/stop` - move to the next song preview, or stop them\n- `/reload` - reload model settings and sign-ins\n- `/remember [kind] <text>` - ask me to remember something\n- `/forget <memory-id>` - forget something\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/rewind latest` - edit the most recent message\n- `/resume` - pick up a saved conversation\n- `/resume <session-id>` - go straight to one\n- `/new` - start fresh; the last one stays saved\n- `/quit` - exit\n\nAnything you type that isn't a command goes to the model you picked with `/model`, or the one set in `MOONDOG_PROVIDER` and `MOONDOG_MODEL`.\nSign in with `/auth`, or set the provider's API key in your environment. `/auth openai` signs in with your ChatGPT subscription or an API key.\nOnce your profile is ready, I can search your library, explain what I see, and plan playlists with you.\nI can only control Spotify after `moondog spotify login`, and I never post, send messages, delete anything, or spend money.\nAsk me to move playback onto a device by name, such as your iPhone.": "# 全部命令\n\n在终端里:\n\n- `moondog --version` - 显示已安装的版本\n- `moondog update [--check] [--channel latest|beta]` - 检查或安装已发布的版本\n- `moondog web status|search|read [参数] [--json]` - 通过 DeepSeek、Brave Search 或 Codex CLI 在公开音乐网站上查资料\n- `moondog demo-history --output <绝对路径.zip> [--json]` - 生成一个虚构的 Spotify 历史 ZIP,用来试用导入\n- `moondog auth login <provider>` - 登录模型服务商;密钥输入时不显示,`openai --chatgpt` 用你的 ChatGPT 订阅登录\n- `moondog auth status [provider]` - 查看保存了哪些登录\n- `moondog auth logout <provider>` - 退出某个服务商\n- `moondog spotify help` - 设置并控制 Spotify\n- `moondog spotify login [client-id]` - 在浏览器里连接 Spotify\n- `moondog spotify now|devices|queue` - 查看 Spotify 正在放什么、在哪放、接下来是什么\n- `moondog spotify recent` - 查看你最近听了什么\n- `moondog spotify sync-recent` - 把最近的播放加入你的资料\n- `moondog spotify sync-library` - 把你的 Spotify 曲库加入你的资料\n- `moondog spotify play|pause|next|previous` - 控制 Spotify 播放\n- `moondog listenbrainz import-history <listen-history.json>` - 把 ListenBrainz 收听文件加入你的资料\n- `moondog catalog latest-single --artist <名字> [--known-release <标题> | --from <spotify-history.zip>]` - 在 Apple Music(美区)查找某位艺人的最新单曲,无需模型\n- `moondog status [--json]` - 查看当前状态\n- `moondog taste [--json]` - 你的聆听报告\n- `moondog taste --html [--output <文件.html>]` - 把报告保存为可离线打开的网页\n- `moondog taste --card [--output <文件.html>]` - 保存一份简短回顾,分享前可以先检查\n- `moondog taste --from <spotify-history.zip> --html` - 从一个 Spotify ZIP 生成一次性报告,不保存\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - 从两份 Spotify 导出一起生成一次性报告\n- `moondog taste --from <spotify-history.zip> --save --html` - 保存 Spotify 历史,然后显示完整报告\n- `moondog data inspect --scope <listening|apple|profile>` - 查看保存了什么,并获取重置所需的代码\n- `moondog data export --scope <listening|apple|profile> --output <目录>` - 导出一份副本,原件保持不变\n- `moondog data reset --scope <listening|apple|profile> --confirm <代码>` - 把保存的数据移到一边(归档,不删除)\n- `moondog profile build [--force]` - 用已连接的模型生成或继续生成保存的资料\n- `moondog profile saved [偏移]` - 阅读你保存的资料\n- `moondog profile explain <编号>` - 追溯一条已保存发现的证据\n- `moondog profile corrections [--all]` - 你告诉过我的所有选择,包括早先的\n- `moondog profile correct --artist <名字> (--like|--avoid)` - 标记喜欢某位艺人,或不再推荐\n- `moondog profile correct --track <歌名> --by <艺人> (--like|--avoid)` - 标记喜欢某首歌,或不再推荐\n- `moondog profile retract <correction-id>` - 撤销你的一项选择\n- `moondog demo --offline [--json]` - 用虚构数据的演示,无需登录\n- `moondog demo [提示] [--json]` - 同样的演示,通过你的模型对话\n- `moondog ask <提示>` - 问一个问题后退出\n- `moondog remember <内容>` - 让我记住一件事\n- `moondog forget <memory-id>` - 忘掉一件事\n- `moondog memory reflect [--dry-run] [--json]` - 让我现在回顾最近的对话\n- `moondog` - 打开聆听室\n\n在聆听室里:\n\n- `/update [--check] [--channel latest|beta]` - 检查更新,或保存并关闭本次会话来安装\n- `/status` 或 `/sources` - 查看当前状态\n- `/profile` 或 `/taste` - 你的资料,以及每首歌、每位艺人为什么在这里\n- `/taste report` - 一页看完整份报告\n- `/profile build [--force]` - 生成或继续生成保存的解读;Ctrl+C 会保留进度\n- `/profile saved [偏移]` - 阅读你保存的资料\n- `/profile explain <编号>` - 查看一条已保存发现的证据\n- `/profile corrections [--all]` - 你告诉过我的所有选择\n- `/profile correct --track \"<歌名>\" --by \"<艺人>\" (--like|--avoid)` - 标记喜欢某首歌,或不再推荐\n- `/profile correct --artist \"<名字>\" (--like|--avoid)` - 标记喜欢某位艺人,或不再推荐\n- `/profile retract <correction-id>` - 撤销一项选择\n- `/memory` - 我记住的内容\n- `/tools` - 我现在能做什么\n- `/doctor` - 检查你的设置\n- `/model` - 选择我用来对话的模型\n- `/model <provider> <model>` - 直接切换到某个模型\n- `/model refresh [provider]` - 更新公开的模型列表;保留当前选择\n- `/auth [provider]` - 登录模型服务商\n- `/web status|search|read` - 在公开音乐网站上查资料\n- `/import [路径]` - 导入你的历史、曲库或一个歌单\n- `/language` - 选择 Moondog 使用的语言\n- `/service [spotify|apple_music|netease]` - 选择我在哪里放音乐\n- `/spotify` - Spotify 命令\n- `/spotify login [client-id]` - 连接 Spotify\n- `/spotify now|devices|queue` - 查看正在放什么、在哪放、接下来是什么\n- `/spotify recent|sync-recent` - 查看或保存你最近的播放\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - 加入一个 Spotify ZIP,无需登录\n- `/skip` 或 `/stop` - 跳到下一首试听,或停止试听\n- `/reload` - 重新加载模型设置和登录\n- `/remember [类型] <内容>` - 让我记住一件事\n- `/forget <memory-id>` - 忘掉一件事\n- `/rewind` 或 Alt+R - 就地编辑之前的一条消息;之后的消息会被替换\n- `/branch` - 从这里在新对话中继续;这段对话会保留\n- `/rewind latest` - 编辑最近的一条消息\n- `/resume` - 继续一段保存的对话\n- `/resume <session-id>` - 直接打开某一段\n- `/new` - 重新开始;上一段会保存下来\n- `/quit` - 退出\n\n你输入的非命令内容,会发给你用 `/model` 选的模型,或 `MOONDOG_PROVIDER` 和 `MOONDOG_MODEL` 指定的模型。\n用 `/auth` 登录,或在环境变量里设置服务商的 API 密钥。`/auth openai` 可以用 ChatGPT 订阅登录,也可以填 API 密钥。\n资料准备好之后,我可以搜索你的曲库、解释我看到的内容,并和你一起规划歌单。\n只有在 `moondog spotify login` 之后我才能控制 Spotify,而且我从不发帖、不发消息、不删除任何东西,也不花钱。\n说出设备名,比如你的 iPhone,我就能把播放切过去。",
|
|
179
|
+
"# Every command\n\nFrom your shell:\n\n- `moondog --version` - show the installed version\n- `moondog update [--check] [--channel latest|beta]` - check for or install a published release\n- `moondog web status|search|read [arguments] [--json]` - look things up on public music sites through DeepSeek, Brave Search or the Codex CLI\n- `moondog demo-history --output <absolute-file.zip> [--json]` - make a fictional Spotify history ZIP to try the importer with\n- `moondog auth login <provider>` - sign in to a model provider; the key is typed out of sight; `openai --chatgpt` signs in with your ChatGPT subscription\n- `moondog auth status [provider]` - see which sign-ins are saved\n- `moondog auth logout <provider>` - sign out of a provider\n- `moondog spotify help` - set up and control Spotify\n- `moondog spotify login [client-id]` - connect Spotify in your browser\n- `moondog spotify now|devices|queue` - see what Spotify is playing, where, and what's next\n- `moondog spotify recent` - see what you played lately\n- `moondog spotify sync-recent` - add your latest plays to your profile\n- `moondog spotify sync-library` - add your Spotify library to your profile\n- `moondog spotify play|pause|next|previous` - control Spotify playback\n- `moondog listenbrainz import-history <listen-history.json>` - add a ListenBrainz listens file to your profile\n- `moondog catalog latest-single --artist <name> [--known-release <title> | --from <spotify-history.zip>]` - find an artist's latest single on Apple Music (US), no model needed\n- `moondog status [--json]` - see where things stand\n- `moondog taste [--json]` - your listening report\n- `moondog taste --html [--output <file.html>]` - save your report as a web page that works offline\n- `moondog taste --card [--output <file.html>]` - save a short recap you can check before sharing\n- `moondog taste --from <spotify-history.zip> --html` - a one-off report from a Spotify ZIP, without saving it\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - a one-off report from both Spotify exports together\n- `moondog taste --from <spotify-history.zip> --save --html` - save the Spotify history, then show your full report\n- `moondog data inspect --scope <listening|apple|profile>` - see what's stored, and get the code needed to reset it\n- `moondog data export --scope <listening|apple|profile> --output <directory>` - export a copy, leaving the original alone\n- `moondog data reset --scope <listening|apple|profile> --confirm <token>` - set stored data aside (it is archived, not deleted)\n- `moondog profile build [--force]` - build or resume a saved profile with your connected model\n- `moondog profile saved [offset]` - read your saved profile\n- `moondog profile explain <number>` - trace a saved finding to its evidence\n- `moondog profile corrections [--all]` - everything you've told me, including earlier choices\n- `moondog profile correct --artist <name> (--like|--avoid)` - like an artist, or keep them out\n- `moondog profile correct --track <title> --by <artist> (--like|--avoid)` - like a track, or keep it out\n- `moondog profile retract <correction-id>` - undo one of your choices\n- `moondog demo --offline [--json]` - a demo with made-up data, no sign-in needed\n- `moondog demo [prompt] [--json]` - the same demo, talking through your model\n- `moondog ask <prompt>` - ask one question and exit\n- `moondog remember <text>` - ask me to remember something\n- `moondog forget <memory-id>` - forget something\n- `moondog memory reflect [--dry-run] [--json]` - let me think over recent conversations now\n- `moondog` - open the listening room\n\nInside the listening room:\n\n- `/update [--check] [--channel latest|beta]` - check for updates, or save and close this session to install one\n- `/status` or `/sources` - see where things stand\n- `/profile` or `/taste` - your profile, and why each song or artist is there\n- `/taste report` - the whole report on one page\n- `/profile build [--force]` - build or resume a saved reading; Ctrl+C keeps progress\n- `/profile saved [offset]` - read your saved profile\n- `/profile explain <number>` - inspect a saved finding's evidence\n- `/profile corrections [--all]` - everything you've told me\n- `/profile correct --track \"<title>\" --by \"<artist>\" (--like|--avoid)` - like a track, or keep it out\n- `/profile correct --artist \"<name>\" (--like|--avoid)` - like an artist, or keep them out\n- `/profile retract <correction-id>` - undo a choice\n- `/memory` - what I remember\n- `/tools` - what I can do right now\n- `/doctor` - check your setup\n- `/model` - pick the model I talk through\n- `/model <provider> <model>` - switch straight to a model\n- `/model refresh [provider]` - update public model choices; keep the selected model\n- `/model roles` - see what side tasks use: the model that reads images and the web search service\n- `/model vision auto|<provider> <model>` - choose the model that reads images\n- `/model web auto|deepseek|brave|codex` - choose the web search service\n- `/effort` - choose how hard the model thinks\n- `/auth [provider]` - sign in to a model provider\n- `/endpoint add` or `/endpoint remove <id>` - add a model service by its address, or remove it\n- `/web status|search|read` - look things up on public music sites\n- `/import [path]` - bring in your history, library, or a playlist\n- `/library` - your saved songs and playlists\n- `/library play <name>` - play a playlist\n- `/library save [playlist]` - keep the song playing now\n- `/library import <link>` - copy a playlist from a link\n- `/generation on|off` - let Moondog make music on this Mac, or stop\n- `/generation download|use|remove|cancel` - set up a Stable Audio 3 model\n- `/onair` - go on air, or come off it\n- `/language` - choose the language Moondog uses\n- `/service [spotify|apple_music|netease]` - choose where I play music\n- `/spotify` - Spotify commands\n- `/spotify login [client-id]` - connect Spotify\n- `/spotify now|devices|queue` - see what's playing, where, and what's next\n- `/spotify recent|sync-recent` - see or save your latest plays\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - add a Spotify ZIP, no sign-in needed\n- `/skip` or `/stop` - move to the next song preview or stream track, or stop them\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/reload` - reload model settings and sign-ins\n- `/remember [kind] <text>` - ask me to remember something\n- `/forget <memory-id>` - forget something\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/rewind latest` - edit the most recent message\n- `/resume` - pick up a saved conversation\n- `/resume <session-id>` - go straight to one\n- `/new` - start fresh; the last one stays saved\n- `/quit` - exit\n\nAnything you type that isn't a command goes to the model you picked with `/model`, or the one set in `MOONDOG_PROVIDER` and `MOONDOG_MODEL`.\nSign in with `/auth`, or set the provider's API key in your environment. `/auth openai` signs in with your ChatGPT subscription or an API key.\nOnce your profile is ready, I can search your library, explain what I see, and plan playlists with you.\nI can only control Spotify after `moondog spotify login`. I ask before I remove anything from your library, and I never post, send messages, or spend money.\nAsk me to move playback onto a device by name, such as your iPhone.": "# 全部命令\n\n在终端里:\n\n- `moondog --version` - 显示已安装的版本\n- `moondog update [--check] [--channel latest|beta]` - 检查或安装已发布的版本\n- `moondog web status|search|read [参数] [--json]` - 通过 DeepSeek、Brave Search 或 Codex CLI 在公开音乐网站上查资料\n- `moondog demo-history --output <绝对路径.zip> [--json]` - 生成一个虚构的 Spotify 历史 ZIP,用来试用导入\n- `moondog auth login <provider>` - 登录模型服务商;密钥输入时不显示,`openai --chatgpt` 用你的 ChatGPT 订阅登录\n- `moondog auth status [provider]` - 查看保存了哪些登录\n- `moondog auth logout <provider>` - 退出某个服务商\n- `moondog spotify help` - 设置并控制 Spotify\n- `moondog spotify login [client-id]` - 在浏览器里连接 Spotify\n- `moondog spotify now|devices|queue` - 查看 Spotify 正在放什么、在哪放、接下来是什么\n- `moondog spotify recent` - 查看你最近听了什么\n- `moondog spotify sync-recent` - 把最近的播放加入你的资料\n- `moondog spotify sync-library` - 把你的 Spotify 曲库加入你的资料\n- `moondog spotify play|pause|next|previous` - 控制 Spotify 播放\n- `moondog listenbrainz import-history <listen-history.json>` - 把 ListenBrainz 收听文件加入你的资料\n- `moondog catalog latest-single --artist <名字> [--known-release <标题> | --from <spotify-history.zip>]` - 在 Apple Music(美区)查找某位艺人的最新单曲,无需模型\n- `moondog status [--json]` - 查看当前状态\n- `moondog taste [--json]` - 你的聆听报告\n- `moondog taste --html [--output <文件.html>]` - 把报告保存为可离线打开的网页\n- `moondog taste --card [--output <文件.html>]` - 保存一份简短回顾,分享前可以先检查\n- `moondog taste --from <spotify-history.zip> --html` - 从一个 Spotify ZIP 生成一次性报告,不保存\n- `moondog taste --from <account-data.zip> --from <extended-history.zip> --html` - 从两份 Spotify 导出一起生成一次性报告\n- `moondog taste --from <spotify-history.zip> --save --html` - 保存 Spotify 历史,然后显示完整报告\n- `moondog data inspect --scope <listening|apple|profile>` - 查看保存了什么,并获取重置所需的代码\n- `moondog data export --scope <listening|apple|profile> --output <目录>` - 导出一份副本,原件保持不变\n- `moondog data reset --scope <listening|apple|profile> --confirm <代码>` - 把保存的数据移到一边(归档,不删除)\n- `moondog profile build [--force]` - 用已连接的模型生成或继续生成保存的资料\n- `moondog profile saved [偏移]` - 阅读你保存的资料\n- `moondog profile explain <编号>` - 追溯一条已保存发现的证据\n- `moondog profile corrections [--all]` - 你告诉过我的所有选择,包括早先的\n- `moondog profile correct --artist <名字> (--like|--avoid)` - 标记喜欢某位艺人,或不再推荐\n- `moondog profile correct --track <歌名> --by <艺人> (--like|--avoid)` - 标记喜欢某首歌,或不再推荐\n- `moondog profile retract <correction-id>` - 撤销你的一项选择\n- `moondog demo --offline [--json]` - 用虚构数据的演示,无需登录\n- `moondog demo [提示] [--json]` - 同样的演示,通过你的模型对话\n- `moondog ask <提示>` - 问一个问题后退出\n- `moondog remember <内容>` - 让我记住一件事\n- `moondog forget <memory-id>` - 忘掉一件事\n- `moondog memory reflect [--dry-run] [--json]` - 让我现在回顾最近的对话\n- `moondog` - 打开聆听室\n\n在聆听室里:\n\n- `/update [--check] [--channel latest|beta]` - 检查更新,或保存并关闭本次会话来安装\n- `/status` 或 `/sources` - 查看当前状态\n- `/profile` 或 `/taste` - 你的资料,以及每首歌、每位艺人为什么在这里\n- `/taste report` - 一页看完整份报告\n- `/profile build [--force]` - 生成或继续生成保存的解读;Ctrl+C 会保留进度\n- `/profile saved [偏移]` - 阅读你保存的资料\n- `/profile explain <编号>` - 查看一条已保存发现的证据\n- `/profile corrections [--all]` - 你告诉过我的所有选择\n- `/profile correct --track \"<歌名>\" --by \"<艺人>\" (--like|--avoid)` - 标记喜欢某首歌,或不再推荐\n- `/profile correct --artist \"<名字>\" (--like|--avoid)` - 标记喜欢某位艺人,或不再推荐\n- `/profile retract <correction-id>` - 撤销一项选择\n- `/memory` - 我记住的内容\n- `/tools` - 我现在能做什么\n- `/doctor` - 检查你的设置\n- `/model` - 选择我用来对话的模型\n- `/model <provider> <model>` - 直接切换到某个模型\n- `/model refresh [provider]` - 更新公开的模型列表;保留当前选择\n- `/model roles` - 看看副任务在用什么:读图的模型和网页搜索服务\n- `/model vision auto|<provider> <model>` - 选择读图的模型\n- `/model web auto|deepseek|brave|codex` - 选择网页搜索服务\n- `/effort` - 选择模型思考的程度\n- `/auth [provider]` - 登录模型服务商\n- `/endpoint add` 或 `/endpoint remove <id>` - 按地址添加模型服务,或移除它\n- `/web status|search|read` - 在公开音乐网站上查资料\n- `/import [路径]` - 导入你的历史、曲库或一个歌单\n- `/library` - 你收藏的歌和播放列表\n- `/library play <名称>` - 播放一个播放列表\n- `/library save [播放列表]` - 收藏正在放的歌\n- `/library import <链接>` - 从链接复制一个播放列表\n- `/generation on|off` - 让 Moondog 在这台 Mac 上做音乐,或停下\n- `/generation download|use|remove|cancel` - 设置 Stable Audio 3 模型\n- `/onair` - 开播,或下播\n- `/language` - 选择 Moondog 使用的语言\n- `/service [spotify|apple_music|netease]` - 选择我在哪里放音乐\n- `/spotify` - Spotify 命令\n- `/spotify login [client-id]` - 连接 Spotify\n- `/spotify now|devices|queue` - 查看正在放什么、在哪放、接下来是什么\n- `/spotify recent|sync-recent` - 查看或保存你最近的播放\n- `/spotify import-history \"/path/to/spotify-history.zip\"` - 加入一个 Spotify ZIP,无需登录\n- `/skip` 或 `/stop` - 跳到下一首试听或直播曲目,或停止它们\n- `/home` - 回到唱片封套;对话还在\n- `/theme paper|charcoal|terminal|auto` - 换外观\n- `/art braille|ascii|off` - 换插画\n- `/motion on|off` - 打开或关闭动画\n- `/lyrics` - 封套上的歌词;`/lyrics sync` 找更多\n- `/reload` - 重新加载模型设置和登录\n- `/remember [类型] <内容>` - 让我记住一件事\n- `/forget <memory-id>` - 忘掉一件事\n- `/rewind` 或 Alt+R - 就地编辑之前的一条消息;之后的消息会被替换\n- `/branch` - 从这里在新对话中继续;这段对话会保留\n- `/rewind latest` - 编辑最近的一条消息\n- `/resume` - 继续一段保存的对话\n- `/resume <session-id>` - 直接打开某一段\n- `/new` - 重新开始;上一段会保存下来\n- `/quit` - 退出\n\n你输入的非命令内容,会发给你用 `/model` 选的模型,或 `MOONDOG_PROVIDER` 和 `MOONDOG_MODEL` 指定的模型。\n用 `/auth` 登录,或在环境变量里设置服务商的 API 密钥。`/auth openai` 可以用 ChatGPT 订阅登录,也可以填 API 密钥。\n资料准备好之后,我可以搜索你的曲库、解释我看到的内容,并和你一起规划歌单。\n只有在 `moondog spotify login` 之后我才能控制 Spotify。从你的曲库移除东西之前我会先问你,而且我从不发帖、不发消息,也不花钱。\n说出设备名,比如你的 iPhone,我就能把播放切过去。",
|
|
180
180
|
"Apple Music library": "Apple Music 曲库",
|
|
181
181
|
"Model": "模型",
|
|
182
182
|
"Finding similar music": "查找相似的音乐",
|
|
@@ -817,8 +817,8 @@ export default {
|
|
|
817
817
|
"Choose the model Moondog talks through": "选择 Moondog 对话使用的模型",
|
|
818
818
|
"Look things up on public music sites": "在公开音乐网站上查资料",
|
|
819
819
|
"Connect and control Spotify": "连接并控制 Spotify",
|
|
820
|
-
"Skip to the next song preview": "
|
|
821
|
-
"Stop the song previews": "
|
|
820
|
+
"Skip to the next song preview or stream track": "跳到下一首试听或直播曲目",
|
|
821
|
+
"Stop the song previews or the stream": "停止试听或直播",
|
|
822
822
|
"Reload model settings and sign-ins": "重新加载模型设置和登录",
|
|
823
823
|
"Ask Moondog to remember something": "让 Moondog 记住一件事",
|
|
824
824
|
"Forget one memory by ID": "按 ID 忘掉一条记忆",
|
|
@@ -979,6 +979,17 @@ export default {
|
|
|
979
979
|
"Saved the {service} key. Web search goes through {provider}.": "已保存 {service} 密钥。网页搜索使用 {provider}。",
|
|
980
980
|
"Saved the {service} key, but web search still isn't ready. Run `/web status` to see why.": "已保存 {service} 密钥,但网页搜索还不能用。运行 `/web status` 查看原因。",
|
|
981
981
|
"Add an endpoint by its address": "按地址添加接口",
|
|
982
|
+
"See what side tasks use": "看看副任务在用什么",
|
|
983
|
+
"Choose the model that reads images": "选择读图的模型",
|
|
984
|
+
"Choose the web search service": "选择网页搜索服务",
|
|
985
|
+
"Let the chat model read images when it can": "让聊天模型在能读图时直接读",
|
|
986
|
+
"Take the first service that is set up": "用第一个已设置的服务",
|
|
987
|
+
"Search with DeepSeek": "用 DeepSeek 搜索",
|
|
988
|
+
"Search with Brave Search": "用 Brave Search 搜索",
|
|
989
|
+
"Search with the Codex CLI": "用 Codex CLI 搜索",
|
|
990
|
+
"Play a playlist by name": "按名称播放一个播放列表",
|
|
991
|
+
"Keep the song playing now": "收藏正在放的歌",
|
|
992
|
+
"Copy a playlist from a link": "从链接复制一个播放列表",
|
|
982
993
|
"Remove an endpoint and its key": "移除接口和它的密钥",
|
|
983
994
|
"ChatGPT sign-in or API key": "ChatGPT 登录或 API 密钥",
|
|
984
995
|
"ChatGPT subscription": "ChatGPT 订阅",
|
|
@@ -1136,6 +1147,7 @@ export default {
|
|
|
1136
1147
|
"Your saved songs and playlists": "你收藏的歌和播放列表",
|
|
1137
1148
|
"Look in the library": "翻翻资料库",
|
|
1138
1149
|
"Save to the library": "收进资料库",
|
|
1150
|
+
"Change a playlist": "修改播放列表",
|
|
1139
1151
|
"Play from the library": "播放资料库里的歌",
|
|
1140
1152
|
"Paste a playlist link after /library import.": "在 /library import 后面粘贴歌单链接。",
|
|
1141
1153
|
"Reading the playlist…": "正在读取歌单…",
|
|
@@ -55,7 +55,8 @@ const text = (value, maximum = 200) => (typeof value === "string" ? Array.from(v
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* An Apple Music playlist from its public page: its name, how many songs it has, and the songs the page
|
|
58
|
-
* lists with their Apple Music ids and covers
|
|
58
|
+
* lists with their Apple Music ids and covers, and the playlist's own square cover (the page's og:image is a
|
|
59
|
+
* wide share card). A long playlist's page may list only its first songs;
|
|
59
60
|
* read and total say how many.
|
|
60
61
|
*/
|
|
61
62
|
export async function readApplePlaylist({ id, url }, { fetchImpl = fetch, signal } = {}) {
|
|
@@ -65,27 +66,38 @@ export async function readApplePlaylist({ id, url }, { fetchImpl = fetch, signal
|
|
|
65
66
|
const data = block(/<script[^>]*id="serialized-server-data"[^>]*>([\s\S]*?)<\/script>/u);
|
|
66
67
|
const tracks = [];
|
|
67
68
|
const seen = new Set();
|
|
69
|
+
const artworkAt = (node, size) => {
|
|
70
|
+
const url = node.artwork?.dictionary?.url;
|
|
71
|
+
return typeof url === "string" && url.startsWith("https://") ? url.replace("{w}x{h}", `${size}x${size}`).replace("{c}", "").replace("{f}", "jpg") : null;
|
|
72
|
+
};
|
|
73
|
+
// The playlist's own entry in the server data. A listener's own playlist has no schema block, and its og:title
|
|
74
|
+
// reads "Name by Listener on Apple Music", so this entry's title and count come first.
|
|
75
|
+
let own = null;
|
|
76
|
+
let cover = null;
|
|
68
77
|
// The server data lists each song as a track lockup with its title, its artist and its catalog id.
|
|
69
78
|
const walk = (node, depth) => {
|
|
70
79
|
if (!node || typeof node !== "object" || depth > 12 || tracks.length >= 2000) return;
|
|
71
80
|
if (Array.isArray(node)) { for (const each of node) walk(each, depth + 1); return; }
|
|
72
81
|
const catalog = node.contentDescriptor?.identifiers?.storeAdamID;
|
|
82
|
+
// The page's intent carries the same id with no title or artwork, and comes first.
|
|
83
|
+
if (!own && node.contentDescriptor?.kind === "playlist" && catalog === id && typeof node.title === "string") { own = node; cover = artworkAt(node, 600); }
|
|
73
84
|
if (typeof node.title === "string" && typeof node.artistName === "string" && node.contentDescriptor?.kind === "song" && catalog) {
|
|
74
85
|
const key = String(catalog);
|
|
75
86
|
if (!seen.has(key)) {
|
|
76
87
|
seen.add(key);
|
|
77
|
-
const artwork =
|
|
78
|
-
tracks.push({ id: key, title: text(node.title), artist: text(node.artistName), ...(artwork
|
|
88
|
+
const artwork = artworkAt(node, 300);
|
|
89
|
+
tracks.push({ id: key, title: text(node.title), artist: text(node.artistName), ...(artwork ? { artwork } : {}) });
|
|
79
90
|
}
|
|
80
91
|
return;
|
|
81
92
|
}
|
|
82
93
|
for (const value of Object.values(node)) walk(value, depth + 1);
|
|
83
94
|
};
|
|
84
95
|
walk(data, 0);
|
|
85
|
-
const name = text(schema?.name) || text(/<meta property="og:title" content="([^"]+)"/u.exec(html)?.[1]) || "Apple Music playlist";
|
|
86
|
-
const
|
|
96
|
+
const name = text(own?.title) || text(schema?.name) || text(/<meta property="og:title" content="([^"]+)"/u.exec(html)?.[1]) || "Apple Music playlist";
|
|
97
|
+
const count = schema?.numTracks ?? own?.trackCount;
|
|
98
|
+
const total = count !== null && count !== undefined && Number.isSafeInteger(Number(count)) ? Number(count) : null;
|
|
87
99
|
if (!tracks.length) fail("playlist_unavailable", "Apple Music didn't list the songs of this playlist. Check that it is shared publicly.");
|
|
88
|
-
return { provider: "apple_music", id, url, name, total: total !== null && total >= tracks.length ? total : null, tracks: tracks.filter((track) => track.title && track.artist) };
|
|
100
|
+
return { provider: "apple_music", id, url, name, ...(cover ? { cover } : {}), total: total !== null && total >= tracks.length ? total : null, tracks: tracks.filter((track) => track.title && track.artist) };
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
/** A NetEase Music or QQ Music playlist through its public share link, as library songs. */
|
|
@@ -97,6 +109,6 @@ export async function readPublicPlaylistLink({ url }, { fetchImpl = fetch } = {}
|
|
|
97
109
|
if (!error.code) error.code = /^Could not reach/u.test(error.message) ? "playlist_unreachable" : aboutLink.test(error.message) ? "playlist_link_unsupported" : "playlist_unavailable";
|
|
98
110
|
throw error;
|
|
99
111
|
});
|
|
100
|
-
return { provider: playlist.provider, id: playlist.id, url: playlist.url, name: playlist.name, total: playlist.total,
|
|
112
|
+
return { provider: playlist.provider, id: playlist.id, url: playlist.url, name: playlist.name, total: playlist.total, ...(playlist.cover ? { cover: playlist.cover } : {}),
|
|
101
113
|
tracks: playlist.rows.map((row) => ({ id: row.id, title: row.title, artist: row.artist, ...(row.album ? { album: row.album } : {}), ...(row.artwork ? { artwork: row.artwork } : {}) })).filter((track) => track.artist) };
|
|
102
114
|
}
|
|
@@ -74,7 +74,7 @@ async function neteasePlaylist(id, fetchImpl) {
|
|
|
74
74
|
const detail = await boundedJson(await responseFor(`https://music.163.com/api/song/detail/?ids=${encodeURIComponent(`[${batch.join(",")}]`)}`, fetchImpl, referer));
|
|
75
75
|
for (const song of Array.isArray(detail?.songs) ? detail.songs : []) songs.set(String(song?.id ?? ""), song);
|
|
76
76
|
}
|
|
77
|
-
return { code: 200, result: { id: playlist.id, name: playlist.name, privacy: playlist.privacy, trackCount: playlist.trackCount ?? ids.length,
|
|
77
|
+
return { code: 200, result: { id: playlist.id, name: playlist.name, coverImgUrl: playlist.coverImgUrl, privacy: playlist.privacy, trackCount: playlist.trackCount ?? ids.length,
|
|
78
78
|
tracks: ids.map((songId) => songs.get(songId)).filter(Boolean) } };
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -119,7 +119,9 @@ export async function fetchPublicPlaylist({ input, provider, fetchImpl = fetch }
|
|
|
119
119
|
playlistId: identity.id, playlistName: name, position: index + 1, member: "public-playlist.json",
|
|
120
120
|
};
|
|
121
121
|
}).filter((row) => row.id && row.title);
|
|
122
|
-
|
|
122
|
+
// NetEase's own image host, shown over https, as a song's cover is.
|
|
123
|
+
const cover = !qq && /^https?:\/\/p[0-9]+\.music\.126\.net\//u.test(playlist.coverImgUrl ?? "") ? playlist.coverImgUrl.replace(/^http:/u, "https:") : null;
|
|
124
|
+
return { provider: identity.provider, id: identity.id, url: url.href, name, total, rows, skipped: songs.length - rows.length, ...(cover ? { cover } : {}) };
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
export async function readPublicPlaylist({ input, subjectId, capturedAt, provider, fetchImpl = fetch }) {
|
|
@@ -905,10 +905,15 @@ export function createSpotifyService(options = {}) {
|
|
|
905
905
|
if (!playlist) fail("spotify_playlist_unavailable", "Spotify did not describe this playlist.");
|
|
906
906
|
const page = await client.getPlaylistItems({ playlistId, limit: SPOTIFY_SERVICE_LIMITS.playlistItemsPageMax, offset: 0 }, { signal })
|
|
907
907
|
.catch((error) => (signal?.aborted ? Promise.reject(error) : null));
|
|
908
|
-
return { name: playlist.name, uri: playlist.uri, tracks_total: playlist.tracks_total ?? null,
|
|
908
|
+
return { name: playlist.name, uri: playlist.uri, tracks_total: playlist.tracks_total ?? null, ...(playlist.image ? { image: playlist.image } : {}),
|
|
909
909
|
tracks: page ? page.items.map((entry) => entry.item).filter(Boolean) : null };
|
|
910
910
|
},
|
|
911
911
|
|
|
912
|
+
// Only a playlist's cover, for one imported before Moondog kept it.
|
|
913
|
+
async readPlaylistCover({ playlistId } = {}, { signal } = {}) {
|
|
914
|
+
return (await client.getPlaylist({ playlistId: requiredPlaylistId(String(playlistId ?? "")) }, { signal }))?.image ?? null;
|
|
915
|
+
},
|
|
916
|
+
|
|
912
917
|
// A whole playlist for the listener's library: its name, whether the signed-in listener owns it, and its
|
|
913
918
|
// songs page by page, up to 2,000. Spotify's own editorial playlists answer most apps with not found.
|
|
914
919
|
async readPlaylist({ playlistId } = {}, { signal } = {}) {
|
|
@@ -160,14 +160,18 @@ function normalizeArtistNames(rawArtists) {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
// Cover art a window can draw: one Spotify CDN image, the largest that is at most 640 pixels.
|
|
163
|
-
function coverImage(images) {
|
|
163
|
+
function coverImage(images, allowed = /^https:\/\/i\.scdn\.co\/image\/[A-Za-z0-9_-]{1,128}$/u) {
|
|
164
164
|
const usable = (Array.isArray(images) ? images : []).filter((image) =>
|
|
165
|
-
typeof image?.url === "string" &&
|
|
165
|
+
typeof image?.url === "string" && allowed.test(image.url));
|
|
166
166
|
const sized = usable.filter((image) => !Number.isInteger(image.width) || image.width <= 640)
|
|
167
167
|
.sort((left, right) => (right.width ?? 0) - (left.width ?? 0));
|
|
168
168
|
return (sized[0] ?? usable.at(-1))?.url;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
// A playlist's cover lives on more hosts than an album's: one a listener uploaded on image-cdn-*.spotifycdn.com, the
|
|
172
|
+
// four-album mosaic on mosaic.scdn.co. The window's image policy (renderer/index.html) names the same two domains.
|
|
173
|
+
const PLAYLIST_COVER = /^https:\/\/[a-z0-9-]{1,40}\.(?:scdn\.co|spotifycdn\.com)\/[A-Za-z0-9_/-]{1,200}$/u;
|
|
174
|
+
|
|
171
175
|
// A track's album, kept so a song played alone can go on into the rest of its album.
|
|
172
176
|
// Hosts keep it next to the track URI and never show it to the model.
|
|
173
177
|
function albumUri(raw) {
|
|
@@ -462,6 +466,8 @@ function normalizePlaylist(payload, { includeControlMetadata = false } = {}) {
|
|
|
462
466
|
const snapshotId = safeText(payload.snapshot_id, 128);
|
|
463
467
|
if (ownerId) playlist.owner_id = ownerId;
|
|
464
468
|
if (snapshotId) playlist.snapshot_id = snapshotId;
|
|
469
|
+
const cover = coverImage(payload.images, PLAYLIST_COVER);
|
|
470
|
+
if (cover) playlist.image = cover;
|
|
465
471
|
}
|
|
466
472
|
const tracksTotal = safeInteger(
|
|
467
473
|
payload.items?.total ?? payload.tracks?.total,
|
|
@@ -6615,11 +6615,12 @@ function createToolFactories(
|
|
|
6615
6615
|
name: descriptor.tool_name,
|
|
6616
6616
|
label: descriptor.label,
|
|
6617
6617
|
description:
|
|
6618
|
-
"Find playlists in the listener's own library on this Mac by words of their name, or list the newest ones without words. Saved is the built-in playlist of single songs and made tracks they kept. Each playlist says how many entries it holds and how many of them Moondog made. With playlist_id, it reads that playlist's entries in order.",
|
|
6618
|
+
"Find playlists in the listener's own library on this Mac by words of their name, or list the newest ones without words. Saved is the built-in playlist of single songs and made tracks they kept. Each playlist says how many entries it holds and how many of them Moondog made. With playlist_id, it reads that playlist's entries in order, 200 at a time; offset reads on.",
|
|
6619
6619
|
parameters: Type.Object(
|
|
6620
6620
|
{
|
|
6621
6621
|
query: Type.Optional(Type.String({ maxLength: 120 })),
|
|
6622
6622
|
playlist_id: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),
|
|
6623
|
+
offset: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
6623
6624
|
},
|
|
6624
6625
|
{ additionalProperties: false },
|
|
6625
6626
|
),
|
|
@@ -6629,8 +6630,8 @@ function createToolFactories(
|
|
|
6629
6630
|
const playlist = await application.libraryPlaylist(parameters.playlist_id);
|
|
6630
6631
|
if (!playlist) throw Object.assign(new Error("That playlist is not in the library."), { code: "library_playlist_not_found" });
|
|
6631
6632
|
return { playlist: { id: playlist.id, name: playlist.saved ? "Saved" : playlist.name, origin: playlist.origin,
|
|
6632
|
-
entries: playlist.entries.slice(0,
|
|
6633
|
-
total: playlist.entries.length } };
|
|
6633
|
+
entries: playlist.entries.slice(parameters.offset ?? 0, (parameters.offset ?? 0) + 200).map((entry) => ({ title: entry.title, artist: entry.artist_credit, ...(entry.kind === "made" ? { made_by_moondog: true } : {}) })),
|
|
6634
|
+
offset: parameters.offset ?? 0, total: playlist.entries.length } };
|
|
6634
6635
|
}
|
|
6635
6636
|
return { playlists: application.findLibraryPlaylists(parameters.query ?? "") };
|
|
6636
6637
|
},
|
|
@@ -6675,6 +6676,31 @@ function createToolFactories(
|
|
|
6675
6676
|
),
|
|
6676
6677
|
}),
|
|
6677
6678
|
],
|
|
6679
|
+
[
|
|
6680
|
+
"collection.edit",
|
|
6681
|
+
(descriptor) => ({
|
|
6682
|
+
name: descriptor.tool_name,
|
|
6683
|
+
label: descriptor.label,
|
|
6684
|
+
description:
|
|
6685
|
+
"Change one of the listener's own playlists on this Mac, only when they ask: name renames it, remove takes songs out, move puts songs before another song (before), or at the end without it, in the order given. To reorder a whole playlist, move every song in the new order. Songs go by title as listed; give the artist when two share a title. To add songs use moondog_collection_save. Say what changed; not_found names songs it did not find.",
|
|
6686
|
+
parameters: Type.Object(
|
|
6687
|
+
{
|
|
6688
|
+
playlist_id: Type.String({ minLength: 1, maxLength: 128 }),
|
|
6689
|
+
name: Type.Optional(Type.String({ minLength: 1, maxLength: 120 })),
|
|
6690
|
+
remove: Type.Optional(Type.Array(LIBRARY_SONG, { minItems: 1, maxItems: 200 })),
|
|
6691
|
+
move: Type.Optional(Type.Array(LIBRARY_SONG, { minItems: 1, maxItems: 200 })),
|
|
6692
|
+
before: Type.Optional(LIBRARY_SONG),
|
|
6693
|
+
},
|
|
6694
|
+
{ additionalProperties: false },
|
|
6695
|
+
),
|
|
6696
|
+
executionMode: "sequential",
|
|
6697
|
+
execute: executeDomain(
|
|
6698
|
+
async (_toolCallId, parameters) => application.editLibraryPlaylist({ playlistId: parameters.playlist_id, name: parameters.name,
|
|
6699
|
+
remove: parameters.remove, move: parameters.move, before: parameters.before }),
|
|
6700
|
+
(value) => structuredClone(value),
|
|
6701
|
+
),
|
|
6702
|
+
}),
|
|
6703
|
+
],
|
|
6678
6704
|
[
|
|
6679
6705
|
"collection.import",
|
|
6680
6706
|
(descriptor) => ({
|
|
@@ -6891,6 +6917,11 @@ const isOnAirRequest = (text) => {
|
|
|
6891
6917
|
};
|
|
6892
6918
|
const ON_AIR_NOTE = "The listener pressed On Air. Answer this message by starting Moondog's stream with moondog_start_stream: instrumental tracks made on this Mac from their taste and the moment, one after another, with a broad set of descriptors as that tool asks. Do not search, play or queue catalog music for it. If making music isn't available here, say so in one sentence.";
|
|
6893
6919
|
|
|
6920
|
+
const LIBRARY_SONG = Type.Object({
|
|
6921
|
+
title: Type.String({ minLength: 1, maxLength: 200 }),
|
|
6922
|
+
artist: Type.Optional(Type.String({ maxLength: 200 })),
|
|
6923
|
+
}, { additionalProperties: false });
|
|
6924
|
+
|
|
6894
6925
|
function sessionSection(application) {
|
|
6895
6926
|
return sessionAvailability({
|
|
6896
6927
|
spotifyReady: application.spotifyReady?.() ?? false,
|
|
@@ -6942,7 +6973,7 @@ Public web research rules:
|
|
|
6942
6973
|
|
|
6943
6974
|
Grounding and evidence rules:
|
|
6944
6975
|
- Before naming or selecting tracks as present in the user's library, call moondog_library_search.
|
|
6945
|
-
- The listener's collection in Moondog (Saved and their own playlists, which can hold songs and tracks Moondog made) is separate from their imported library and from Spotify. When they ask to save, keep, collect or like music (收藏, 存下来) without naming Spotify, use moondog_collection_save; use moondog_spotify_library_save only when they name Spotify or Liked Songs. To play one of their playlists, find it with moondog_collection_list and play it with moondog_collection_play. When they paste a playlist link and ask to import or add it, use moondog_collection_import.
|
|
6976
|
+
- The listener's collection in Moondog (Saved and their own playlists, which can hold songs and tracks Moondog made) is separate from their imported library and from Spotify. When they ask to save, keep, collect or like music (收藏, 存下来) without naming Spotify, use moondog_collection_save; use moondog_spotify_library_save only when they name Spotify or Liked Songs. To play one of their playlists, find it with moondog_collection_list and play it with moondog_collection_play. To rename one, take songs out or reorder it, use moondog_collection_edit. When they paste a playlist link and ask to import or add it, use moondog_collection_import.
|
|
6946
6977
|
- When personalization matters, call moondog_profile_summary instead of assuming a profile.
|
|
6947
6978
|
- Before saying how often, when, or whether the listener played something, check the listening coverage. Plays inside a gap, outside every source's span, or after recent_plays_checked_at are unknown, not zero. When a gap could hold the plays in question, lead with that boundary, for example "I have no records from August 30 to October 21", and do not conclude that the listener rarely plays it or only just found it.
|
|
6948
6979
|
- The saved reading is enduring taste up to its listening date. Recent attention is the present: stored plays from the last four weeks, and Spotify's four-week top artists, which count listening on every device, including plays Moondog never stored and songs Moondog itself played or queued; stored plays count those apart as moondog_started_plays. When they disagree about what the listener plays lately, trust recent attention, and say which one you read.
|
|
@@ -8118,7 +8149,7 @@ export class PiAgentRuntime {
|
|
|
8118
8149
|
// A finished reply keeps only its text, so the transcript, not this agent, says what was declared.
|
|
8119
8150
|
#sessionUpdate(messages) {
|
|
8120
8151
|
// An On Air reply carries the host's note in its session section; the next reply drops it again.
|
|
8121
|
-
const session = [sessionSection(this.application), this.onAirTurn ? ON_AIR_NOTE : null].filter(Boolean).join("\n\n") || null;
|
|
8152
|
+
const session = [sessionSection(this.application), this.onAirTurn ? ON_AIR_NOTE : null, this.libraryNote].filter(Boolean).join("\n\n") || null;
|
|
8122
8153
|
if ((getCurrentSystemMessage(messages)?.sections?.session ?? null) === session) return [];
|
|
8123
8154
|
return [{ role: "system", content: "", sections: { session }, timestamp: Date.now() }];
|
|
8124
8155
|
}
|
|
@@ -8179,6 +8210,8 @@ export class PiAgentRuntime {
|
|
|
8179
8210
|
this.#refreshSurface();
|
|
8180
8211
|
this.loopSurfaceVersion = this.surfaceVersion;
|
|
8181
8212
|
this.onAirTurn = isOnAirRequest(text);
|
|
8213
|
+
// What this conversation's messages name with @, read fresh for this reply.
|
|
8214
|
+
this.libraryNote = this.application?.libraryMentionNote?.([...this.agent.state.messages.filter((message) => message.role === "user").map(extractMessageText), text]) ?? null;
|
|
8182
8215
|
const sessionUpdate = this.#sessionUpdate(this.agent.state.messages);
|
|
8183
8216
|
if (sessionUpdate.length) this.agent.state.messages = [...this.agent.state.messages, ...sessionUpdate];
|
|
8184
8217
|
const historyStartIndex = this.agent.state.messages.length;
|
|
@@ -564,5 +564,5 @@ function wrapDescription(text, width) {
|
|
|
564
564
|
}
|
|
565
565
|
|
|
566
566
|
export function listeningHelp() {
|
|
567
|
-
return tr("# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.");
|
|
567
|
+
return tr("# Your listening room\n\n## 01 / Listen and discover\n\nJust type to talk about music, ask for a playlist, or go exploring.\nTo talk, Moondog needs a model: `/auth` signs you in, then `/model` picks one.\nWhile an answer is coming, each step shows in the conversation, and the footer names the one in progress.\n\n- `/taste` - your profile: open any song or artist to see why it's there\n- `/taste report` - the whole picture on one page\n- `/import` - bring in your history, your library, or a playlist\n- `/library` - your saved songs and playlists\n- `/generation on|off` - let Moondog make music on this Mac, or stop\n- `/onair` - go on air, or come off it\n- `/lyrics` - the lyrics on the sleeve; `/lyrics sync` finds more\n- `/service` - choose where I play music: Spotify, Apple Music, or NetEase\n- `/spotify` - play, queue, and make playlists in Spotify\n- Ask to move playback onto your iPhone, computer, or another Spotify device by name\n- `/web search <query>` or `/web read <url>` - look things up on public music sites\n\n## 02 / Make it yours\n\n- `/profile` - the same profile as `/taste`\n- `/profile corrections` - everything you've told me\n- `/profile retract <id>` - undo one of those\n- `/profile help` - the full set of profile commands\n- `/remember <text>`, `/memory`, `/forget <id>` - what I remember between conversations\n\n## 03 / Around the room\n\n- `/home` - back to the record sleeve; the conversation stays\n- `/theme paper|charcoal|terminal|auto` - change the look\n- `/art braille|ascii|off` - change the artwork\n- `/motion on|off` - turn the animation on or off\n- `/commands` or Ctrl+P - search every command; your message stays put\n- Page Up and Page Down scroll the conversation. The header and your draft stay put\n- Up and Down in the draft recall what you typed in this conversation\n- `/resume` - pick up a saved conversation (type to filter, Enter opens)\n- `/new` - start fresh; this conversation stays saved\n- `/rewind` or Alt+R - edit an earlier message in place; the messages after it are replaced\n- `/branch` - go on from here in a new conversation; this one stays saved\n- `/status`, `/sources`, `/tools`, `/doctor` - see what's connected and working\n- `/reload` - reload model settings and sign-ins\n- `/model roles` - see what side tasks use: the model that reads images and the web search service\n- `/effort` - choose how hard the model thinks\n- `/endpoint add` or `/endpoint remove <id>` - add a model service by its address, or remove it\n- `/update [--check] [--channel latest|beta]` - check for a release, or close this room and install it\n- `/help all` - every command, including the ones for the shell\n- `/language` - choose the language Moondog uses\n- `/quit` - leave\n\nTab moves to the menu on the home screen. Esc goes back to typing.\nEnter sends, and Shift+Enter starts a new line.\nTab or Enter accepts a suggestion.\nCtrl+C stops a model or web request, or leaves when nothing is running.\nIn the profile, type to filter, Tab switches lists, and Enter shows what you can do.\nCtrl+R refreshes it and Ctrl+O opens the full report.\nYour profile works without a model.\nPut quotes around paths, titles, and names that have spaces.");
|
|
568
568
|
}
|