@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.
- package/LICENSE +202 -0
- package/README.md +153 -68
- package/contracts/v1/definitions.schema.json +1 -169
- package/package.json +7 -23
- package/scripts/contract-lib.mjs +0 -7
- package/scripts/contract-semantics.mjs +0 -1904
- package/scripts/moondog.mjs +285 -74
- package/src/core/apple-library-source-status.mjs +0 -16
- package/src/core/apple-projection-domain-services.mjs +168 -36
- package/src/core/application-update.mjs +320 -0
- package/src/core/capability-catalog.mjs +278 -55
- package/src/core/listening-now.mjs +108 -0
- package/src/core/listening-profile-domain-services.mjs +153 -41
- package/src/core/listening-upkeep.mjs +31 -0
- package/src/core/moondog-application.mjs +1908 -104
- package/src/core/playback-preferences.mjs +97 -0
- package/src/core/spotify-listening-intent.mjs +121 -0
- package/src/core/synthetic-domain-services.mjs +24 -3
- package/src/demo/moondog-demo.mjs +4 -22
- package/src/i18n/index.mjs +285 -0
- package/src/i18n/messages/de.mjs +128 -0
- package/src/i18n/messages/en.mjs +129 -0
- package/src/i18n/messages/es.mjs +128 -0
- package/src/i18n/messages/fr.mjs +128 -0
- package/src/i18n/messages/it.mjs +128 -0
- package/src/i18n/messages/ja.mjs +128 -0
- package/src/i18n/messages/ko.mjs +128 -0
- package/src/i18n/messages/pt.mjs +128 -0
- package/src/i18n/messages/zh-Hant.mjs +128 -0
- package/src/i18n/messages/zh.mjs +128 -0
- package/src/i18n/preferences.mjs +34 -0
- package/src/i18n/screen/es.mjs +966 -0
- package/src/i18n/screen/ja.mjs +966 -0
- package/src/i18n/screen/pt.mjs +966 -0
- package/src/i18n/screen/zh.mjs +966 -0
- package/src/importers/apple-music-library/index.mjs +0 -16
- package/src/importers/apple-music-library/sqlite-projection.mjs +51 -9
- package/src/integrations/apple-music/catalog.mjs +123 -14
- package/src/integrations/apple-music/music-app.mjs +232 -0
- package/src/integrations/apple-music/storefront.mjs +28 -0
- package/src/integrations/apple-music/terminal-preview-player.mjs +221 -0
- package/src/integrations/lastfm/history.mjs +221 -0
- package/src/integrations/lastfm/settings.mjs +75 -0
- package/src/integrations/netease/ncm-cli-player.mjs +321 -0
- package/src/integrations/open-music-similarity/artist-radio.mjs +26 -18
- package/src/integrations/public-playlists.mjs +2 -1
- package/src/integrations/spotify/account-data-profile.mjs +14 -6
- package/src/integrations/spotify/authentication.mjs +149 -15
- package/src/integrations/spotify/catalog-resolver.mjs +8 -4
- package/src/integrations/spotify/connection.mjs +2 -1
- package/src/integrations/spotify/credential-store.mjs +4 -0
- package/src/integrations/spotify/extended-streaming-history.mjs +11 -11
- package/src/integrations/spotify/history-archive.mjs +1 -1
- package/src/integrations/spotify/library-snapshot.mjs +227 -0
- package/src/integrations/spotify/recent-activity.mjs +2 -0
- package/src/integrations/spotify/service.mjs +873 -69
- package/src/integrations/spotify/web-api-client.mjs +407 -127
- package/src/integrations/web/brave-web.mjs +45 -0
- package/src/integrations/web/codex-web.mjs +15 -82
- package/src/integrations/web/deepseek-web.mjs +81 -0
- package/src/integrations/web/web-research.mjs +119 -0
- package/src/integrations/web/web-result.mjs +215 -0
- package/src/integrations/youtube-music/takeout.mjs +3 -1
- package/src/memory/local-memory-store.mjs +469 -41
- package/src/profile/history-import.mjs +42 -6
- package/src/profile/listener-profile-build.mjs +378 -0
- package/src/profile/listener-profile-store.mjs +130 -0
- package/src/profile/listener-profile-verification.mjs +68 -0
- package/src/profile/listener-profile-worker.mjs +172 -0
- package/src/profile/listening-history-store.mjs +424 -8
- package/src/profile/listening-profile-projection.mjs +242 -76
- package/src/profile/local-music-data.mjs +1 -1
- package/src/profile/music-providers.mjs +11 -7
- package/src/profile/profile-exploration.mjs +84 -0
- package/src/profile/recorded-measures.mjs +24 -0
- package/src/profile/spotify-archive-taste.mjs +0 -4
- package/src/runtime/pi/agent-runtime.mjs +2204 -605
- package/src/runtime/pi/authentication.mjs +34 -1
- package/src/runtime/pi/configured-runtime.mjs +22 -6
- package/src/runtime/pi/conversation-name.mjs +53 -0
- package/src/runtime/pi/memory-agent-runtime.mjs +2 -2
- package/src/runtime/pi/model-catalog.mjs +28 -5
- package/src/runtime/pi/model-settings.mjs +202 -0
- package/src/runtime/pi/model-transport.mjs +10 -0
- package/src/runtime/pi/persistent-credential-store.mjs +67 -31
- package/src/runtime/pi/profile-build-runtime.mjs +160 -0
- package/src/runtime/pi/public-model-catalog.mjs +288 -0
- package/src/runtime/pi/runtime-settings.mjs +10 -2
- package/src/runtime/pi/skills/listener-profile/SKILL.md +46 -0
- package/src/runtime/pi/tool-trace.mjs +37 -0
- package/src/surfaces/cli/auth-command.mjs +12 -4
- package/src/surfaces/cli/brand-components.mjs +310 -132
- package/src/surfaces/cli/brand-theme.mjs +51 -28
- package/src/surfaces/cli/command-completions.mjs +58 -42
- package/src/surfaces/cli/format-output.mjs +199 -388
- package/src/surfaces/cli/history-import-view.mjs +292 -139
- package/src/surfaces/cli/import-guides.mjs +2 -0
- package/src/surfaces/cli/listener-profile-command.mjs +92 -0
- package/src/surfaces/cli/listening-menu.mjs +7 -4
- package/src/surfaces/cli/profile-command.mjs +30 -21
- package/src/surfaces/cli/seasons-chart.mjs +87 -0
- package/src/surfaces/cli/spotify-command.mjs +54 -6
- package/src/surfaces/cli/taste-profile-model.mjs +78 -79
- package/src/surfaces/cli/taste-profile-view.mjs +33 -26
- package/src/surfaces/cli/terminal-art.mjs +140 -35
- package/src/surfaces/cli/tui.mjs +1066 -357
- package/src/surfaces/cli/update-command.mjs +32 -0
- package/src/surfaces/cli/web-command.mjs +53 -14
- package/src/surfaces/html/tasteprint.mjs +43 -70
- package/contracts/v1/capability-policy.schema.json +0 -572
- package/contracts/v1/profile-evidence.schema.json +0 -237
- package/contracts/v1/tool-invocation.schema.json +0 -318
- package/contracts/v1/tool-receipt.schema.json +0 -1066
- package/scripts/demo-studio.mjs +0 -58
- package/src/core/apple-data-migration.mjs +0 -50
- package/src/demo/moondog-interactive-tasteprint-demo.mjs +0 -293
- package/src/demo/moondog-tasteprint-demo.mjs +0 -631
- package/src/integrations/spotify/index.mjs +0 -80
- package/src/surfaces/web/showcase.mjs +0 -272
- package/src/surfaces/web/studio-page.mjs +0 -4148
- 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="
|
|
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"
|
|
7
|
+
<p align="center">Source candidate 0.2.0-beta.2</p>
|
|
8
8
|
|
|
9
|
-
<p align="center">
|
|
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
|
|
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
|
|
15
|
+
<p align="center"><sub>The real TUI, in charcoal, with fictional listening data.</sub></p>
|
|
16
16
|
|
|
17
|
-
Moondog
|
|
18
|
-
It
|
|
19
|
-
|
|
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
|
-
|
|
24
|
+
## Open the room
|
|
22
25
|
|
|
23
|
-
|
|
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
|
-
|
|
35
|
-
To see the agent
|
|
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
|
|
40
|
-
Moondog
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
57
|
-
The [terminal guide](docs/TERMINAL_GUIDE.md#import-and-inspect-listening-history)
|
|
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
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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="
|
|
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>
|
|
128
|
+
<p align="center"><sub>Fictional data, with the evidence and the limit of that evidence.</sub></p>
|
|
74
129
|
|
|
75
|
-
|
|
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
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
##
|
|
142
|
+
## An agent, when you want one
|
|
95
143
|
|
|
96
|
-
Sign in with `/auth
|
|
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
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
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
|
|
111
|
-
|
|
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
|
-
##
|
|
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
|
|
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)
|
|
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
|
|
124
|
-
|
|
125
|
-
There is no open-source license yet.
|
|
209
|
+
Moondog is open source under the [Apache License 2.0](LICENSE).
|
|
210
|
+
Copyright 2026 Audiofool.
|