fluncle 0.174.0 → 0.176.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 +41 -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.176.0".trim() ? "0.176.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.176.0".trim() ? "0.176.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,43 @@ 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
|
+
let failedFetches = 0;
|
|
10393
|
+
let fetchCeilingHit = false;
|
|
10392
10394
|
const MAX_PASSES = 100;
|
|
10393
10395
|
for (let pass = 0;pass < MAX_PASSES; pass += 1) {
|
|
10394
|
-
const result = await
|
|
10396
|
+
const result = await backfillLabelReleasesCommand2(perPass, options.dryRun);
|
|
10395
10397
|
dryRun = result.dryRun;
|
|
10396
10398
|
configured = result.configured;
|
|
10397
10399
|
labelsProbed += result.labelsProbed;
|
|
10398
10400
|
albumsSeen += result.albumsSeen;
|
|
10401
|
+
albumsMatched += result.albumsMatched;
|
|
10399
10402
|
newRows += result.newRows;
|
|
10400
10403
|
skippedKnown += result.skippedKnown;
|
|
10404
|
+
failedFetches += result.failedFetches;
|
|
10405
|
+
fetchCeilingHit = fetchCeilingHit || result.fetchCeilingHit;
|
|
10401
10406
|
newTrackIds.push(...result.newTrackIds);
|
|
10402
|
-
|
|
10403
|
-
|
|
10407
|
+
labelSlugs.push(...result.labelSlugs);
|
|
10408
|
+
failedLabels.push(...result.failedLabels);
|
|
10404
10409
|
if (!options.json) {
|
|
10405
10410
|
const verb2 = result.dryRun ? "would probe" : "probed";
|
|
10406
|
-
console.log(` \u2026${verb2} ${result.
|
|
10411
|
+
console.log(` \u2026${verb2} ${result.labelSlugs.length} label(s); ${result.albumsMatched} matched album(s); ${result.newRows} new; ${result.skippedKnown} known; ${result.failedFetches} fetch-fail; ${result.failedLabels.length} search-fail`);
|
|
10407
10412
|
}
|
|
10408
10413
|
if (!result.configured) {
|
|
10409
10414
|
break;
|
|
10410
10415
|
}
|
|
10411
|
-
if (result.breakerTripped) {
|
|
10412
|
-
breakerTripped = true;
|
|
10413
|
-
break;
|
|
10414
|
-
}
|
|
10415
10416
|
if (result.rateLimited) {
|
|
10416
10417
|
throttled = true;
|
|
10417
10418
|
break;
|
|
@@ -10419,35 +10420,40 @@ async function runBackfillAppleReleases(options, backfillAppleReleasesCommand2)
|
|
|
10419
10420
|
if (result.dryRun) {
|
|
10420
10421
|
break;
|
|
10421
10422
|
}
|
|
10422
|
-
if (result.labelsProbed === 0
|
|
10423
|
+
if (result.labelsProbed === 0) {
|
|
10423
10424
|
break;
|
|
10424
10425
|
}
|
|
10425
10426
|
}
|
|
10426
10427
|
if (options.json) {
|
|
10427
10428
|
printSweepJson({
|
|
10429
|
+
albumsMatched,
|
|
10428
10430
|
albumsSeen,
|
|
10429
|
-
breakerTripped,
|
|
10430
10431
|
configured,
|
|
10431
10432
|
dryRun,
|
|
10433
|
+
failedFetches,
|
|
10434
|
+
failedLabels,
|
|
10435
|
+
fetchCeilingHit,
|
|
10436
|
+
labelSlugs,
|
|
10432
10437
|
labelsProbed,
|
|
10433
10438
|
newRows,
|
|
10434
10439
|
newTrackIds,
|
|
10435
10440
|
rateLimited: throttled,
|
|
10436
|
-
|
|
10437
|
-
skippedKnown,
|
|
10438
|
-
unresolvedLabels
|
|
10441
|
+
skippedKnown
|
|
10439
10442
|
}, 0);
|
|
10440
10443
|
return;
|
|
10441
10444
|
}
|
|
10442
10445
|
if (!configured) {
|
|
10443
|
-
console.log("
|
|
10446
|
+
console.log("Label-releases tap is a no-op \u2014 the Worker's Spotify grant is gone; reconnect Spotify.");
|
|
10444
10447
|
return;
|
|
10445
10448
|
}
|
|
10446
10449
|
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
|
-
|
|
10450
|
-
console.log(
|
|
10450
|
+
const probedCount = dryRun ? labelSlugs.length : labelsProbed;
|
|
10451
|
+
console.log(`${verb} ${probedCount} enabled seed label(s); ${albumsMatched} matched album(s); ${newRows} new catalogue row(s); ${skippedKnown} already known; ${failedFetches} fetch-fail; ${failedLabels.length} search-fail.`);
|
|
10452
|
+
if (fetchCeilingHit) {
|
|
10453
|
+
console.log(" (a pass ended early on the single-fetch ceiling \u2014 resumes next tick)");
|
|
10454
|
+
}
|
|
10455
|
+
for (const slug of failedLabels) {
|
|
10456
|
+
console.log(` search error: ${slug}`);
|
|
10451
10457
|
}
|
|
10452
10458
|
}
|
|
10453
10459
|
async function runBackfillArtists(options, backfillArtistsCommand2) {
|
package/package.json
CHANGED