fluncle 0.114.0 → 0.115.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.
- package/bin/fluncle.mjs +137 -3
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -557,7 +557,7 @@ function parseVersion(version) {
|
|
|
557
557
|
var currentVersion;
|
|
558
558
|
var init_version = __esm(() => {
|
|
559
559
|
init_output();
|
|
560
|
-
currentVersion = "0.
|
|
560
|
+
currentVersion = "0.115.0".trim() ? "0.115.0".trim() : "0.1.0";
|
|
561
561
|
});
|
|
562
562
|
|
|
563
563
|
// src/update-notifier.ts
|
|
@@ -1042,6 +1042,48 @@ var init_artists = __esm(() => {
|
|
|
1042
1042
|
init_api();
|
|
1043
1043
|
});
|
|
1044
1044
|
|
|
1045
|
+
// src/commands/galaxies.ts
|
|
1046
|
+
var exports_galaxies = {};
|
|
1047
|
+
__export(exports_galaxies, {
|
|
1048
|
+
galaxyMapWriteCommand: () => galaxyMapWriteCommand,
|
|
1049
|
+
galaxyMapReadCommand: () => galaxyMapReadCommand,
|
|
1050
|
+
galaxyGetCommand: () => galaxyGetCommand,
|
|
1051
|
+
galaxyEmbeddingsCommand: () => galaxyEmbeddingsCommand,
|
|
1052
|
+
galaxiesListCommand: () => galaxiesListCommand
|
|
1053
|
+
});
|
|
1054
|
+
async function galaxiesListCommand() {
|
|
1055
|
+
const response = await publicApiGet("/api/v1/galaxies");
|
|
1056
|
+
return response.galaxies;
|
|
1057
|
+
}
|
|
1058
|
+
async function galaxyGetCommand(slug) {
|
|
1059
|
+
const response = await publicApiGet(`/api/v1/galaxies/${encodeURIComponent(slug)}`);
|
|
1060
|
+
return { findings: response.findings, galaxy: response.galaxy };
|
|
1061
|
+
}
|
|
1062
|
+
async function galaxyMapReadCommand() {
|
|
1063
|
+
const response = await adminApiGet("/api/admin/galaxies");
|
|
1064
|
+
return response.galaxies;
|
|
1065
|
+
}
|
|
1066
|
+
async function galaxyEmbeddingsCommand(options) {
|
|
1067
|
+
const params = new URLSearchParams;
|
|
1068
|
+
if (options.cursor) {
|
|
1069
|
+
params.set("cursor", options.cursor);
|
|
1070
|
+
}
|
|
1071
|
+
if (options.limit) {
|
|
1072
|
+
params.set("limit", options.limit);
|
|
1073
|
+
}
|
|
1074
|
+
const query = params.toString();
|
|
1075
|
+
return adminApiGet(`/api/admin/tracks/embeddings${query ? `?${query}` : ""}`);
|
|
1076
|
+
}
|
|
1077
|
+
async function galaxyMapWriteCommand(clusters) {
|
|
1078
|
+
const response = await adminApiPut("/api/admin/galaxies/map", {
|
|
1079
|
+
clusters
|
|
1080
|
+
});
|
|
1081
|
+
return response.galaxies;
|
|
1082
|
+
}
|
|
1083
|
+
var init_galaxies = __esm(() => {
|
|
1084
|
+
init_api();
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1045
1087
|
// src/commands/mixtape-api.ts
|
|
1046
1088
|
async function mixtapeListCommand() {
|
|
1047
1089
|
const response = await adminApiGet("/api/admin/mixtapes");
|
|
@@ -2209,7 +2251,7 @@ function parseVersion2(version) {
|
|
|
2209
2251
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2210
2252
|
var init_version2 = __esm(() => {
|
|
2211
2253
|
init_output();
|
|
2212
|
-
currentVersion2 = "0.
|
|
2254
|
+
currentVersion2 = "0.115.0".trim() ? "0.115.0".trim() : "0.1.0";
|
|
2213
2255
|
});
|
|
2214
2256
|
|
|
2215
2257
|
// ../../packages/registry/src/index.ts
|
|
@@ -3270,6 +3312,9 @@ async function trackUpdateCommand(trackId, options) {
|
|
|
3270
3312
|
if (options.embedding !== undefined) {
|
|
3271
3313
|
body.embedding = options.embedding;
|
|
3272
3314
|
}
|
|
3315
|
+
if (options.galaxyId !== undefined) {
|
|
3316
|
+
body.galaxyId = options.galaxyId;
|
|
3317
|
+
}
|
|
3273
3318
|
if (options.note !== undefined) {
|
|
3274
3319
|
body.note = options.note;
|
|
3275
3320
|
}
|
|
@@ -3462,6 +3507,9 @@ async function trackUpdateCommand2(trackId, options) {
|
|
|
3462
3507
|
if (options.embedding !== undefined) {
|
|
3463
3508
|
body.embedding = options.embedding;
|
|
3464
3509
|
}
|
|
3510
|
+
if (options.galaxyId !== undefined) {
|
|
3511
|
+
body.galaxyId = options.galaxyId;
|
|
3512
|
+
}
|
|
3465
3513
|
if (options.note !== undefined) {
|
|
3466
3514
|
body.note = options.note;
|
|
3467
3515
|
}
|
|
@@ -7768,6 +7816,10 @@ function addListenCommands(program2) {
|
|
|
7768
7816
|
const { artistsListCommand: artistsListCommand2, artistsGetCommand: artistsGetCommand2 } = await Promise.resolve().then(() => (init_artists(), exports_artists));
|
|
7769
7817
|
await runArtists(slug, options, { artistsGetCommand: artistsGetCommand2, artistsListCommand: artistsListCommand2 });
|
|
7770
7818
|
});
|
|
7819
|
+
program2.command("galaxies").description("Wander Fluncle's sonic galaxies").argument("[slug]", "Galaxy slug (omit for the full map)").option("--json", "Print JSON", false).action(async (slug, options) => {
|
|
7820
|
+
const { galaxiesListCommand: galaxiesListCommand2, galaxyGetCommand: galaxyGetCommand2 } = await Promise.resolve().then(() => (init_galaxies(), exports_galaxies));
|
|
7821
|
+
await runGalaxies(slug, options, { galaxiesListCommand: galaxiesListCommand2, galaxyGetCommand: galaxyGetCommand2 });
|
|
7822
|
+
});
|
|
7771
7823
|
program2.command("mixtapes").description("Fluncle's checkpoint sets").option("--json", "Print JSON", false).action(async (options) => {
|
|
7772
7824
|
const { mixtapesCommand: mixtapesCommand2 } = await Promise.resolve().then(() => (init_mixtapes(), exports_mixtapes));
|
|
7773
7825
|
await runMixtapes(options, mixtapesCommand2);
|
|
@@ -7901,7 +7953,7 @@ function addAdminCommands(program2) {
|
|
|
7901
7953
|
const { mixableOrderCommand: mixableOrderCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
7902
7954
|
await runMixableOrder(logIds, options, mixableOrderCommand2);
|
|
7903
7955
|
});
|
|
7904
|
-
adminTrack.command("update").description("Certify a track into the archive").argument("[trackId]").option("--analyzed-at <iso>", "Analysis-write ISO timestamp (BPM/key provenance)").option("--analyzed-from <class>", "Audio class BPM/key were analyzed from: full or preview").option("--bpm <number>", "Track BPM").option("--bpm-confidence <number>", "Analyzer confidence in the BPM (0..1)").option("--bpm-source <source>", "Where the BPM came from (analyzer bpmSource)").option("--embedding <json>", "MuQ audio embedding as a JSON array of 1024 floats").option("--embedding-file <file>", "Read the MuQ embedding JSON array from a file").option("--features <json>", "Audio feature JSON").option("--json", "Print JSON", false).option("--key <key>", "Musical key").option("--key-confidence <number>", "Analyzer confidence in the key (0..1)").option("--key-source <source>", "Where the key came from (analyzer keySource)").option("--note <text>", "Operator note").option("--status <status>", "Enrichment status").option("--video-url <url>", "Rendered video URL").allowExcessArguments().action(async (trackId, options) => {
|
|
7956
|
+
adminTrack.command("update").description("Certify a track into the archive").argument("[trackId]").option("--analyzed-at <iso>", "Analysis-write ISO timestamp (BPM/key provenance)").option("--analyzed-from <class>", "Audio class BPM/key were analyzed from: full or preview").option("--bpm <number>", "Track BPM").option("--bpm-confidence <number>", "Analyzer confidence in the BPM (0..1)").option("--bpm-source <source>", "Where the BPM came from (analyzer bpmSource)").option("--embedding <json>", "MuQ audio embedding as a JSON array of 1024 floats").option("--embedding-file <file>", "Read the MuQ embedding JSON array from a file").option("--features <json>", "Audio feature JSON").option("--galaxy-id <id>", "Sonic galaxy assignment (empty string clears it)").option("--json", "Print JSON", false).option("--key <key>", "Musical key").option("--key-confidence <number>", "Analyzer confidence in the key (0..1)").option("--key-source <source>", "Where the key came from (analyzer keySource)").option("--note <text>", "Operator note").option("--status <status>", "Enrichment status").option("--video-url <url>", "Rendered video URL").allowExcessArguments().action(async (trackId, options) => {
|
|
7905
7957
|
const { trackUpdateCommand: trackUpdateCommand3 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
7906
7958
|
await runTrackUpdate(trackId, options, trackUpdateCommand3);
|
|
7907
7959
|
});
|
|
@@ -8143,6 +8195,22 @@ function addAdminCommands(program2) {
|
|
|
8143
8195
|
artists.action(() => {
|
|
8144
8196
|
artists.outputHelp();
|
|
8145
8197
|
});
|
|
8198
|
+
const galaxies = configureCommand(admin.command("galaxies").description("Sonic galaxy map (cluster sweep) commands"));
|
|
8199
|
+
galaxies.action(() => {
|
|
8200
|
+
galaxies.outputHelp();
|
|
8201
|
+
});
|
|
8202
|
+
galaxies.command("map").description("Read the full galaxy map (named + unnamed + retired, with centroids)").option("--json", "Print JSON", false).action(async (options) => {
|
|
8203
|
+
const { galaxyMapReadCommand: galaxyMapReadCommand2 } = await Promise.resolve().then(() => (init_galaxies(), exports_galaxies));
|
|
8204
|
+
await runGalaxyMapRead(options, galaxyMapReadCommand2);
|
|
8205
|
+
});
|
|
8206
|
+
galaxies.command("embeddings").description("Read a cursor page of the embedded corpus (the cluster engine's input)").option("--cursor <cursor>", "Opaque cursor from a prior page's nextCursor").option("--limit <limit>", "Page size (default 200, clamped to 500)").option("--json", "Print JSON", false).action(async (options) => {
|
|
8207
|
+
const { galaxyEmbeddingsCommand: galaxyEmbeddingsCommand2 } = await Promise.resolve().then(() => (init_galaxies(), exports_galaxies));
|
|
8208
|
+
await runGalaxyEmbeddings(options, galaxyEmbeddingsCommand2);
|
|
8209
|
+
});
|
|
8210
|
+
galaxies.command("set-map").description("Write the galaxy map transactionally (mint new ids, upsert centroids, retire)").requiredOption("--file <file>", "Path to the clusters JSON ({ clusters: [...] } or a bare array)").option("--json", "Print JSON", false).action(async (options) => {
|
|
8211
|
+
const { galaxyMapWriteCommand: galaxyMapWriteCommand2 } = await Promise.resolve().then(() => (init_galaxies(), exports_galaxies));
|
|
8212
|
+
await runGalaxyMapWrite(options, galaxyMapWriteCommand2);
|
|
8213
|
+
});
|
|
8146
8214
|
const backfill = configureCommand(admin.command("backfills").description("Backfill operator-only archives"));
|
|
8147
8215
|
backfill.action(() => {
|
|
8148
8216
|
backfill.outputHelp();
|
|
@@ -8792,6 +8860,7 @@ async function runTrackUpdate(trackId, options, trackUpdateCommand3) {
|
|
|
8792
8860
|
bpmSource: options.bpmSource,
|
|
8793
8861
|
embedding,
|
|
8794
8862
|
features: options.features,
|
|
8863
|
+
galaxyId: options.galaxyId,
|
|
8795
8864
|
key: options.key,
|
|
8796
8865
|
keyConfidence,
|
|
8797
8866
|
keySource: options.keySource,
|
|
@@ -9155,6 +9224,71 @@ async function runArtists(slug, options, commands) {
|
|
|
9155
9224
|
console.log(`${a.name.padEnd(40)} ${String(a.findingCount).padStart(3)} finding${a.findingCount === 1 ? "" : "s"}`);
|
|
9156
9225
|
}
|
|
9157
9226
|
}
|
|
9227
|
+
async function runGalaxies(slug, options, commands) {
|
|
9228
|
+
if (slug) {
|
|
9229
|
+
const { findings, galaxy } = await commands.galaxyGetCommand(slug);
|
|
9230
|
+
if (options.json) {
|
|
9231
|
+
printJson({ findings, galaxy, ok: true });
|
|
9232
|
+
return;
|
|
9233
|
+
}
|
|
9234
|
+
console.log(`${galaxy.name} (${galaxy.slug})`);
|
|
9235
|
+
console.log(`${galaxy.memberCount} finding${galaxy.memberCount === 1 ? "" : "s"}`);
|
|
9236
|
+
for (const finding of findings) {
|
|
9237
|
+
const coordinate3 = finding.logId ? `${finding.logId} ` : "";
|
|
9238
|
+
console.log(` ${coordinate3}${finding.artists.join(", ")} \u2014 ${finding.title}`);
|
|
9239
|
+
}
|
|
9240
|
+
return;
|
|
9241
|
+
}
|
|
9242
|
+
const galaxies = await commands.galaxiesListCommand();
|
|
9243
|
+
if (options.json) {
|
|
9244
|
+
printJson({ galaxies, ok: true });
|
|
9245
|
+
return;
|
|
9246
|
+
}
|
|
9247
|
+
if (galaxies.length === 0) {
|
|
9248
|
+
console.log("No galaxies named yet. Quiet map tonight.");
|
|
9249
|
+
return;
|
|
9250
|
+
}
|
|
9251
|
+
for (const galaxy of galaxies) {
|
|
9252
|
+
console.log(`${galaxy.name.padEnd(40)} ${String(galaxy.memberCount).padStart(3)} finding${galaxy.memberCount === 1 ? "" : "s"}`);
|
|
9253
|
+
}
|
|
9254
|
+
}
|
|
9255
|
+
async function runGalaxyMapRead(options, galaxyMapReadCommand2) {
|
|
9256
|
+
const galaxies = await galaxyMapReadCommand2();
|
|
9257
|
+
if (options.json) {
|
|
9258
|
+
printJson({ galaxies, ok: true });
|
|
9259
|
+
return;
|
|
9260
|
+
}
|
|
9261
|
+
if (galaxies.length === 0) {
|
|
9262
|
+
console.log("No galaxies on the map yet.");
|
|
9263
|
+
return;
|
|
9264
|
+
}
|
|
9265
|
+
for (const galaxy of galaxies) {
|
|
9266
|
+
const name = galaxy.name ?? "(unnamed)";
|
|
9267
|
+
const retired = galaxy.retiredAt ? " [retired]" : "";
|
|
9268
|
+
console.log(`${galaxy.id} ${galaxy.handle.padEnd(30)} ${name.padEnd(24)} ${String(galaxy.memberCount).padStart(4)} members${retired}`);
|
|
9269
|
+
}
|
|
9270
|
+
}
|
|
9271
|
+
async function runGalaxyEmbeddings(options, galaxyEmbeddingsCommand2) {
|
|
9272
|
+
const result = await galaxyEmbeddingsCommand2({ cursor: options.cursor, limit: options.limit });
|
|
9273
|
+
if (options.json) {
|
|
9274
|
+
printJson(result);
|
|
9275
|
+
return;
|
|
9276
|
+
}
|
|
9277
|
+
console.log(`${result.embeddings.length} embedding(s)${result.nextCursor ? ` \xB7 nextCursor: ${result.nextCursor}` : " \xB7 end of corpus"}`);
|
|
9278
|
+
}
|
|
9279
|
+
async function runGalaxyMapWrite(options, galaxyMapWriteCommand2) {
|
|
9280
|
+
const raw = JSON.parse(readFileSync6(options.file, "utf8"));
|
|
9281
|
+
const clusters = Array.isArray(raw) || raw === null ? raw : raw.clusters;
|
|
9282
|
+
if (!Array.isArray(clusters)) {
|
|
9283
|
+
throw new Error("Invalid --file: expected { clusters: [...] } or a JSON array of cluster rows");
|
|
9284
|
+
}
|
|
9285
|
+
const galaxies = await galaxyMapWriteCommand2(clusters);
|
|
9286
|
+
if (options.json) {
|
|
9287
|
+
printJson({ galaxies, ok: true });
|
|
9288
|
+
return;
|
|
9289
|
+
}
|
|
9290
|
+
console.log(`Wrote ${clusters.length} cluster(s); the map now holds ${galaxies.length} galaxy(ies).`);
|
|
9291
|
+
}
|
|
9158
9292
|
async function runMixtapes(options, mixtapesCommand2) {
|
|
9159
9293
|
const mixtapes = await mixtapesCommand2();
|
|
9160
9294
|
if (options.json) {
|
package/package.json
CHANGED