fluncle 0.167.0 → 0.168.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 +87 -2
- 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.168.0".trim() ? "0.168.0".trim() : "0.1.0";
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
// src/update-notifier.ts
|
|
@@ -2229,7 +2229,7 @@ function parseVersion2(version) {
|
|
|
2229
2229
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2230
2230
|
var init_version2 = __esm(() => {
|
|
2231
2231
|
init_output();
|
|
2232
|
-
currentVersion2 = "0.
|
|
2232
|
+
currentVersion2 = "0.168.0".trim() ? "0.168.0".trim() : "0.1.0";
|
|
2233
2233
|
});
|
|
2234
2234
|
|
|
2235
2235
|
// ../../packages/registry/src/index.ts
|
|
@@ -3119,6 +3119,19 @@ var init_src = __esm(() => {
|
|
|
3119
3119
|
title: "Recording MBIDs",
|
|
3120
3120
|
weights: { status: "hidden" }
|
|
3121
3121
|
},
|
|
3122
|
+
{
|
|
3123
|
+
command: "fluncle admin backfills label-lineage",
|
|
3124
|
+
exposedContent: [
|
|
3125
|
+
"resolve each label's founding date + place + parent imprint from MusicBrainz → the labels row"
|
|
3126
|
+
],
|
|
3127
|
+
kind: "cron",
|
|
3128
|
+
name: "cron.label-lineage",
|
|
3129
|
+
operatorNotes: "every 60m, run by a rave-02 HOST systemd timer (docs/agents/hermes/label-lineage-timer/). The label entity's LINEAGE half (RFC label-lineage-remixer, U1): gives each label its founding facts + its place in the imprint hierarchy from MusicBrainz — `life-span.begin` → `founding_date`, `area.name` → `founded_location`, and the `backward` `label ownership` / `imprint` label-rels → `parent_label_id` (matched to an EXISTING label by MBID; NEVER minted — an unmatched parent is only counted). A dedicated sweep, not a rider on the label-image sweep, because that one is terminal per label and a logo-resolved label would never get its lineage: this carries its OWN `lineage_state` machine so it reaches every label once. METADATA ONLY — it certifies nothing, mints nothing, publishes nothing (agent tier, the `backfill_label_images` precedent). Worker-paced (the box holds no MusicBrainz budget): one bounded batch per tick, 1 req/s, circuit-broken on a throttle, reusing the shared MB client + exact-fold identity search. The `labels` row carries the durable reliability state (lineage_state/lineage_attempted_at/lineage_failures), so a resolved/none label is terminal. Emitted as the `/label/<slug>` Organization's `foundingDate` / `location` / `parentOrganization` / `subOrganization`. Zero LLM tokens. Source: docs/agents/hermes/scripts/label-lineage-sweep.*. See docs/label-entity.md.",
|
|
3130
|
+
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-label-lineage", kind: "cron" },
|
|
3131
|
+
statusDescription: "resolves each label's founding and imprint",
|
|
3132
|
+
title: "Label lineage",
|
|
3133
|
+
weights: { status: "hidden" }
|
|
3134
|
+
},
|
|
3122
3135
|
{
|
|
3123
3136
|
command: "fluncle admin backfills cover-masters",
|
|
3124
3137
|
exposedContent: [
|
|
@@ -6250,6 +6263,7 @@ __export(exports_admin_labels, {
|
|
|
6250
6263
|
labelsBioQueueCommand: () => labelsBioQueueCommand,
|
|
6251
6264
|
draftLabelBioCommand: () => draftLabelBioCommand,
|
|
6252
6265
|
describeLabelCommand: () => describeLabelCommand,
|
|
6266
|
+
backfillLabelLineageCommand: () => backfillLabelLineageCommand,
|
|
6253
6267
|
backfillLabelImagesCommand: () => backfillLabelImagesCommand
|
|
6254
6268
|
});
|
|
6255
6269
|
async function describeLabelCommand(slug, options) {
|
|
@@ -6269,6 +6283,13 @@ async function backfillLabelImagesCommand(limit, dryRun, cursor) {
|
|
|
6269
6283
|
}
|
|
6270
6284
|
return adminApiPost(`/api/admin/backfill/label-images?${params.toString()}`);
|
|
6271
6285
|
}
|
|
6286
|
+
async function backfillLabelLineageCommand(limit, dryRun, cursor) {
|
|
6287
|
+
const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
|
|
6288
|
+
if (cursor) {
|
|
6289
|
+
params.set("cursor", cursor);
|
|
6290
|
+
}
|
|
6291
|
+
return adminApiPost(`/api/admin/backfill/label-lineage?${params.toString()}`);
|
|
6292
|
+
}
|
|
6272
6293
|
var init_admin_labels = __esm(() => {
|
|
6273
6294
|
init_api();
|
|
6274
6295
|
init_admin_artists2();
|
|
@@ -9510,6 +9531,10 @@ function addAdminCommands(program2) {
|
|
|
9510
9531
|
const { backfillLabelImagesCommand: backfillLabelImagesCommand2 } = await Promise.resolve().then(() => (init_admin_labels(), exports_admin_labels));
|
|
9511
9532
|
await runBackfillLabelImages(options, backfillLabelImagesCommand2);
|
|
9512
9533
|
});
|
|
9534
|
+
backfill.command("label-lineage").description("Resolve label lineage (founding date, place, parent imprint) from MusicBrainz").option("--dry-run", "Report the eligible worklist without any vendor call or write", false).option("--limit <limit>", "Max labels to process", "50").option("--json", "Print JSON", false).action(async (options) => {
|
|
9535
|
+
const { backfillLabelLineageCommand: backfillLabelLineageCommand2 } = await Promise.resolve().then(() => (init_admin_labels(), exports_admin_labels));
|
|
9536
|
+
await runBackfillLabelLineage(options, backfillLabelLineageCommand2);
|
|
9537
|
+
});
|
|
9513
9538
|
backfill.command("recording-mbids").description("Fill MusicBrainz recording MBIDs (crawler PK strip + ISRC resolve) over tracks").option("--dry-run", "Report the eligible worklist without any vendor call or write", false).option("--limit <limit>", "Max ISRC lookups to process", "50").option("--json", "Print JSON", false).action(async (options) => {
|
|
9514
9539
|
const { backfillRecordingMbidsCommand: backfillRecordingMbidsCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
9515
9540
|
await runBackfillRecordingMbids(options, backfillRecordingMbidsCommand2);
|
|
@@ -10308,6 +10333,66 @@ async function runBackfillCoverMasters(options, backfillCoverMastersCommand2) {
|
|
|
10308
10333
|
process.exitCode = 1;
|
|
10309
10334
|
}
|
|
10310
10335
|
}
|
|
10336
|
+
async function runBackfillLabelLineage(options, backfillLabelLineageCommand2) {
|
|
10337
|
+
const limit = parseListLimit(options.limit);
|
|
10338
|
+
const resolved = [];
|
|
10339
|
+
const none = [];
|
|
10340
|
+
const failed = [];
|
|
10341
|
+
let cursor;
|
|
10342
|
+
let dryRun = options.dryRun;
|
|
10343
|
+
let throttled = false;
|
|
10344
|
+
let unmatchedParents = 0;
|
|
10345
|
+
while (resolved.length + none.length + failed.length < limit) {
|
|
10346
|
+
const remaining = limit - (resolved.length + none.length + failed.length);
|
|
10347
|
+
const result = await backfillLabelLineageCommand2(remaining, options.dryRun, cursor);
|
|
10348
|
+
dryRun = result.dryRun;
|
|
10349
|
+
resolved.push(...result.resolved);
|
|
10350
|
+
none.push(...result.none);
|
|
10351
|
+
failed.push(...result.failed);
|
|
10352
|
+
unmatchedParents += result.unmatchedParents;
|
|
10353
|
+
if (!options.json) {
|
|
10354
|
+
const verb2 = result.dryRun ? "would walk" : "walked";
|
|
10355
|
+
console.log(` \u2026${verb2} ${result.resolvedCount}; ${result.noneCount} with no MusicBrainz identity; ${result.failedCount} failed; ${result.unmatchedParents} unmatched parent(s)`);
|
|
10356
|
+
}
|
|
10357
|
+
if (result.rateLimited) {
|
|
10358
|
+
throttled = true;
|
|
10359
|
+
break;
|
|
10360
|
+
}
|
|
10361
|
+
if (result.nextCursor === null) {
|
|
10362
|
+
break;
|
|
10363
|
+
}
|
|
10364
|
+
cursor = result.nextCursor;
|
|
10365
|
+
}
|
|
10366
|
+
if (options.json) {
|
|
10367
|
+
printJson({
|
|
10368
|
+
dryRun,
|
|
10369
|
+
failed,
|
|
10370
|
+
failedCount: failed.length,
|
|
10371
|
+
none,
|
|
10372
|
+
noneCount: none.length,
|
|
10373
|
+
ok: true,
|
|
10374
|
+
rateLimited: throttled,
|
|
10375
|
+
resolved,
|
|
10376
|
+
resolvedCount: resolved.length,
|
|
10377
|
+
unmatchedParents
|
|
10378
|
+
});
|
|
10379
|
+
if (failed.length > 0) {
|
|
10380
|
+
process.exitCode = 1;
|
|
10381
|
+
}
|
|
10382
|
+
return;
|
|
10383
|
+
}
|
|
10384
|
+
const verb = dryRun ? "Would walk" : "Walked";
|
|
10385
|
+
console.log(`${verb} ${resolved.length} label lineage(s); ${none.length} with no MusicBrainz identity; ${failed.length} failed; ${unmatchedParents} unmatched parent(s).`);
|
|
10386
|
+
for (const slug of resolved) {
|
|
10387
|
+
console.log(` ${slug}`);
|
|
10388
|
+
}
|
|
10389
|
+
for (const item of failed) {
|
|
10390
|
+
console.log(` ${item.slug}: ${item.error}`);
|
|
10391
|
+
}
|
|
10392
|
+
if (failed.length > 0) {
|
|
10393
|
+
process.exitCode = 1;
|
|
10394
|
+
}
|
|
10395
|
+
}
|
|
10311
10396
|
async function runBackfillLabelImages(options, backfillLabelImagesCommand2) {
|
|
10312
10397
|
const limit = parseListLimit(options.limit);
|
|
10313
10398
|
const resolved = [];
|
package/package.json
CHANGED