fluncle 0.140.0 → 0.141.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 +91 -4
- 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.141.0".trim() ? "0.141.0".trim() : "0.1.0";
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
// src/update-notifier.ts
|
|
@@ -2189,7 +2189,7 @@ function parseVersion2(version) {
|
|
|
2189
2189
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2190
2190
|
var init_version2 = __esm(() => {
|
|
2191
2191
|
init_output();
|
|
2192
|
-
currentVersion2 = "0.
|
|
2192
|
+
currentVersion2 = "0.141.0".trim() ? "0.141.0".trim() : "0.1.0";
|
|
2193
2193
|
});
|
|
2194
2194
|
|
|
2195
2195
|
// ../../packages/registry/src/index.ts
|
|
@@ -2654,7 +2654,7 @@ var init_src = __esm(() => {
|
|
|
2654
2654
|
exposedContent: ["the XML sitemap index of every public page"],
|
|
2655
2655
|
kind: "discovery",
|
|
2656
2656
|
name: "discovery.sitemap",
|
|
2657
|
-
operatorNotes: "A sitemap INDEX, not a flat urlset: the URLs live in children at /sitemap/<kind>-<n>.xml (pages/findings/
|
|
2657
|
+
operatorNotes: "A sitemap INDEX, not a flat urlset: the URLs live in children at /sitemap/<kind>-<n>.xml, ONE CHILD PER ENTITY TYPE (pages/findings/artists/labels/albums/galaxies/logbook), each auto-paged under Google's 50,000-URL ceiling so a breach cannot happen rather than merely not having happened yet. robots.txt still names this one URL — a crawler discovers the children from here. Splitting per entity type is also the diagnostic: Search Console reports coverage PER sitemap, so each entity type gets its own submitted/indexed count.",
|
|
2658
2658
|
probeConfig: { cadenceMs: PROBE_CADENCE_MS, kind: "http", timeoutMs: PROBE_TIMEOUT_MS },
|
|
2659
2659
|
route: "/sitemap.xml",
|
|
2660
2660
|
url: `${SITE}/sitemap.xml`,
|
|
@@ -2662,7 +2662,9 @@ var init_src = __esm(() => {
|
|
|
2662
2662
|
},
|
|
2663
2663
|
{
|
|
2664
2664
|
apiFormat: "application/xml",
|
|
2665
|
-
exposedContent: [
|
|
2665
|
+
exposedContent: [
|
|
2666
|
+
"one child sitemap, per entity type: the pages / findings / artists / labels / albums / galaxies / logbook URLs, auto-paged"
|
|
2667
|
+
],
|
|
2666
2668
|
kind: "discovery",
|
|
2667
2669
|
name: "discovery.sitemap-shard",
|
|
2668
2670
|
probeConfig: { cadenceMs: PROBE_CADENCE_MS, kind: "http", timeoutMs: PROBE_TIMEOUT_MS },
|
|
@@ -2956,6 +2958,17 @@ var init_src = __esm(() => {
|
|
|
2956
2958
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-label-images", kind: "cron" },
|
|
2957
2959
|
weights: { status: "hidden" }
|
|
2958
2960
|
},
|
|
2961
|
+
{
|
|
2962
|
+
command: "fluncle admin backfills cover-masters",
|
|
2963
|
+
exposedContent: [
|
|
2964
|
+
"resolve each pending album/artist its OWN ≤1200² cover master (best source wins) → its own R2 image"
|
|
2965
|
+
],
|
|
2966
|
+
kind: "cron",
|
|
2967
|
+
name: "cron.cover-masters",
|
|
2968
|
+
operatorNotes: "every 60m, run by a rave-02 HOST systemd timer (docs/agents/hermes/cover-masters-timer/). The DURABLE other half of the album/artist cover (RFC musickit-second-authority U3b): the publish path + catalogue crawl MINT albums/artists (each `image_state='pending'`) and this cron gives each its OWN ≤1200²-capped cover derivative in R2 (found.fluncle.com, `albums/<slug>.<ext>` / `artists/<slug>.<ext>`) instead of hotlinking a third party — the label-logo posture, two entities over. IMAGE ONLY — a downscaled display derivative, reversible, the REF-05-conscious 1200 line (docs/album-artwork.md); it certifies nothing and publishes nothing (agent tier, the `backfill_label_images` precedent). Worker-paced: one bounded batch of albums (Apple template → Cover Art Archive → Spotify floor), then one of artists (Spotify floor), per tick; every rung requests a ≤1200 rendition and a byte read enforces the cap before the R2 put, so no un-downscaled original is ever stored. The `albums`/`artists` row carries the durable reliability state (image_state/image_attempted_at/image_failures), so a resolved/none entity is terminal. Served via Cloudflare Images `/cdn-cgi/image/…` (decision B). Zero LLM tokens. Source: docs/agents/hermes/scripts/cover-masters-sweep.*. See docs/album-artwork.md.",
|
|
2969
|
+
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-cover-masters", kind: "cron" },
|
|
2970
|
+
weights: { status: "hidden" }
|
|
2971
|
+
},
|
|
2959
2972
|
{
|
|
2960
2973
|
command: "fluncle admin tracks capture-audio --queue",
|
|
2961
2974
|
exposedContent: [
|
|
@@ -5792,6 +5805,22 @@ var init_admin_labels = __esm(() => {
|
|
|
5792
5805
|
init_api();
|
|
5793
5806
|
});
|
|
5794
5807
|
|
|
5808
|
+
// src/commands/admin-covers.ts
|
|
5809
|
+
var exports_admin_covers = {};
|
|
5810
|
+
__export(exports_admin_covers, {
|
|
5811
|
+
backfillCoverMastersCommand: () => backfillCoverMastersCommand
|
|
5812
|
+
});
|
|
5813
|
+
async function backfillCoverMastersCommand(kind, limit, dryRun, cursor) {
|
|
5814
|
+
const params = new URLSearchParams({ dryRun: String(dryRun), kind, limit: String(limit) });
|
|
5815
|
+
if (cursor) {
|
|
5816
|
+
params.set("cursor", cursor);
|
|
5817
|
+
}
|
|
5818
|
+
return adminApiPost(`/api/admin/backfill/cover-masters?${params.toString()}`);
|
|
5819
|
+
}
|
|
5820
|
+
var init_admin_covers = __esm(() => {
|
|
5821
|
+
init_api();
|
|
5822
|
+
});
|
|
5823
|
+
|
|
5795
5824
|
// src/commands/preview-migration.ts
|
|
5796
5825
|
var exports_preview_migration = {};
|
|
5797
5826
|
__export(exports_preview_migration, {
|
|
@@ -8829,6 +8858,10 @@ function addAdminCommands(program2) {
|
|
|
8829
8858
|
const { backfillLabelImagesCommand: backfillLabelImagesCommand2 } = await Promise.resolve().then(() => (init_admin_labels(), exports_admin_labels));
|
|
8830
8859
|
await runBackfillLabelImages(options, backfillLabelImagesCommand2);
|
|
8831
8860
|
});
|
|
8861
|
+
backfill.command("cover-masters").description("Resolve owned \u22641200\xB2 cover masters (album/artist) into R2").option("--kind <kind>", "Which entity to drain: album | artist", "album").option("--dry-run", "Report the eligible worklist without any fetch or write", false).option("--limit <limit>", "Max entities to process", "50").option("--json", "Print JSON", false).action(async (options) => {
|
|
8862
|
+
const { backfillCoverMastersCommand: backfillCoverMastersCommand2 } = await Promise.resolve().then(() => (init_admin_covers(), exports_admin_covers));
|
|
8863
|
+
await runBackfillCoverMasters(options, backfillCoverMastersCommand2);
|
|
8864
|
+
});
|
|
8832
8865
|
artists.command("resolve").description("Resolve an artist's social identity (MB url-rels + Firecrawl gap-fill)").argument("[artistId]").option("--queue", "Show the resolve worklist (artists awaiting resolution), oldest first", false).option("--limit <limit>", "Number of artists to show with --queue", "50").option("--json", "Print JSON", false).allowExcessArguments().action(async (artistId, options) => {
|
|
8833
8866
|
if (options.queue) {
|
|
8834
8867
|
const { listArtistsCommand: listArtistsCommand2 } = await Promise.resolve().then(() => (init_admin_artists(), exports_admin_artists));
|
|
@@ -9461,6 +9494,60 @@ async function runBackfillArtistImages(options, backfillArtistImagesCommand2) {
|
|
|
9461
9494
|
process.exitCode = 1;
|
|
9462
9495
|
}
|
|
9463
9496
|
}
|
|
9497
|
+
async function runBackfillCoverMasters(options, backfillCoverMastersCommand2) {
|
|
9498
|
+
const limit = parseListLimit(options.limit);
|
|
9499
|
+
const kind = options.kind === "artist" ? "artist" : "album";
|
|
9500
|
+
const resolved = [];
|
|
9501
|
+
const none = [];
|
|
9502
|
+
const failed = [];
|
|
9503
|
+
let cursor;
|
|
9504
|
+
let dryRun = options.dryRun;
|
|
9505
|
+
while (resolved.length + none.length + failed.length < limit) {
|
|
9506
|
+
const remaining = limit - (resolved.length + none.length + failed.length);
|
|
9507
|
+
const result = await backfillCoverMastersCommand2(kind, remaining, options.dryRun, cursor);
|
|
9508
|
+
dryRun = result.dryRun;
|
|
9509
|
+
resolved.push(...result.resolved);
|
|
9510
|
+
none.push(...result.none);
|
|
9511
|
+
failed.push(...result.failed);
|
|
9512
|
+
if (!options.json) {
|
|
9513
|
+
const verb2 = result.dryRun ? "would resolve" : "resolved";
|
|
9514
|
+
console.log(` \u2026${verb2} ${result.resolvedCount}; ${result.noneCount} without a source; ${result.failedCount} failed`);
|
|
9515
|
+
}
|
|
9516
|
+
if (result.nextCursor === null) {
|
|
9517
|
+
break;
|
|
9518
|
+
}
|
|
9519
|
+
cursor = result.nextCursor;
|
|
9520
|
+
}
|
|
9521
|
+
if (options.json) {
|
|
9522
|
+
printJson({
|
|
9523
|
+
dryRun,
|
|
9524
|
+
failed,
|
|
9525
|
+
failedCount: failed.length,
|
|
9526
|
+
kind,
|
|
9527
|
+
none,
|
|
9528
|
+
noneCount: none.length,
|
|
9529
|
+
ok: true,
|
|
9530
|
+
rateLimited: false,
|
|
9531
|
+
resolved,
|
|
9532
|
+
resolvedCount: resolved.length
|
|
9533
|
+
});
|
|
9534
|
+
if (failed.length > 0) {
|
|
9535
|
+
process.exitCode = 1;
|
|
9536
|
+
}
|
|
9537
|
+
return;
|
|
9538
|
+
}
|
|
9539
|
+
const verb = dryRun ? "Would resolve" : "Resolved";
|
|
9540
|
+
console.log(`${verb} ${resolved.length} ${kind} cover master(s); ${none.length} without a source; ${failed.length} failed.`);
|
|
9541
|
+
for (const slug of resolved) {
|
|
9542
|
+
console.log(` ${slug}`);
|
|
9543
|
+
}
|
|
9544
|
+
for (const item of failed) {
|
|
9545
|
+
console.log(` ${item.slug}: ${item.error}`);
|
|
9546
|
+
}
|
|
9547
|
+
if (failed.length > 0) {
|
|
9548
|
+
process.exitCode = 1;
|
|
9549
|
+
}
|
|
9550
|
+
}
|
|
9464
9551
|
async function runBackfillLabelImages(options, backfillLabelImagesCommand2) {
|
|
9465
9552
|
const limit = parseListLimit(options.limit);
|
|
9466
9553
|
const resolved = [];
|
package/package.json
CHANGED