@audiofool/moondog 0.1.0 → 0.2.0-beta.2

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.
Files changed (121) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +153 -68
  3. package/contracts/v1/definitions.schema.json +1 -169
  4. package/package.json +7 -23
  5. package/scripts/contract-lib.mjs +0 -7
  6. package/scripts/contract-semantics.mjs +0 -1904
  7. package/scripts/moondog.mjs +285 -74
  8. package/src/core/apple-library-source-status.mjs +0 -16
  9. package/src/core/apple-projection-domain-services.mjs +168 -36
  10. package/src/core/application-update.mjs +320 -0
  11. package/src/core/capability-catalog.mjs +278 -55
  12. package/src/core/listening-now.mjs +108 -0
  13. package/src/core/listening-profile-domain-services.mjs +153 -41
  14. package/src/core/listening-upkeep.mjs +31 -0
  15. package/src/core/moondog-application.mjs +1908 -104
  16. package/src/core/playback-preferences.mjs +97 -0
  17. package/src/core/spotify-listening-intent.mjs +121 -0
  18. package/src/core/synthetic-domain-services.mjs +24 -3
  19. package/src/demo/moondog-demo.mjs +4 -22
  20. package/src/i18n/index.mjs +285 -0
  21. package/src/i18n/messages/de.mjs +128 -0
  22. package/src/i18n/messages/en.mjs +129 -0
  23. package/src/i18n/messages/es.mjs +128 -0
  24. package/src/i18n/messages/fr.mjs +128 -0
  25. package/src/i18n/messages/it.mjs +128 -0
  26. package/src/i18n/messages/ja.mjs +128 -0
  27. package/src/i18n/messages/ko.mjs +128 -0
  28. package/src/i18n/messages/pt.mjs +128 -0
  29. package/src/i18n/messages/zh-Hant.mjs +128 -0
  30. package/src/i18n/messages/zh.mjs +128 -0
  31. package/src/i18n/preferences.mjs +34 -0
  32. package/src/i18n/screen/es.mjs +966 -0
  33. package/src/i18n/screen/ja.mjs +966 -0
  34. package/src/i18n/screen/pt.mjs +966 -0
  35. package/src/i18n/screen/zh.mjs +966 -0
  36. package/src/importers/apple-music-library/index.mjs +0 -16
  37. package/src/importers/apple-music-library/sqlite-projection.mjs +51 -9
  38. package/src/integrations/apple-music/catalog.mjs +123 -14
  39. package/src/integrations/apple-music/music-app.mjs +232 -0
  40. package/src/integrations/apple-music/storefront.mjs +28 -0
  41. package/src/integrations/apple-music/terminal-preview-player.mjs +221 -0
  42. package/src/integrations/lastfm/history.mjs +221 -0
  43. package/src/integrations/lastfm/settings.mjs +75 -0
  44. package/src/integrations/netease/ncm-cli-player.mjs +321 -0
  45. package/src/integrations/open-music-similarity/artist-radio.mjs +26 -18
  46. package/src/integrations/public-playlists.mjs +2 -1
  47. package/src/integrations/spotify/account-data-profile.mjs +14 -6
  48. package/src/integrations/spotify/authentication.mjs +149 -15
  49. package/src/integrations/spotify/catalog-resolver.mjs +8 -4
  50. package/src/integrations/spotify/connection.mjs +2 -1
  51. package/src/integrations/spotify/credential-store.mjs +4 -0
  52. package/src/integrations/spotify/extended-streaming-history.mjs +11 -11
  53. package/src/integrations/spotify/history-archive.mjs +1 -1
  54. package/src/integrations/spotify/library-snapshot.mjs +227 -0
  55. package/src/integrations/spotify/recent-activity.mjs +2 -0
  56. package/src/integrations/spotify/service.mjs +873 -69
  57. package/src/integrations/spotify/web-api-client.mjs +407 -127
  58. package/src/integrations/web/brave-web.mjs +45 -0
  59. package/src/integrations/web/codex-web.mjs +15 -82
  60. package/src/integrations/web/deepseek-web.mjs +81 -0
  61. package/src/integrations/web/web-research.mjs +119 -0
  62. package/src/integrations/web/web-result.mjs +215 -0
  63. package/src/integrations/youtube-music/takeout.mjs +3 -1
  64. package/src/memory/local-memory-store.mjs +469 -41
  65. package/src/profile/history-import.mjs +42 -6
  66. package/src/profile/listener-profile-build.mjs +378 -0
  67. package/src/profile/listener-profile-store.mjs +130 -0
  68. package/src/profile/listener-profile-verification.mjs +68 -0
  69. package/src/profile/listener-profile-worker.mjs +172 -0
  70. package/src/profile/listening-history-store.mjs +424 -8
  71. package/src/profile/listening-profile-projection.mjs +242 -76
  72. package/src/profile/local-music-data.mjs +1 -1
  73. package/src/profile/music-providers.mjs +11 -7
  74. package/src/profile/profile-exploration.mjs +84 -0
  75. package/src/profile/recorded-measures.mjs +24 -0
  76. package/src/profile/spotify-archive-taste.mjs +0 -4
  77. package/src/runtime/pi/agent-runtime.mjs +2204 -605
  78. package/src/runtime/pi/authentication.mjs +34 -1
  79. package/src/runtime/pi/configured-runtime.mjs +22 -6
  80. package/src/runtime/pi/conversation-name.mjs +53 -0
  81. package/src/runtime/pi/memory-agent-runtime.mjs +2 -2
  82. package/src/runtime/pi/model-catalog.mjs +28 -5
  83. package/src/runtime/pi/model-settings.mjs +202 -0
  84. package/src/runtime/pi/model-transport.mjs +10 -0
  85. package/src/runtime/pi/persistent-credential-store.mjs +67 -31
  86. package/src/runtime/pi/profile-build-runtime.mjs +160 -0
  87. package/src/runtime/pi/public-model-catalog.mjs +288 -0
  88. package/src/runtime/pi/runtime-settings.mjs +10 -2
  89. package/src/runtime/pi/skills/listener-profile/SKILL.md +46 -0
  90. package/src/runtime/pi/tool-trace.mjs +37 -0
  91. package/src/surfaces/cli/auth-command.mjs +12 -4
  92. package/src/surfaces/cli/brand-components.mjs +310 -132
  93. package/src/surfaces/cli/brand-theme.mjs +51 -28
  94. package/src/surfaces/cli/command-completions.mjs +58 -42
  95. package/src/surfaces/cli/format-output.mjs +199 -388
  96. package/src/surfaces/cli/history-import-view.mjs +292 -139
  97. package/src/surfaces/cli/import-guides.mjs +2 -0
  98. package/src/surfaces/cli/listener-profile-command.mjs +92 -0
  99. package/src/surfaces/cli/listening-menu.mjs +7 -4
  100. package/src/surfaces/cli/profile-command.mjs +30 -21
  101. package/src/surfaces/cli/seasons-chart.mjs +87 -0
  102. package/src/surfaces/cli/spotify-command.mjs +54 -6
  103. package/src/surfaces/cli/taste-profile-model.mjs +78 -79
  104. package/src/surfaces/cli/taste-profile-view.mjs +33 -26
  105. package/src/surfaces/cli/terminal-art.mjs +140 -35
  106. package/src/surfaces/cli/tui.mjs +1066 -357
  107. package/src/surfaces/cli/update-command.mjs +32 -0
  108. package/src/surfaces/cli/web-command.mjs +53 -14
  109. package/src/surfaces/html/tasteprint.mjs +43 -70
  110. package/contracts/v1/capability-policy.schema.json +0 -572
  111. package/contracts/v1/profile-evidence.schema.json +0 -237
  112. package/contracts/v1/tool-invocation.schema.json +0 -318
  113. package/contracts/v1/tool-receipt.schema.json +0 -1066
  114. package/scripts/demo-studio.mjs +0 -58
  115. package/src/core/apple-data-migration.mjs +0 -50
  116. package/src/demo/moondog-interactive-tasteprint-demo.mjs +0 -293
  117. package/src/demo/moondog-tasteprint-demo.mjs +0 -631
  118. package/src/integrations/spotify/index.mjs +0 -80
  119. package/src/surfaces/web/showcase.mjs +0 -272
  120. package/src/surfaces/web/studio-page.mjs +0 -4148
  121. package/src/surfaces/web/studio.mjs +0 -2288
