fluncle 0.242.0 → 0.244.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 +75 -7
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -622,7 +622,7 @@ function parseVersion(version) {
|
|
|
622
622
|
var currentVersion;
|
|
623
623
|
var init_version = __esm(() => {
|
|
624
624
|
init_output();
|
|
625
|
-
currentVersion = "0.
|
|
625
|
+
currentVersion = "0.244.0".trim() ? "0.244.0".trim() : "0.1.0";
|
|
626
626
|
});
|
|
627
627
|
|
|
628
628
|
// src/update-notifier.ts
|
|
@@ -2335,7 +2335,7 @@ function parseVersion2(version) {
|
|
|
2335
2335
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2336
2336
|
var init_version2 = __esm(() => {
|
|
2337
2337
|
init_output();
|
|
2338
|
-
currentVersion2 = "0.
|
|
2338
|
+
currentVersion2 = "0.244.0".trim() ? "0.244.0".trim() : "0.1.0";
|
|
2339
2339
|
});
|
|
2340
2340
|
|
|
2341
2341
|
// ../../packages/registry/src/index.ts
|
|
@@ -3909,7 +3909,7 @@ var init_src = __esm(() => {
|
|
|
3909
3909
|
weights: { status: "hidden" }
|
|
3910
3910
|
},
|
|
3911
3911
|
{
|
|
3912
|
-
command: "fluncle admin projections get --json; fluncle admin projections advance --target <track_due_work|crawl_due_work> --action repair --limit 500 --max-steps
|
|
3912
|
+
command: "fluncle admin projections get --json; fluncle admin projections advance --target <track_due_work|crawl_due_work> --action repair --limit 500 --max-steps <adaptive> --no-terminal-status --json; fluncle admin projections advance --target <public_aggregates|artist_qualification> --action repair --limit 500 --max-steps <adaptive> --no-terminal-status --json",
|
|
3913
3913
|
exposedContent: [
|
|
3914
3914
|
"keep all four runtime projection families converged after their cutovers with one-read, serial, bounded repair (--no-agent)"
|
|
3915
3915
|
],
|
|
@@ -11435,7 +11435,7 @@ var init_admin_bios = __esm(() => {
|
|
|
11435
11435
|
});
|
|
11436
11436
|
|
|
11437
11437
|
// ../../packages/contracts/src/orpc/admin-catalogue.ts
|
|
11438
|
-
var CatalogueLensSchema, CapturePriorityReasonSchema, CatalogueMatchSchema, CatalogueTrackItemSchema, CatalogueSummarySchema, listCatalogueTracks, rankCatalogue, recordDemand, clearWrongAudio, requeueUnmatchedCaptures, requeueAnchor, requeueIsrcRecovery, flagWrongAudio, forceCapture, certifyTrack, setTrackDismissed, CaptureVerifyItemSchema, listUnverifiedCaptures, verifyCapture, CrawlPassSchema, CrawlPhaseInitializationSchema, MAX_CRAWL_PREPARE_LIMIT = 6, CrawlFetchPlanSchema, SuppliedCrawlBodySchema, MAX_CRAWL_COMMIT_BATCH, CRAWL_COMMIT_TOKEN_MAX_BYTES, CRAWL_COMMIT_BATCH_MAX_TOTAL_BYTES, CrawlCommitItemSchema, CrawlCommitReceiptSchema, CrawlPhaseCapabilitiesSchema, CrawlPhaseInputSchema, CrawlPhaseOutputSchema, CrawlStatusSchema, crawlCatalogue, commitCrawlNodes, getCrawlStatus, ANCHOR_CANDIDATE_LIMIT = 100, ANCHOR_ARTIST_LIMIT = 20, ANCHOR_TEXT_MAX = 300, ANCHOR_ISRC_MAX = 64, ANCHOR_ID_MAX = 64, ANCHOR_URL_MAX = 2048, AnchorCandidateSchema, anchorTrack, DEEZER_CANDIDATE_LIMIT = 5, DEEZER_TEXT_MAX = 300, DEEZER_ISRC_MAX = 64, DEEZER_TRACK_ID_MAX = 32, DeezerIsrcCandidateSchema, resolveAnchor, resolveAnchorReview, setAnchorSearch, setAnchorApify, CaptureBudgetStateSchema, getCaptureBudget, setCaptureBudget, SpotifyAnchorBreakerStateSchema, AnchorRungFlagsSchema, getSpotifyAnchorBreaker, resetSpotifyAnchorBreaker, AppleBreakerStateSchema, resetAppleBreaker, adminCatalogueContract;
|
|
11438
|
+
var CatalogueLensSchema, CapturePriorityReasonSchema, CatalogueMatchSchema, CatalogueTrackItemSchema, CatalogueSummarySchema, listCatalogueTracks, rankCatalogue, recordDemand, clearWrongAudio, requeueUnmatchedCaptures, requeueAnchor, requeueIsrcRecovery, flagWrongAudio, forceCapture, certifyTrack, setTrackDismissed, CaptureVerifyItemSchema, listUnverifiedCaptures, verifyCapture, CrawlPassSchema, CrawlPhaseInitializationSchema, MAX_CRAWL_PREPARE_LIMIT = 6, CrawlFetchPlanSchema, SuppliedCrawlBodySchema, MAX_CRAWL_COMMIT_BATCH, CRAWL_COMMIT_TOKEN_MAX_BYTES, CRAWL_COMMIT_BATCH_MAX_TOTAL_BYTES, CrawlCommitItemSchema, CrawlCommitReceiptSchema, CrawlPhaseCapabilitiesSchema, CrawlPhaseInputSchema, CrawlPhaseOutputSchema, CrawlStatusSchema, crawlCatalogue, commitCrawlNodes, getCrawlStatus, ANCHOR_CANDIDATE_LIMIT = 100, ANCHOR_ARTIST_LIMIT = 20, ANCHOR_TEXT_MAX = 300, ANCHOR_ISRC_MAX = 64, ANCHOR_ID_MAX = 64, ANCHOR_URL_MAX = 2048, AnchorCandidateSchema, anchorTrack, DEEZER_CANDIDATE_LIMIT = 5, DEEZER_TEXT_MAX = 300, DEEZER_ISRC_MAX = 64, DEEZER_TRACK_ID_MAX = 32, DeezerIsrcCandidateSchema, resolveAnchor, resolveAnchorReview, setAnchorSearch, setAnchorApify, CaptureBudgetStateSchema, getCaptureBudget, setCaptureBudget, AnchorApifyBudgetSchema, getAnchorApifyBudget, setAnchorApifyBudget, SpotifyAnchorBreakerStateSchema, AnchorRungFlagsSchema, getSpotifyAnchorBreaker, resetSpotifyAnchorBreaker, AppleBreakerStateSchema, resetAppleBreaker, adminCatalogueContract;
|
|
11439
11439
|
var init_admin_catalogue = __esm(() => {
|
|
11440
11440
|
init_dist3();
|
|
11441
11441
|
init_zod();
|
|
@@ -11896,7 +11896,10 @@ var init_admin_catalogue = __esm(() => {
|
|
|
11896
11896
|
trackId: string2().min(1)
|
|
11897
11897
|
})).output(object({
|
|
11898
11898
|
anchored: boolean2(),
|
|
11899
|
+
apifyBudgetRemaining: number2().int().nonnegative(),
|
|
11900
|
+
apifyEligible: boolean2(),
|
|
11899
11901
|
apifyEnabled: boolean2(),
|
|
11902
|
+
apifyIneligibleReason: _enum(["apify_budget_spent", "awaiting_free_ask"]).nullable(),
|
|
11900
11903
|
freeDurationMsOmitted: number2().int().nonnegative(),
|
|
11901
11904
|
isrcRecoveredByDeezer: boolean2(),
|
|
11902
11905
|
listenbrainzOutcome: _enum([
|
|
@@ -11978,6 +11981,27 @@ var init_admin_catalogue = __esm(() => {
|
|
|
11978
11981
|
dailyTracks: number2().int().min(0).optional(),
|
|
11979
11982
|
paused: boolean2().optional()
|
|
11980
11983
|
})).output(CaptureBudgetStateSchema.extend({ ok: literal(true) }));
|
|
11984
|
+
AnchorApifyBudgetSchema = object({
|
|
11985
|
+
dailyRows: number2(),
|
|
11986
|
+
day: string2(),
|
|
11987
|
+
remainingRows: number2(),
|
|
11988
|
+
rowsSent: number2(),
|
|
11989
|
+
spent: boolean2()
|
|
11990
|
+
}).meta({ id: "AnchorApifyBudget" });
|
|
11991
|
+
getAnchorApifyBudget = oc.route({
|
|
11992
|
+
method: "GET",
|
|
11993
|
+
operationId: "getAnchorApifyBudget",
|
|
11994
|
+
path: "/admin/catalogue/anchor/apify-budget",
|
|
11995
|
+
summary: "The metered Apify anchor rung's daily row cap, today's spend, and what is left",
|
|
11996
|
+
tags: ["Admin"]
|
|
11997
|
+
}).input(object({})).output(AnchorApifyBudgetSchema.extend({ ok: literal(true) }));
|
|
11998
|
+
setAnchorApifyBudget = oc.route({
|
|
11999
|
+
method: "PUT",
|
|
12000
|
+
operationId: "setAnchorApifyBudget",
|
|
12001
|
+
path: "/admin/catalogue/anchor/apify-budget",
|
|
12002
|
+
summary: "Set the metered Apify anchor rung's daily row cap (operator)",
|
|
12003
|
+
tags: ["Admin"]
|
|
12004
|
+
}).input(object({ dailyRows: number2().int().min(0) })).output(AnchorApifyBudgetSchema.extend({ ok: literal(true) }));
|
|
11981
12005
|
SpotifyAnchorBreakerStateSchema = object({
|
|
11982
12006
|
cooldownRemainingMs: number2(),
|
|
11983
12007
|
reason: string2().nullable(),
|
|
@@ -11986,6 +12010,7 @@ var init_admin_catalogue = __esm(() => {
|
|
|
11986
12010
|
trippedAt: string2().nullable()
|
|
11987
12011
|
}).meta({ id: "SpotifyAnchorBreakerState" });
|
|
11988
12012
|
AnchorRungFlagsSchema = object({
|
|
12013
|
+
apifyBudget: AnchorApifyBudgetSchema,
|
|
11989
12014
|
apifyEnabled: boolean2(),
|
|
11990
12015
|
spotifySearchEnabled: boolean2()
|
|
11991
12016
|
}).meta({ id: "AnchorRungFlags" });
|
|
@@ -12024,6 +12049,7 @@ var init_admin_catalogue = __esm(() => {
|
|
|
12024
12049
|
crawl_catalogue: crawlCatalogue,
|
|
12025
12050
|
flag_wrong_audio: flagWrongAudio,
|
|
12026
12051
|
force_capture: forceCapture,
|
|
12052
|
+
get_anchor_apify_budget: getAnchorApifyBudget,
|
|
12027
12053
|
get_capture_budget: getCaptureBudget,
|
|
12028
12054
|
get_crawl_status: getCrawlStatus,
|
|
12029
12055
|
get_spotify_anchor_breaker: getSpotifyAnchorBreaker,
|
|
@@ -12039,6 +12065,7 @@ var init_admin_catalogue = __esm(() => {
|
|
|
12039
12065
|
resolve_anchor: resolveAnchor,
|
|
12040
12066
|
resolve_anchor_review: resolveAnchorReview,
|
|
12041
12067
|
set_anchor_apify: setAnchorApify,
|
|
12068
|
+
set_anchor_apify_budget: setAnchorApifyBudget,
|
|
12042
12069
|
set_anchor_search: setAnchorSearch,
|
|
12043
12070
|
set_capture_budget: setCaptureBudget,
|
|
12044
12071
|
set_track_dismissed: setTrackDismissed,
|
|
@@ -15167,11 +15194,13 @@ var init_admin_tracks = __esm(() => {
|
|
|
15167
15194
|
tags: ["Admin"]
|
|
15168
15195
|
}).input(object({
|
|
15169
15196
|
count: string2().optional(),
|
|
15197
|
+
debtAware: string2().optional(),
|
|
15170
15198
|
kind: TrackWorkKindSchema,
|
|
15171
15199
|
limit: number3().int().min(1).max(250).default(50),
|
|
15172
15200
|
scope: TrackWorkScopeSchema.default("all")
|
|
15173
15201
|
})).output(object({
|
|
15174
15202
|
capabilities: TrackWorkCapabilitiesSchema.optional(),
|
|
15203
|
+
debtPending: boolean2().optional(),
|
|
15175
15204
|
ok: literal(true),
|
|
15176
15205
|
queued: number2().optional(),
|
|
15177
15206
|
tracks: array(TrackWorkItemSchema)
|
|
@@ -17183,9 +17212,14 @@ async function trackWorkCommand(options) {
|
|
|
17183
17212
|
});
|
|
17184
17213
|
if (options.count) {
|
|
17185
17214
|
params.set("count", "true");
|
|
17215
|
+
params.set("debtAware", "true");
|
|
17186
17216
|
}
|
|
17187
17217
|
const response = await adminApiGet(`/api/v1/admin/tracks/work?${params.toString()}`);
|
|
17188
|
-
return {
|
|
17218
|
+
return {
|
|
17219
|
+
debtPending: response.debtPending,
|
|
17220
|
+
queued: response.queued,
|
|
17221
|
+
tracks: response.tracks ?? []
|
|
17222
|
+
};
|
|
17189
17223
|
}
|
|
17190
17224
|
async function requeueAnalysisCommand(options) {
|
|
17191
17225
|
const findings = await fetchAdminTracks({ max: options.max, order: "asc" });
|
|
@@ -18735,6 +18769,12 @@ async function requeueAnchorCommand(trackIds) {
|
|
|
18735
18769
|
async function requeueIsrcRecoveryCommand(input) {
|
|
18736
18770
|
return adminApiPost("/api/v1/admin/catalogue/isrc-recovery/requeue", input);
|
|
18737
18771
|
}
|
|
18772
|
+
async function anchorApifyBudgetCommand() {
|
|
18773
|
+
return adminApiGet("/api/v1/admin/catalogue/anchor/apify-budget");
|
|
18774
|
+
}
|
|
18775
|
+
async function setAnchorApifyBudgetCommand(dailyRows) {
|
|
18776
|
+
return adminApiPut("/api/v1/admin/catalogue/anchor/apify-budget", { dailyRows });
|
|
18777
|
+
}
|
|
18738
18778
|
async function anchorBreakerCommand() {
|
|
18739
18779
|
return adminApiGet("/api/v1/admin/catalogue/anchor/breaker");
|
|
18740
18780
|
}
|
|
@@ -22420,10 +22460,24 @@ JSON field reference:
|
|
|
22420
22460
|
const minutes = Math.ceil(state.cooldownRemainingMs / 60000);
|
|
22421
22461
|
console.log(state.tripped ? `BREAKER TRIPPED \u2014 ${state.reason ?? "unknown"}, ~${minutes}m left (${state.throttlesInWindow} throttle(s) in window)` : `BREAKER CLEAR \u2014 ${state.throttlesInWindow} throttle(s) in window`);
|
|
22422
22462
|
console.log(`RUNGS \u2014 spotify search ${state.rungs.spotifySearchEnabled ? "ARMED" : "OFF"} \xB7 apify fallback ${state.rungs.apifyEnabled ? "ARMED" : "OFF"}`);
|
|
22463
|
+
const budget = state.rungs.apifyBudget;
|
|
22464
|
+
console.log(`APIFY BUDGET \u2014 ${budget.rowsSent}/${budget.dailyRows} rows today \xB7 ${budget.remainingRows} left${budget.spent ? " \xB7 SPENT" : ""}`);
|
|
22423
22465
|
if (!state.rungs.spotifySearchEnabled && !state.rungs.apifyEnabled) {
|
|
22424
22466
|
console.log("No rung can conclude \u2014 ListenBrainz still runs and can win, but its miss settles nothing.");
|
|
22425
22467
|
}
|
|
22426
22468
|
});
|
|
22469
|
+
const anchorApifyBudget = catalogue.command("anchor-apify-budget").description("The paid Apify anchor rung's daily row cap, today's spend, and what is left").option("--json", "Print JSON", false).action(async (options) => {
|
|
22470
|
+
await Promise.resolve().then(() => init_admin_catalogue2());
|
|
22471
|
+
printAnchorApifyBudget(await anchorApifyBudgetCommand(), options);
|
|
22472
|
+
});
|
|
22473
|
+
anchorApifyBudget.command("set").description("Set the paid Apify anchor rung's daily row cap (operator)").requiredOption("--rows <n>", "Max catalogue rows sent to the Apify actor per UTC day").option("--json", "Print JSON", false).action(async (options) => {
|
|
22474
|
+
const dailyRows = Number(options.rows);
|
|
22475
|
+
if (!Number.isInteger(dailyRows) || dailyRows < 0) {
|
|
22476
|
+
throw new Error("--rows must be a non-negative whole number of rows");
|
|
22477
|
+
}
|
|
22478
|
+
await Promise.resolve().then(() => init_admin_catalogue2());
|
|
22479
|
+
printAnchorApifyBudget(await setAnchorApifyBudgetCommand(dailyRows), options);
|
|
22480
|
+
});
|
|
22427
22481
|
catalogue.command("requeue-isrc-recovery").description("Clear Deezer-empty ISRC-recovery stamps from a window (dry-run; --apply to take)").requiredOption("--since <iso>", "Inclusive lower bound on the stamp (2026-09-09)").option("--apply", "Actually clear the stamps (default is a dry-run count)", false).option("--json", "Print JSON", false).action(async (options) => {
|
|
22428
22482
|
await Promise.resolve().then(() => init_admin_catalogue2());
|
|
22429
22483
|
const result = await requeueIsrcRecoveryCommand({
|
|
@@ -24472,6 +24526,15 @@ async function runPublishAdvance(options, publishAdvanceCommand) {
|
|
|
24472
24526
|
console.log(`Failed ${failure.platform} for ${failure.trackId} \u2014 left for the operator.`);
|
|
24473
24527
|
}
|
|
24474
24528
|
}
|
|
24529
|
+
function printAnchorApifyBudget(state, options) {
|
|
24530
|
+
if (options.json) {
|
|
24531
|
+
printJson({ ...state, ok: true });
|
|
24532
|
+
return;
|
|
24533
|
+
}
|
|
24534
|
+
console.log(state.spent ? `APIFY ROWS SPENT for ${state.day} \u2014 the paid anchor rung sends nothing more today.` : `APIFY ROWS OPEN for ${state.day} \u2014 the paid anchor rung may still be sent rows.`);
|
|
24535
|
+
console.log(` Today: ${state.rowsSent} of ${state.dailyRows} row(s)`);
|
|
24536
|
+
console.log(` Left: ${state.remainingRows} row(s)`);
|
|
24537
|
+
}
|
|
24475
24538
|
var GB = 1073741824;
|
|
24476
24539
|
function formatGb(bytes) {
|
|
24477
24540
|
return `${(bytes / GB).toFixed(2)} GB`;
|
|
@@ -25335,14 +25398,18 @@ async function runAdminTrackWork(options, trackWorkCommand) {
|
|
|
25335
25398
|
process.exitCode = 1;
|
|
25336
25399
|
return;
|
|
25337
25400
|
}
|
|
25338
|
-
const { queued, tracks } = await trackWorkCommand({
|
|
25401
|
+
const { debtPending, queued, tracks } = await trackWorkCommand({
|
|
25339
25402
|
count: options.count,
|
|
25340
25403
|
kind,
|
|
25341
25404
|
limit: parseListLimit(options.limit),
|
|
25342
25405
|
scope
|
|
25343
25406
|
});
|
|
25344
25407
|
if (options.json) {
|
|
25345
|
-
printJson({ ok: true, queued, tracks });
|
|
25408
|
+
printJson({ debtPending, ok: true, queued, tracks });
|
|
25409
|
+
return;
|
|
25410
|
+
}
|
|
25411
|
+
if (debtPending === true) {
|
|
25412
|
+
console.log(`${queued ?? 0} queued to ${kind} (${scope}) \u2014 page held back, due-work repair is still converging.`);
|
|
25346
25413
|
return;
|
|
25347
25414
|
}
|
|
25348
25415
|
if (tracks.length === 0) {
|
|
@@ -25720,6 +25787,7 @@ var stringOptions = new Set([
|
|
|
25720
25787
|
"--reasoning",
|
|
25721
25788
|
"--recorded-at",
|
|
25722
25789
|
"--recording",
|
|
25790
|
+
"--rows",
|
|
25723
25791
|
"--rules-file",
|
|
25724
25792
|
"--render",
|
|
25725
25793
|
"--scene",
|
package/package.json
CHANGED