@audiofool/moondog 0.1.0

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 (109) hide show
  1. package/README.md +125 -0
  2. package/assets/brand/moondog-lunar-record/moondog-logo-1x1.png +0 -0
  3. package/contracts/v1/capability-policy.schema.json +572 -0
  4. package/contracts/v1/definitions.schema.json +365 -0
  5. package/contracts/v1/library-track-observation.schema.json +138 -0
  6. package/contracts/v1/listening-event.schema.json +111 -0
  7. package/contracts/v1/profile-evidence.schema.json +237 -0
  8. package/contracts/v1/taste-event.schema.json +258 -0
  9. package/contracts/v1/tool-invocation.schema.json +318 -0
  10. package/contracts/v1/tool-receipt.schema.json +1066 -0
  11. package/contracts/v1/track-ref.schema.json +275 -0
  12. package/contracts/v2/profile-evidence.schema.json +284 -0
  13. package/package.json +105 -0
  14. package/scripts/contract-lib.mjs +361 -0
  15. package/scripts/contract-semantics.mjs +2630 -0
  16. package/scripts/demo-studio.mjs +58 -0
  17. package/scripts/moondog +52 -0
  18. package/scripts/moondog.mjs +954 -0
  19. package/src/core/apple-data-migration.mjs +50 -0
  20. package/src/core/apple-library-source-status.mjs +220 -0
  21. package/src/core/apple-projection-domain-services.mjs +2356 -0
  22. package/src/core/capability-catalog.mjs +577 -0
  23. package/src/core/listening-profile-domain-services.mjs +1010 -0
  24. package/src/core/lyric-library.mjs +121 -0
  25. package/src/core/lyric-profile.mjs +50 -0
  26. package/src/core/lyric-service.mjs +41 -0
  27. package/src/core/moondog-application.mjs +1827 -0
  28. package/src/core/state-directory.mjs +19 -0
  29. package/src/core/synthetic-domain-services.mjs +1485 -0
  30. package/src/core/uuid-v5.mjs +42 -0
  31. package/src/demo/fictional-spotify-history.mjs +400 -0
  32. package/src/demo/moondog-demo.mjs +355 -0
  33. package/src/demo/moondog-interactive-tasteprint-demo.mjs +293 -0
  34. package/src/demo/moondog-tasteprint-demo.mjs +631 -0
  35. package/src/importers/apple-music-library/import-batch.mjs +290 -0
  36. package/src/importers/apple-music-library/index.mjs +76 -0
  37. package/src/importers/apple-music-library/normalize.mjs +1126 -0
  38. package/src/importers/apple-music-library/parse-plist.mjs +357 -0
  39. package/src/importers/apple-music-library/projection-records.mjs +557 -0
  40. package/src/importers/apple-music-library/read-batch.mjs +276 -0
  41. package/src/importers/apple-music-library/sqlite-projection.mjs +1307 -0
  42. package/src/importers/apple-music-library/stable-ids.mjs +19 -0
  43. package/src/importers/apple-music-library/track-snapshot.schema.json +136 -0
  44. package/src/integrations/apple-music/catalog.mjs +770 -0
  45. package/src/integrations/cross-catalog-artist-identity.mjs +222 -0
  46. package/src/integrations/listenbrainz/history-file.mjs +560 -0
  47. package/src/integrations/lyrics/lrclib.mjs +55 -0
  48. package/src/integrations/open-music-similarity/artist-radio.mjs +806 -0
  49. package/src/integrations/public-playlists.mjs +104 -0
  50. package/src/integrations/spotify/account-data-history.mjs +545 -0
  51. package/src/integrations/spotify/account-data-profile.mjs +918 -0
  52. package/src/integrations/spotify/authentication.mjs +791 -0
  53. package/src/integrations/spotify/catalog-resolver.mjs +657 -0
  54. package/src/integrations/spotify/connection.mjs +125 -0
  55. package/src/integrations/spotify/credential-store.mjs +26 -0
  56. package/src/integrations/spotify/extended-streaming-history.mjs +525 -0
  57. package/src/integrations/spotify/history-archive.mjs +59 -0
  58. package/src/integrations/spotify/index.mjs +80 -0
  59. package/src/integrations/spotify/recent-activity.mjs +198 -0
  60. package/src/integrations/spotify/resolution-cache.mjs +260 -0
  61. package/src/integrations/spotify/service.mjs +713 -0
  62. package/src/integrations/spotify/settings.mjs +89 -0
  63. package/src/integrations/spotify/web-api-client.mjs +761 -0
  64. package/src/integrations/web/codex-web.mjs +263 -0
  65. package/src/integrations/youtube-music/takeout.mjs +143 -0
  66. package/src/memory/local-memory-store.mjs +1705 -0
  67. package/src/memory/reflection-worker.mjs +87 -0
  68. package/src/profile/apple-library-import.mjs +28 -0
  69. package/src/profile/history-import.mjs +163 -0
  70. package/src/profile/listener-corrections.mjs +217 -0
  71. package/src/profile/listening-history-store.mjs +2055 -0
  72. package/src/profile/listening-profile-projection.mjs +2520 -0
  73. package/src/profile/local-music-data.mjs +812 -0
  74. package/src/profile/music-import-bundle.mjs +91 -0
  75. package/src/profile/music-providers.mjs +25 -0
  76. package/src/profile/spotify-archive-catalog-hints.mjs +210 -0
  77. package/src/profile/spotify-archive-taste.mjs +482 -0
  78. package/src/runtime/pi/agent-runtime.mjs +6444 -0
  79. package/src/runtime/pi/authentication.mjs +104 -0
  80. package/src/runtime/pi/configured-runtime.mjs +98 -0
  81. package/src/runtime/pi/memory-agent-runtime.mjs +337 -0
  82. package/src/runtime/pi/model-catalog.mjs +62 -0
  83. package/src/runtime/pi/model-transport.mjs +117 -0
  84. package/src/runtime/pi/persistent-credential-store.mjs +670 -0
  85. package/src/runtime/pi/provider-registry.mjs +74 -0
  86. package/src/runtime/pi/runtime-settings.mjs +81 -0
  87. package/src/surfaces/cli/auth-command.mjs +355 -0
  88. package/src/surfaces/cli/brand-components.mjs +390 -0
  89. package/src/surfaces/cli/brand-theme.mjs +231 -0
  90. package/src/surfaces/cli/catalog-command.mjs +509 -0
  91. package/src/surfaces/cli/command-completions.mjs +113 -0
  92. package/src/surfaces/cli/data-command.mjs +214 -0
  93. package/src/surfaces/cli/format-output.mjs +750 -0
  94. package/src/surfaces/cli/history-import-view.mjs +445 -0
  95. package/src/surfaces/cli/import-guides.mjs +9 -0
  96. package/src/surfaces/cli/listenbrainz-command.mjs +129 -0
  97. package/src/surfaces/cli/listening-menu.mjs +171 -0
  98. package/src/surfaces/cli/profile-command.mjs +290 -0
  99. package/src/surfaces/cli/spotify-command.mjs +849 -0
  100. package/src/surfaces/cli/taste-profile-model.mjs +306 -0
  101. package/src/surfaces/cli/taste-profile-view.mjs +272 -0
  102. package/src/surfaces/cli/terminal-art.mjs +295 -0
  103. package/src/surfaces/cli/tui.mjs +1714 -0
  104. package/src/surfaces/cli/web-command.mjs +52 -0
  105. package/src/surfaces/html/tasteprint-artifact.mjs +96 -0
  106. package/src/surfaces/html/tasteprint.mjs +3575 -0
  107. package/src/surfaces/web/showcase.mjs +272 -0
  108. package/src/surfaces/web/studio-page.mjs +4148 -0
  109. package/src/surfaces/web/studio.mjs +2288 -0
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ MOONDOG_STUDIO_MAXIMUM_ARCHIVES,
5
+ runMoondogStudio,
6
+ } from "../src/surfaces/web/studio.mjs";
7
+
8
+ const usage = `Usage:
9
+ npm run demo:studio
10
+ npm run demo:studio -- --from <spotify-history.zip> [--from <spotify-history.zip>]
11
+
12
+ Without --from, Moondog opens the fictional production-importer tour.
13
+ With one or two explicitly supplied ZIPs, it opens a session-only private profile without installing dependencies or writing persistent profile state.`;
14
+
15
+ function terminalText(value) {
16
+ return String(value ?? "Unknown failure")
17
+ .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, " ")
18
+ .replace(/[\u202a-\u202e\u2066-\u2069]/gu, "")
19
+ .slice(0, 1_000);
20
+ }
21
+
22
+ async function main() {
23
+ const values = process.argv.slice(2);
24
+ if (values.length === 1 && new Set(["--help", "-h"]).has(values[0])) {
25
+ process.stdout.write(`${usage}\n`);
26
+ return;
27
+ }
28
+ if (values.length === 0) {
29
+ await runMoondogStudio({ demoOnly: true });
30
+ return;
31
+ }
32
+
33
+ const archivePaths = [];
34
+ for (let index = 0; index < values.length; index += 2) {
35
+ const option = values[index];
36
+ const archivePath = values[index + 1];
37
+ if (
38
+ option !== "--from" ||
39
+ !archivePath ||
40
+ archivePath.startsWith("--")
41
+ ) {
42
+ throw new Error(usage);
43
+ }
44
+ archivePaths.push(archivePath);
45
+ }
46
+ if (
47
+ archivePaths.length < 1 ||
48
+ archivePaths.length > MOONDOG_STUDIO_MAXIMUM_ARCHIVES
49
+ ) {
50
+ throw new Error(usage);
51
+ }
52
+ await runMoondogStudio({ archivePaths });
53
+ }
54
+
55
+ main().catch((error) => {
56
+ process.stderr.write(`moondog demo studio: ${terminalText(error?.message)}\n`);
57
+ process.exitCode = 1;
58
+ });
@@ -0,0 +1,52 @@
1
+ #!/bin/sh
2
+
3
+ set -eu
4
+
5
+ is_compatible_node() {
6
+ "$1" -e '
7
+ const [major, minor] = process.versions.node.split(".").map(Number);
8
+ process.exit(major > 22 || (major === 22 && minor >= 19) ? 0 : 1);
9
+ ' >/dev/null 2>&1
10
+ }
11
+
12
+ node_executable=""
13
+
14
+ if [ -n "${MOONDOG_NODE:-}" ]; then
15
+ if is_compatible_node "$MOONDOG_NODE"; then
16
+ node_executable=$MOONDOG_NODE
17
+ else
18
+ printf '%s\n' "moondog: MOONDOG_NODE must point to Node >=22.19.0." >&2
19
+ exit 1
20
+ fi
21
+ else
22
+ saved_ifs=$IFS
23
+ IFS=:
24
+ for directory in ${PATH:-}; do
25
+ if [ -z "$directory" ]; then
26
+ directory=.
27
+ fi
28
+ candidate=$directory/node
29
+ if [ -x "$candidate" ] && is_compatible_node "$candidate"; then
30
+ node_executable=$candidate
31
+ break
32
+ fi
33
+ done
34
+ IFS=$saved_ifs
35
+ fi
36
+
37
+ if [ -z "$node_executable" ]; then
38
+ printf '%s\n' "moondog: Node >=22.19.0 was not found on PATH." >&2
39
+ exit 1
40
+ fi
41
+
42
+ launcher_path=$0
43
+ while [ -L "$launcher_path" ]; do
44
+ link_target=$(readlink "$launcher_path")
45
+ case $link_target in
46
+ /*) launcher_path=$link_target ;;
47
+ *) launcher_path=$(dirname "$launcher_path")/$link_target ;;
48
+ esac
49
+ done
50
+
51
+ script_directory=$(CDPATH= cd -P "$(dirname "$launcher_path")" && pwd)
52
+ exec "$node_executable" --disable-warning=ExperimentalWarning "$script_directory/moondog.mjs" "$@"