package/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
package/README.md CHANGED
@@ -1,28 +1,30 @@
1
1
  <p align="center">
2
- <img src="assets/brand/moondog-lunar-record/moondog-logo-1x1.png" width="144" alt="Moondog lunar record logo">
2
+ <img src="assets/brand/moondog-lunar-record/moondog-logo-1x1.png" width="156" alt="Moondog lunar record">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Moondog</h1>
6
6
 
7
- <p align="center"><strong>A personal music agent that shows its work.</strong></p>
7
+ <p align="center">Source candidate 0.2.0-beta.2</p>
8
8
 
9
- <p align="center">Your listening history. Your say in what it means.</p>
9
+ <p align="center"><strong>A listening room that shows its work.</strong></p>
10
10
 
11
11
  <p align="center">
12
- <img src="assets/demo/moondog-tui-home.png" width="1000" alt="Moondog's terminal listening room: a lunar record drawn in characters, a short menu, a Pink Floyd lyric, and a message box">
12
+ <img src="assets/demo/moondog-tui-home.png" width="1000" alt="Moondog's listening room in charcoal: a lunar record beside the wordmark, a four-line tracklist, and the line Is there anybody out there">
13
13
  </p>
14
14
 
15
- <p align="center"><sub>The real terminal app, shown with fictional listening data.</sub></p>
15
+ <p align="center"><sub>The real TUI, in charcoal, with fictional listening data.</sub></p>
16
16
 
