fluncle 0.174.0 → 0.175.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 +32 -35
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -561,7 +561,7 @@ function parseVersion(version) {
|
|
|
561
561
|
var currentVersion;
|
|
562
562
|
var init_version = __esm(() => {
|
|
563
563
|
init_output();
|
|
564
|
-
currentVersion = "0.
|
|
564
|
+
currentVersion = "0.175.0".trim() ? "0.175.0".trim() : "0.1.0";
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
// src/update-notifier.ts
|
|
@@ -2259,7 +2259,7 @@ function parseVersion2(version) {
|
|
|
2259
2259
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2260
2260
|
var init_version2 = __esm(() => {
|
|
2261
2261
|
init_output();
|
|
2262
|
-
currentVersion2 = "0.
|
|
2262
|
+
currentVersion2 = "0.175.0".trim() ? "0.175.0".trim() : "0.1.0";
|
|
2263
2263
|
});
|
|
2264
2264
|
|
|
2265
2265
|
// ../../packages/registry/src/index.ts
|
|
@@ -3119,16 +3119,16 @@ var init_src = __esm(() => {
|
|
|
3119
3119
|
weights: { status: "hidden" }
|
|
3120
3120
|
},
|
|
3121
3121
|
{
|
|
3122
|
-
command: "fluncle admin backfills
|
|
3122
|
+
command: "fluncle admin backfills label-releases",
|
|
3123
3123
|
exposedContent: [
|
|
3124
|
-
"tap
|
|
3124
|
+
"tap Spotify's fresh releases for the operator's enabled seed labels → day-one uncertified catalogue rows"
|
|
3125
3125
|
],
|
|
3126
3126
|
kind: "cron",
|
|
3127
|
-
name: "cron.
|
|
3128
|
-
operatorNotes: "every 24h, run by a rave-02 HOST systemd timer (docs/agents/hermes/
|
|
3127
|
+
name: "cron.label-releases",
|
|
3128
|
+
operatorNotes: "every 24h, run by a rave-02 HOST systemd timer (docs/agents/hermes/label-releases-timer/). The FRESHNESS TAP (D8): MusicBrainz WALKS the graph (cron.crawl) but lags a release ~2 weeks; Spotify has it day one, so this searches each ENABLED seed label's fresh releases (`label:\"<name>\" tag:new`, copyright-filtered — the fuzzy `label:` search is post-filtered on the album's ℗/© strings) and mints METADATA-ONLY catalogue rows (a `tracks` row with no `findings` row) with their real release dates — closing the /fresh lag cliff. It certifies nothing, publishes nothing, and never widens the graph (no new labels, no artist hops). Deduped against the MB crawl from both directions (Spotify id/uri/ISRC + same-album title fold). Worker-paced, reusing the publish path's Spotify OAuth (no new secret; Apple was a measured 2/99 seed-label dead end). Zero LLM tokens. Source: docs/agents/hermes/scripts/label-releases-sweep.*. See docs/catalogue-crawler.md.",
|
|
3129
3129
|
probeConfig: {
|
|
3130
3130
|
cadenceMs: 24 * 60 * MINUTE_MS,
|
|
3131
|
-
cronName: "fluncle-
|
|
3131
|
+
cronName: "fluncle-label-releases",
|
|
3132
3132
|
kind: "cron"
|
|
3133
3133
|
},
|
|
3134
3134
|
statusDescription: "taps day-one releases from the enabled labels",
|
|
@@ -4109,8 +4109,8 @@ __export(exports_admin_tracks, {
|
|
|
4109
4109
|
captureQueueCommand: () => captureQueueCommand,
|
|
4110
4110
|
backfillRecordingMbidsCommand: () => backfillRecordingMbidsCommand,
|
|
4111
4111
|
backfillLastfmCommand: () => backfillLastfmCommand,
|
|
4112
|
+
backfillLabelReleasesCommand: () => backfillLabelReleasesCommand,
|
|
4112
4113
|
backfillDiscogsCommand: () => backfillDiscogsCommand,
|
|
4113
|
-
backfillAppleReleasesCommand: () => backfillAppleReleasesCommand,
|
|
4114
4114
|
backfillAppleMusicCommand: () => backfillAppleMusicCommand,
|
|
4115
4115
|
backfillAppleCatalogueCommand: () => backfillAppleCatalogueCommand
|
|
4116
4116
|
});
|
|
@@ -4296,9 +4296,9 @@ async function backfillAppleCatalogueCommand(limit, dryRun) {
|
|
|
4296
4296
|
const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
|
|
4297
4297
|
return adminApiPost(`/api/admin/backfill/apple-catalogue?${params.toString()}`);
|
|
4298
4298
|
}
|
|
4299
|
-
async function
|
|
4299
|
+
async function backfillLabelReleasesCommand(limit, dryRun) {
|
|
4300
4300
|
const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
|
|
4301
|
-
return adminApiPost(`/api/admin/backfill/
|
|
4301
|
+
return adminApiPost(`/api/admin/backfill/label-releases?${params.toString()}`);
|
|
4302
4302
|
}
|
|
4303
4303
|
async function backfillRecordingMbidsCommand(limit, dryRun, cursor) {
|
|
4304
4304
|
const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
|
|
@@ -9679,9 +9679,9 @@ function addAdminCommands(program2) {
|
|
|
9679
9679
|
const { backfillAppleCatalogueCommand: backfillAppleCatalogueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
9680
9680
|
await runBackfillAppleCatalogue(options, backfillAppleCatalogueCommand2);
|
|
9681
9681
|
});
|
|
9682
|
-
backfill.command("
|
|
9683
|
-
const {
|
|
9684
|
-
await
|
|
9682
|
+
backfill.command("label-releases").description("Tap Spotify's fresh releases for enabled seed labels into catalogue rows").option("--dry-run", "Report the labels that would be probed without any Spotify call", false).option("--limit <limit>", "Max enabled seed labels to probe per pass", "5").option("--json", "Print JSON", false).action(async (options) => {
|
|
9683
|
+
const { backfillLabelReleasesCommand: backfillLabelReleasesCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
9684
|
+
await runBackfillLabelReleases(options, backfillLabelReleasesCommand2);
|
|
9685
9685
|
});
|
|
9686
9686
|
backfill.command("artists").description("Back-fill the artist entity (artists + track_artists) for existing findings").option("--dry-run", "Report which findings would be upserted without touching the DB", false).option("--limit <limit>", "Max findings to process", "50").option("--json", "Print JSON", false).action(async (options) => {
|
|
9687
9687
|
const { backfillArtistsCommand: backfillArtistsCommand2 } = await Promise.resolve().then(() => (init_admin_artists(), exports_admin_artists));
|
|
@@ -10376,42 +10376,39 @@ async function runBackfillAppleCatalogue(options, backfillAppleCatalogueCommand2
|
|
|
10376
10376
|
process.exitCode = 1;
|
|
10377
10377
|
}
|
|
10378
10378
|
}
|
|
10379
|
-
async function
|
|
10379
|
+
async function runBackfillLabelReleases(options, backfillLabelReleasesCommand2) {
|
|
10380
10380
|
const perPass = parseListLimit(options.limit);
|
|
10381
10381
|
const newTrackIds = [];
|
|
10382
|
-
const
|
|
10383
|
-
const
|
|
10382
|
+
const labelSlugs = [];
|
|
10383
|
+
const failedLabels = [];
|
|
10384
10384
|
let dryRun = options.dryRun;
|
|
10385
10385
|
let throttled = false;
|
|
10386
|
-
let breakerTripped = false;
|
|
10387
10386
|
let configured = true;
|
|
10388
10387
|
let labelsProbed = 0;
|
|
10389
10388
|
let albumsSeen = 0;
|
|
10389
|
+
let albumsMatched = 0;
|
|
10390
10390
|
let newRows = 0;
|
|
10391
10391
|
let skippedKnown = 0;
|
|
10392
10392
|
const MAX_PASSES = 100;
|
|
10393
10393
|
for (let pass = 0;pass < MAX_PASSES; pass += 1) {
|
|
10394
|
-
const result = await
|
|
10394
|
+
const result = await backfillLabelReleasesCommand2(perPass, options.dryRun);
|
|
10395
10395
|
dryRun = result.dryRun;
|
|
10396
10396
|
configured = result.configured;
|
|
10397
10397
|
labelsProbed += result.labelsProbed;
|
|
10398
10398
|
albumsSeen += result.albumsSeen;
|
|
10399
|
+
albumsMatched += result.albumsMatched;
|
|
10399
10400
|
newRows += result.newRows;
|
|
10400
10401
|
skippedKnown += result.skippedKnown;
|
|
10401
10402
|
newTrackIds.push(...result.newTrackIds);
|
|
10402
|
-
|
|
10403
|
-
|
|
10403
|
+
labelSlugs.push(...result.labelSlugs);
|
|
10404
|
+
failedLabels.push(...result.failedLabels);
|
|
10404
10405
|
if (!options.json) {
|
|
10405
10406
|
const verb2 = result.dryRun ? "would probe" : "probed";
|
|
10406
|
-
console.log(` \u2026${verb2} ${result.
|
|
10407
|
+
console.log(` \u2026${verb2} ${result.labelSlugs.length} label(s); ${result.albumsMatched} matched album(s); ${result.newRows} new; ${result.skippedKnown} known; ${result.failedLabels.length} failed`);
|
|
10407
10408
|
}
|
|
10408
10409
|
if (!result.configured) {
|
|
10409
10410
|
break;
|
|
10410
10411
|
}
|
|
10411
|
-
if (result.breakerTripped) {
|
|
10412
|
-
breakerTripped = true;
|
|
10413
|
-
break;
|
|
10414
|
-
}
|
|
10415
10412
|
if (result.rateLimited) {
|
|
10416
10413
|
throttled = true;
|
|
10417
10414
|
break;
|
|
@@ -10419,35 +10416,35 @@ async function runBackfillAppleReleases(options, backfillAppleReleasesCommand2)
|
|
|
10419
10416
|
if (result.dryRun) {
|
|
10420
10417
|
break;
|
|
10421
10418
|
}
|
|
10422
|
-
if (result.labelsProbed === 0
|
|
10419
|
+
if (result.labelsProbed === 0) {
|
|
10423
10420
|
break;
|
|
10424
10421
|
}
|
|
10425
10422
|
}
|
|
10426
10423
|
if (options.json) {
|
|
10427
10424
|
printSweepJson({
|
|
10425
|
+
albumsMatched,
|
|
10428
10426
|
albumsSeen,
|
|
10429
|
-
breakerTripped,
|
|
10430
10427
|
configured,
|
|
10431
10428
|
dryRun,
|
|
10429
|
+
failedLabels,
|
|
10430
|
+
labelSlugs,
|
|
10432
10431
|
labelsProbed,
|
|
10433
10432
|
newRows,
|
|
10434
10433
|
newTrackIds,
|
|
10435
10434
|
rateLimited: throttled,
|
|
10436
|
-
|
|
10437
|
-
skippedKnown,
|
|
10438
|
-
unresolvedLabels
|
|
10435
|
+
skippedKnown
|
|
10439
10436
|
}, 0);
|
|
10440
10437
|
return;
|
|
10441
10438
|
}
|
|
10442
10439
|
if (!configured) {
|
|
10443
|
-
console.log("
|
|
10440
|
+
console.log("Label-releases tap is a no-op \u2014 the Worker's Spotify grant is gone; reconnect Spotify.");
|
|
10444
10441
|
return;
|
|
10445
10442
|
}
|
|
10446
10443
|
const verb = dryRun ? "Would probe" : "Probed";
|
|
10447
|
-
const probedCount = dryRun ?
|
|
10448
|
-
console.log(`${verb} ${probedCount} enabled seed label(s); ${newRows} new catalogue row(s); ${skippedKnown} already known; ${
|
|
10449
|
-
for (const slug of
|
|
10450
|
-
console.log(`
|
|
10444
|
+
const probedCount = dryRun ? labelSlugs.length : labelsProbed;
|
|
10445
|
+
console.log(`${verb} ${probedCount} enabled seed label(s); ${albumsMatched} matched album(s); ${newRows} new catalogue row(s); ${skippedKnown} already known; ${failedLabels.length} failed.`);
|
|
10446
|
+
for (const slug of failedLabels) {
|
|
10447
|
+
console.log(` transient Spotify error: ${slug}`);
|
|
10451
10448
|
}
|
|
10452
10449
|
}
|
|
10453
10450
|
async function runBackfillArtists(options, backfillArtistsCommand2) {
|
package/package.json
CHANGED