fluncle 0.243.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.
Files changed (2) hide show
  1. package/bin/fluncle.mjs +60 -3
  2. 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.243.0".trim() ? "0.243.0".trim() : "0.1.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.243.0".trim() ? "0.243.0".trim() : "0.1.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
@@ -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,
@@ -18742,6 +18769,12 @@ async function requeueAnchorCommand(trackIds) {
18742
18769
  async function requeueIsrcRecoveryCommand(input) {
18743
18770
  return adminApiPost("/api/v1/admin/catalogue/isrc-recovery/requeue", input);
18744
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
+ }
18745
18778
  async function anchorBreakerCommand() {
18746
18779
  return adminApiGet("/api/v1/admin/catalogue/anchor/breaker");
18747
18780
  }
@@ -22427,10 +22460,24 @@ JSON field reference:
22427
22460
  const minutes = Math.ceil(state.cooldownRemainingMs / 60000);
22428
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`);
22429
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" : ""}`);
22430
22465
  if (!state.rungs.spotifySearchEnabled && !state.rungs.apifyEnabled) {
22431
22466
  console.log("No rung can conclude \u2014 ListenBrainz still runs and can win, but its miss settles nothing.");
22432
22467
  }
22433
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
+ });
22434
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) => {
22435
22482
  await Promise.resolve().then(() => init_admin_catalogue2());
22436
22483
  const result = await requeueIsrcRecoveryCommand({
@@ -24479,6 +24526,15 @@ async function runPublishAdvance(options, publishAdvanceCommand) {
24479
24526
  console.log(`Failed ${failure.platform} for ${failure.trackId} \u2014 left for the operator.`);
24480
24527
  }
24481
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
+ }
24482
24538
  var GB = 1073741824;
24483
24539
  function formatGb(bytes) {
24484
24540
  return `${(bytes / GB).toFixed(2)} GB`;
@@ -25731,6 +25787,7 @@ var stringOptions = new Set([
25731
25787
  "--reasoning",
25732
25788
  "--recorded-at",
25733
25789
  "--recording",
25790
+ "--rows",
25734
25791
  "--rules-file",
25735
25792
  "--render",
25736
25793
  "--scene",
package/package.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "url": "git+https://github.com/mauricekleine/fluncle.git"
32
32
  },
33
33
  "type": "module",
34
- "version": "0.243.0"
34
+ "version": "0.244.0"
35
35
  }