17
- Moondog reads the history your music services already keep and turns it into a profile you can open, question, and correct.
18
- It tells you what it found, shows the evidence behind every reading, and is honest about what play counts can never know.
19
- When you want company, an agent can use that profile to talk music, find songs you haven't heard, and shape a playlist with you.
17
+ Moondog is a listening room in your terminal.
18
+ It reads the history your music services already keep, and turns it into a profile you can open, question, and correct.
19
+ The profile works without a model, an API key, or a music-service login.
20
+ When you want company, an agent can talk music with you, find songs you have not heard, and shape a playlist.
21
+ Your data stays on your machine.
22
+ The room is built on [Pi](https://github.com/earendil-works/pi).
20
23
 
21
- It runs in your terminal, keeps your data on your machine, and is built on [Pi](https://github.com/earendil-works/pi).
24
+ ## Open the room
22
25
 
23
- ## Start listening
24
-
25
- You need Node.js **22.19.0 or newer** on macOS or Linux.
26
+ You need Node.js 22.19.0 or newer, on macOS or Linux.
27
+ Install from this checkout to run the room shown here.
26
28
 
27
29
  ```bash
28
30
  git clone https://github.com/Audiofool934/moondog.git
@@ -31,95 +33,178 @@ npm ci
31
33
  npm start
32
34
  ```
33
35
 
34
- Your profile works without a model, an API key, or a music-service login.
35
- To see the agent at work with fictional data and no sign-in at all, run `npm run demo`.
36
+ [@audiofool/moondog](https://www.npmjs.com/package/@audiofool/moondog) 0.1.0 is the published package.
37
+ To see the agent work through fictional data, with no sign-in at all, run `npm run demo` from the checkout.
38
+
39
+ The source version supports `moondog update` and `/update`, with stable (`latest`) and preview (`beta`) channels.
40
+ Startup checks show a quiet notification; installation happens only when you request it.
41
+ See [updating and release channels](docs/UPDATES.md), including the one-time upgrade needed for the older npm 0.1.0 package.
42
+
43
+ ## Other ways in
44
+
45
+ [Moondog for Mac](app/README.md) is a native window on the same core as the terminal room.
46
+ It shares your profile, settings, sign-ins, and conversations with `moondog`, and draws its own conversation, now playing, and up next.
47
+ Run it from this checkout with `cd app && npm ci && npm start`.
48
+
49
+ The [project page](site/README.md) runs the real room in a browser on fictional listening data.
50
+
51
+ ## The sleeve
52
+
53
+ The opening is a record sleeve drawn in characters.
54
+ Nothing in the terminal is a picture.
55
+ On a wide screen the record sits beside the title, with the wordmark level with the dog's eye.
56
+ On a tall or narrow screen the record stacks above the title.
57
+ Moondog uses whichever arrangement leaves the record larger.
58
+ A lyric rests midway between the record and the input box, with room on both sides.
59
+ The input asks what you have been listening to.
60
+
61
+ Until your library has a line of its own, the sleeve rotates three short ones: "Where have you been?", "Is there anybody out there?", and "Wish you were here."
62
+ When a matching line from music you have played is available, that line takes the place.
63
+ Moondog asks [LRCLIB](https://lrclib.net/) for the original words only, and does not send your profile, your history, or the conversation.
64
+
65
+ The room is black and white, like the moon.
66
+ Paper is black ink on white.
67
+ Charcoal is moonlight on a black sky.
68
+ `/theme terminal` keeps your own colors.
69
+ The only other colors are the six from the prism on *The Dark Side of the Moon*.
70
+ Red means a step failed, orange is a caution, green confirms, and the spectrum shows while Moondog is working.
71
+
72
+ Press Tab on an empty input to step onto the tracklist, then use the arrow keys and Enter.
73
+
74
+ | On the sleeve | Command |
75
+ | --- | --- |
76
+ | Listening profile | `/taste` |
77
+ | Import your music | `/import` |
78
+ | Appearance | `/theme` |
79
+ | Help & commands | `/help` |
80
+
81
+ While the room is idle, lunar marks travel the record, a highlight follows the groove, and the needle pulses.
82
+ The dog and the wordmark stay still.
83
+ `/motion off` holds the sleeve.
84
+ `/art ascii` switches the drawing.
85
+ `/home` returns here and leaves the conversation where it was.
36
86
 
37
87
  ## Bring your history
38
88
 
39
- Type `/import` and pick **Spotify**, **Apple Music**, **YouTube Music**, **QQ Music**, or **NetEase Cloud Music**.
40
- Moondog walks you through getting your data, then shows you what's inside before anything is added.
89
+ Type `/import` and pick a service.
90
+ Moondog shows you what is inside before anything is saved.
91
+ When the import finishes, your profile opens in the same TUI session.
41
92
 
42
- - **Spotify:** your latest plays in a minute, or your whole history from the ZIP Spotify emails you.
43
- - **Apple Music:** the `Library.xml` you export from Music on a Mac.
44
- - **YouTube Music:** a Google Takeout export.
45
- - **QQ Music and NetEase:** any public playlist, from its share link.
46
- - **ListenBrainz:** a saved listens file.
93
+ | Service | What you can bring |
94
+ | --- | --- |
95
+ | Spotify | Recent plays after you connect, or the whole history from the ZIP Spotify emails you. |
96
+ | Apple Music | The Library.xml you export from Music on a Mac. |
97
+ | YouTube Music | A Google Takeout export. |
98
+ | Last.fm | Your scrobbles and loved tracks, read by username. |
99
+ | QQ Music and NetEase | Any public playlist, from its share link. |
100
+ | ListenBrainz | A saved listens file. |
47
101
 
48
- A Spotify ZIP can also go straight in:
102
+ A Spotify ZIP can also go straight in.
49
103
 
50
104
  ```text
51
105
  /import "/path/to/spotify-history.zip"
52
106
  ```
53
107
 
54
- When the import finishes, your profile opens right there in the same TUI session, with the full report kept in the conversation above it.
55
108
  Importing the same file twice changes nothing, and your original files are never touched.
56
- Some sources aren't supported yet, such as Apple's privacy download and full QQ or NetEase listening history; the import guide says so where it matters.
57
- The [terminal guide](docs/TERMINAL_GUIDE.md#import-and-inspect-listening-history) covers every format in detail.
109
+ Apple's privacy download, and full QQ or NetEase listening history, are not supported yet.
110
+ The [terminal guide](docs/TERMINAL_GUIDE.md#import-and-inspect-listening-history) has every format.
58
111
 
59
- ## See what it says, and tell it what it got wrong
112
+ With a connected model, `/profile build` writes a reading of everything you imported, usually in a few minutes.
113
+ It names the threads in your listening, keeps what you played apart from what you saved, and marks its interpretations as interpretations.
114
+ A second pass checks the draft for contradictions and invented claims, and the build fixes what it finds before saving.
115
+ Use `/profile saved` to read it and `/profile explain 1` to trace a finding to its evidence, including after restarting.
116
+ New imports or corrections mark it for an update; a cancelled build keeps its draft and your previous reading.
117
+ The builder sends a compact summary of your music evidence to your configured model when you ask for it.
60
118
 
61
- | In your profile | What you can do |
62
- | --- | --- |
63
- | **Find a song or artist** | Type to filter, then open the one you want. |
64
- | **See why it's there** | Read what you played, what that can't prove, and what you told Moondog, each on its own. |
65
- | **Make a choice** | Choose **I like this** (Like) or **Keep it out** (Avoid), and watch the profile update. |
66
- | **Change your mind** | **Undo my choice** at any time; you can retract anything, and the original listening history never changes. |
67
- | **Find more like this** | Start an editable request for three songs, seeded from the track you picked. |
119
+ ## Your profile
120
+
121
+ The profile says what you played, and what that cannot prove.
122
+ Playing a song a lot does not, on its own, establish how much it matters to you.
68
123
 
69
124
  <p align="center">
70
- <img src="assets/demo/moondog-tui-profile.png" width="1000" alt="Moondog's listening profile showing the fictional track Midnight Lines, why it is there, and what that evidence cannot tell">
125
+ <img src="assets/demo/moondog-tui-profile.png" width="1000" alt="The listening profile for the fictional track Midnight Lines by Mara Vale, with the plays on one side and the limit of that evidence on the other">
71
126
  </p>
72
127
 
73
- <p align="center"><sub>The profile with fictional data. Playing a song a lot shows you know it, not that you love it.</sub></p>
128
+ <p align="center"><sub>Fictional data, with the evidence and the limit of that evidence.</sub></p>
74
129
 
75
- Type `/taste report` for the whole picture on one page.
76
- It walks through your years one song at a time, finds songs that went quiet and songs that came back, and ends with the dark side of the moon: what your listening data can't tell anyone.
77
- You can also save it as a private web page that works offline.
78
-
79
- ## Getting around
80
-
81
- | Command or key | What it does |
130
+ | In the profile | What you can do |
82
131
  | --- | --- |
83
- | `/taste` | Open your profile. |
84
- | Type, ↑ ↓, Enter | Filter, pick, and see why something is there, or make a choice. |
85
- | Tab in the profile | Switch between All, Tracks, Artists, and Your choices. |
86
- | Esc | Go back; whatever you were typing stays put. |
87
- | Ctrl+P | Search every command. |
88
- | `/resume` · `/new` | Pick up a saved conversation, or start a fresh one. |
89
- | `/home` | Back to the record sleeve, without clearing the conversation. |
132
+ | Find a song or artist | Type to filter, then open it. |
133
+ | See why it is there | Read what you played, what that cannot prove, and what you told Moondog, each on its own. |
134
+ | Make a choice | Choose **I like this** (Like) or **Keep it out** (Avoid), and the profile updates in place. |
135
+ | Change your mind | Choose **Undo my choice**, and the original listening history never changes. |
136
+ | Find more like this | Start an editable request for three songs, from the track you picked. |
90
137
 
91
- Each launch starts a new conversation, while your profile and anything Moondog remembers carry over.
92
- Change the look with `/theme paper` or `/theme charcoal`, switch the artwork with `/art ascii`, or keep it still with `/motion off`.
138
+ Type `/taste report` for the long view.
139
+ It walks the years one song at a time, names songs that went quiet and songs that came back, and ends on the dark side of the moon: what play counts can never tell anyone.
140
+ You can save that report as a private page that works offline.
93
141
 
94
- ## Add an agent when you want one
142
+ ## An agent, when you want one
95
143
 
96
- Sign in with `/auth` to GLM, Kimi, DeepSeek, Grok, GPT, Claude, Gemini, or OpenRouter, then pick a model with `/model`.
144
+ Sign in with `/auth`, then pick a model with `/model`.
145
+ GLM, Kimi, DeepSeek, Grok, GPT, Claude, Gemini, and OpenRouter are there.
97
146
  `openai-codex` uses your ChatGPT sign-in.
98
- You can switch models mid-conversation; the [model setup guide](docs/TERMINAL_GUIDE.md#enable-agent-conversation) lists provider IDs and environment variables.
99
-
100
- Ask for a route through your own history, reshuffle what it suggests, or reach past your library.
101
- Every song the agent picks has to come from a real list it looked up, and what it read about the wider music world stays separate from what it knows about you.
147
+ You can switch models in the middle of a conversation.
148
+ The [model setup guide](docs/TERMINAL_GUIDE.md#enable-agent-conversation) lists each provider and the environment variable it reads.
149
+
150
+ While an answer is on the way, each step appears in the conversation as it starts.
151
+ The steps stay above the reply, with a count of what finished, what failed, and what was not confirmed.
152
+ The agent can use musical knowledge and web research to find candidates, then verify the recordings on Spotify before playing or queueing them.
153
+ Without Spotify, it plays 30-second Apple Music previews from the terminal instead, each next to a link to the full song.
154
+ It also sees what you already play: the song and playlist in the Music app on a Mac, or on Spotify's active device, so “more like this playlist” needs no names.
155
+ macOS asks once before Moondog may read the Music app.
156
+ For example, “Pon doce de salsa clásica a la cola” asks it to add up to twelve verified songs directly; your history guides the choice without limiting it to your library.
157
+ What it reads about the wider music world stays separate from what it knows about you.
102
158
 
103
159
  | Optional connection | What it adds |
104
160
  | --- | --- |
105
- | **A model through Pi** | Conversation, discovery, and building playlists together. |
106
- | **Codex CLI** | `/web` lookups with links to their sources, using your own signed-in Codex CLI. |
107
- | **Spotify sign-in** | Playback control, and private playlists made only when you ask. |
161
+ | A model through Pi | Conversation, discovery, and playlists built together. |
162
+ | A web search service | `/web` lookups with links to their sources, through DeepSeek (`/auth deepseek`, which also reads pages), Brave Search (`/auth brave`), or your own signed-in Codex CLI. |
163
+ | Spotify sign-in | Playback, and private playlists made only when you ask. |
108
164
 
109
165
  Your profile never touches the network.
110
- The agent and connected features talk to the services you set up; `/web` sends only the question or link you give it, never your profile, history, or files.
111
- Importing a Spotify ZIP doesn't need a Spotify sign-in.
166
+ The agent talks only to the services you set up.
167
+ `/web` sends the question or the link you give it, and nothing from your profile, history, or files.
168
+ A Spotify ZIP does not need a Spotify sign-in.
112
169
  Read the [connection and data details](docs/TERMINAL_GUIDE.md) before you connect anything.
113
170
 
114
- ## Explore further
171
+ ## Getting around
172
+
173
+ | Command or key | What it does |
174
+ | --- | --- |
175
+ | `/taste` | Open your profile. |
176
+ | Type, arrow keys, Enter | Filter, pick a row, and see why it is there, or make a choice. |
177
+ | Tab in the profile | Switch between All, Tracks, Artists, and Your choices. |
178
+ | Tab on the sleeve | Step onto the tracklist, then press Escape to return to the line you were writing. |
179
+ | Esc | Go back, and the draft stays put. |
180
+ | Ctrl+P | Search every command. |
181
+ | Page Up, Page Down | Move through the conversation while the header, the draft, and the status line stay put. |
182
+ | Up and Down in the draft | Recall what you typed in this conversation. |
183
+ | Enter while Moondog is working | Queue the next message. It sends when this one finishes. |
184
+ | `/resume`, `/new` | Pick up a saved conversation, or start a fresh one. |
185
+ | `/home` | Back to the sleeve, without clearing the conversation. |
186
+ | `/skip`, `/stop` | Skip to the next song preview, or stop the previews. |
187
+ | `/lyrics` | See which line is on the sleeve, and which song it came from. |
188
+ | `/theme paper` | Black ink on white. |
189
+ | `/theme charcoal` | Moonlight on a black sky. |
190
+ | `/theme terminal` | Your terminal's own colors. |
191
+ | `/language` | Choose the language Moondog replies in: English, 简体中文, 繁體中文, 日本語, 한국어, Español, Français, Deutsch, Português (Brasil), or Italiano. Screens follow in English, Español, Português (Brasil), 日本語, and 简体中文. |
192
+
193
+ Each launch starts a new conversation.
194
+ Your profile, and anything Moondog remembers, carry over.
195
+
196
+ ## Further
115
197
 
116
198
  - [Terminal guide](docs/TERMINAL_GUIDE.md): import formats, commands, appearance, models, Spotify, memory, and your local data.
117
199
  - [Private Tasteprint](docs/PRIVATE_TASTEPRINT.md): what the evidence can support, and what a report reveals about you.
118
- - [Product charter](docs/PRODUCT_CHARTER.md) and [public roadmap](docs/ROADMAP.md): where Moondog is headed, and what it won't do.
200
+ - [Product charter](docs/PRODUCT_CHARTER.md) and [public roadmap](docs/ROADMAP.md): where Moondog is headed, and what it will not do.
119
201
  - [Voice](docs/VOICE.md): how Moondog talks, and where Pink Floyd shows up.
120
202
  - [Runtime architecture](docs/ADR_0001_AGENT_RUNTIME_AND_CLI.md) and [data contracts](contracts/README.md): how the pieces fit together.
121
- - [Contribution guide](CONTRIBUTING.md) and [release readiness](docs/PUBLIC_RELEASE_READINESS.md): local setup, checks, and how private data is kept out.
203
+ - [Contribution guide](CONTRIBUTING.md): local setup, checks, and how private data is kept out.
204
+ - [Release status](docs/PUBLIC_RELEASE_READINESS.md): what is published, and what the checks cover.
205
+ - [Translating Moondog](docs/TRANSLATING.md): how replies choose a language, and how to add one.
206
+
207
+ ## License
122
208
 
123
- Moondog is early, and the Pi-based TUI is where the work happens.
124
- GUI and Studio development is paused; the earlier [browser prototypes](docs/TERMINAL_GUIDE.md#archived-gui-prototypes-paused) are still there for reference.
125
- There is no open-source license yet.
209
+ Moondog is open source under the [Apache License 2.0](LICENSE).
210
+ Copyright 2026 Audiofool.