fluncle 0.267.0 → 0.269.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 +152 -12
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -651,7 +651,7 @@ function parseVersion(version) {
651
651
  var currentVersion;
652
652
  var init_version = __esm(() => {
653
653
  init_output();
654
- currentVersion = "0.267.0".trim() ? "0.267.0".trim() : "0.1.0";
654
+ currentVersion = "0.269.0".trim() ? "0.269.0".trim() : "0.1.0";
655
655
  });
656
656
 
657
657
  // src/update-notifier.ts
@@ -2364,7 +2364,7 @@ function parseVersion2(version) {
2364
2364
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
2365
2365
  var init_version2 = __esm(() => {
2366
2366
  init_output();
2367
- currentVersion2 = "0.267.0".trim() ? "0.267.0".trim() : "0.1.0";
2367
+ currentVersion2 = "0.269.0".trim() ? "0.269.0".trim() : "0.1.0";
2368
2368
  });
2369
2369
 
2370
2370
  // ../../packages/registry/src/index.ts
@@ -10258,7 +10258,7 @@ var init_zod = __esm(() => {
10258
10258
  });
10259
10259
 
10260
10260
  // ../../packages/contracts/src/orpc/admin-catalogue.ts
10261
- 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, CrawlPipelineSummarySchema, PipelineWatchBoundedCountSchema, getPipeline, 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, recordAnchorFailure, DEEZER_CANDIDATE_LIMIT = 5, DEEZER_TEXT_MAX = 300, DEEZER_ISRC_MAX = 64, DEEZER_TRACK_ID_MAX = 32, DeezerIsrcCandidateSchema, AnchorResolveResultSchema, AnchorCommitResultSchema, prepareAnchor, AnchorPhaseBatchItemFailureSchema, prepareAnchorBatch, resolveAnchorCandidate, commitAnchor, commitAnchorBatch, getAnchorReceipt, getAnchorPaidToken, cancelAnchorPaidResult, resolveAnchorPaidResult, resolveAnchor, resolveAnchorReview, CrawlHoldReasonSchema, CrawlHoldStateSchema, CrawlHoldSchema, listCrawlHolds, resolveCrawlHold, setAnchorSearch, setAnchorApify, CaptureBudgetStateSchema, getCaptureBudget, setCaptureBudget, AnchorApifyBudgetSchema, getAnchorApifyBudget, setAnchorApifyBudget, SpotifyAnchorBreakerStateSchema, AnchorRungFlagsSchema, getSpotifyAnchorBreaker, LabelReleasesBudgetSchema, getLabelReleasesBudget, setLabelReleasesBudget, resetSpotifyAnchorBreaker, AppleBreakerStateSchema, resetAppleBreaker, adminCatalogueContract;
10261
+ 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, CrawlPipelineSummarySchema, PipelineWatchBoundedCountSchema, getPipeline, 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, recordAnchorFailure, DEEZER_CANDIDATE_LIMIT = 5, DEEZER_TEXT_MAX = 300, DEEZER_ISRC_MAX = 64, DEEZER_TRACK_ID_MAX = 32, DeezerIsrcCandidateSchema, AnchorResolveResultSchema, AnchorCommitResultSchema, prepareAnchor, AnchorPhaseBatchItemFailureSchema, prepareAnchorBatch, resolveAnchorCandidate, commitAnchor, commitAnchorBatch, getAnchorReceipt, getAnchorPaidToken, cancelAnchorPaidResult, resolveAnchorPaidResult, resolveAnchor, ReleaseLinkResultSchema, ReleaseLinkProbeSchema, resolveAnchorReleaseProbe, commitAnchorRelease, resolveAnchorReview, CrawlHoldReasonSchema, CrawlHoldStateSchema, CrawlHoldSchema, listCrawlHolds, resolveCrawlHold, setAnchorSearch, setAnchorApify, CaptureBudgetStateSchema, getCaptureBudget, setCaptureBudget, AnchorApifyBudgetSchema, getAnchorApifyBudget, setAnchorApifyBudget, SpotifyAnchorBreakerStateSchema, AnchorRungFlagsSchema, getSpotifyAnchorBreaker, setSpotifyConsumerBudget, LabelReleasesBudgetSchema, getLabelReleasesBudget, setLabelReleasesBudget, resetSpotifyAnchorBreaker, AppleBreakerStateSchema, resetAppleBreaker, adminCatalogueContract;
10262
10262
  var init_admin_catalogue = __esm(() => {
10263
10263
  init_dist3();
10264
10264
  init_zod();
@@ -10754,6 +10754,7 @@ var init_admin_catalogue = __esm(() => {
10754
10754
  }).meta({ id: "DeezerIsrcCandidate" });
10755
10755
  AnchorResolveResultSchema = object({
10756
10756
  anchored: boolean2(),
10757
+ anchoredByReleaseLink: number2().int().nonnegative().optional(),
10757
10758
  apifyBudgetRemaining: number2().int().nonnegative(),
10758
10759
  apifyEligible: boolean2(),
10759
10760
  apifyEnabled: boolean2(),
@@ -10773,7 +10774,18 @@ var init_admin_catalogue = __esm(() => {
10773
10774
  ]),
10774
10775
  ok: literal(true),
10775
10776
  paidResultToken: string2().optional(),
10776
- source: _enum(["listenbrainz", "spotify-isrc", "spotify-search"]).nullable(),
10777
+ releaseLinkAlbumFetchFailed: number2().int().nonnegative().optional(),
10778
+ releaseLinkAlbumsFetched: number2().int().nonnegative().optional(),
10779
+ releaseLinkBackoffSkipped: number2().int().nonnegative().optional(),
10780
+ releaseLinkCacheHits: number2().int().nonnegative().optional(),
10781
+ releaseLinkNoAlbum: number2().int().nonnegative().optional(),
10782
+ source: _enum([
10783
+ "listenbrainz",
10784
+ "listenbrainz-metadata",
10785
+ "release-link",
10786
+ "spotify-isrc",
10787
+ "spotify-search"
10788
+ ]).nullable(),
10777
10789
  spotifyIsrcAsked: boolean2(),
10778
10790
  spotifySearchDone: boolean2(),
10779
10791
  spotifySearchEnabled: boolean2(),
@@ -10907,13 +10919,65 @@ var init_admin_catalogue = __esm(() => {
10907
10919
  method: "POST",
10908
10920
  operationId: "resolveAnchor",
10909
10921
  path: "/admin/catalogue/anchor/resolve",
10910
- summary: "Resolve a catalogue row's Spotify anchor from the free rungs (ListenBrainz + dark Spotify search)",
10922
+ summary: "Resolve a catalogue row's Spotify anchor from release links, ListenBrainz, and Spotify search",
10911
10923
  tags: ["Admin"]
10912
10924
  }).input(object({
10913
10925
  deezerCandidates: array(DeezerIsrcCandidateSchema).max(DEEZER_CANDIDATE_LIMIT).optional(),
10914
10926
  spotifySearch: boolean2().optional(),
10915
10927
  trackId: string2().min(1)
10916
10928
  })).output(AnchorResolveResultSchema);
10929
+ ReleaseLinkResultSchema = object({
10930
+ albumFetchFailed: number2().int().nonnegative(),
10931
+ albumsFetched: number2().int().nonnegative(),
10932
+ anchored: boolean2(),
10933
+ anchoredCount: number2().int().nonnegative(),
10934
+ backoffSkipped: number2().int().nonnegative(),
10935
+ cacheHits: number2().int().nonnegative(),
10936
+ noAlbum: number2().int().nonnegative(),
10937
+ ok: literal(true),
10938
+ remainder: number2().int().nonnegative().nullable(),
10939
+ throttled: boolean2(),
10940
+ verifiedBy: _enum(["isrc", "search", "search-subset"]).nullable()
10941
+ });
10942
+ ReleaseLinkProbeSchema = object({
10943
+ evidence: array(object({
10944
+ albumId: string2().nullable(),
10945
+ checkedAt: string2().nullable(),
10946
+ recordingIds: array(string2()).max(1000),
10947
+ releaseId: string2(),
10948
+ siblingTrackIds: array(string2()).max(1000),
10949
+ tracks: array(object({
10950
+ artists: array(object({ id: string2(), name: string2() })),
10951
+ discNumber: number2(),
10952
+ durationMs: number2(),
10953
+ isrc: string2().nullable(),
10954
+ spotifyTrackId: string2(),
10955
+ title: string2(),
10956
+ trackNumber: number2()
10957
+ })).max(1000)
10958
+ })).max(3),
10959
+ issuedAt: number2().int().nonnegative(),
10960
+ result: ReleaseLinkResultSchema.omit({ ok: true }),
10961
+ trackId: string2().min(1)
10962
+ });
10963
+ resolveAnchorReleaseProbe = oc.route({
10964
+ method: "POST",
10965
+ operationId: "resolveAnchorReleaseProbe",
10966
+ path: "/admin/catalogue/anchor/release/probe",
10967
+ summary: "Probe MusicBrainz release links and Spotify album tracks",
10968
+ tags: ["Admin"]
10969
+ }).input(object({ spotifySearch: boolean2().optional(), trackId: string2().min(1) })).output(object({ ok: literal(true), probe: ReleaseLinkProbeSchema, proof: string2() }));
10970
+ commitAnchorRelease = oc.route({
10971
+ method: "POST",
10972
+ operationId: "commitAnchorRelease",
10973
+ path: "/admin/catalogue/anchor/release/commit",
10974
+ summary: "Commit release mappings and a bounded sibling anchor batch",
10975
+ tags: ["Admin"]
10976
+ }).input(object({
10977
+ cursor: number2().int().nonnegative(),
10978
+ probe: ReleaseLinkProbeSchema,
10979
+ proof: string2()
10980
+ })).output(ReleaseLinkResultSchema);
10917
10981
  resolveAnchorReview = oc.route({
10918
10982
  method: "POST",
10919
10983
  operationId: "resolveAnchorReview",
@@ -11052,6 +11116,7 @@ var init_admin_catalogue = __esm(() => {
11052
11116
  "quota_hold",
11053
11117
  "breaker_quota",
11054
11118
  "breaker_throttle",
11119
+ "daily_budget",
11055
11120
  "shared_meter",
11056
11121
  "open"
11057
11122
  ]),
@@ -11065,10 +11130,37 @@ var init_admin_catalogue = __esm(() => {
11065
11130
  summary: "The Spotify anchor-search throttle breaker: tripped, why, how long left, and the rungs",
11066
11131
  tags: ["Admin"]
11067
11132
  }).input(object({})).output(SpotifyAnchorBreakerStateSchema.extend({
11133
+ consumerBudgets: object({
11134
+ anchor: object({
11135
+ callsSpent: number2().int().nullable(),
11136
+ dailyBudget: number2().int().nullable()
11137
+ }),
11138
+ artist_images: object({
11139
+ callsSpent: number2().int().nullable(),
11140
+ dailyBudget: number2().int().nullable()
11141
+ }),
11142
+ public_search: object({
11143
+ callsSpent: number2().int().nullable(),
11144
+ dailyBudget: number2().int().nullable()
11145
+ })
11146
+ }),
11147
+ essentialDailyCalls: number2().int().nullable(),
11068
11148
  ok: literal(true),
11149
+ quotaHoldState: _enum(["clear", "held", "unknown"]),
11150
+ quotaHoldUntil: string2().nullable(),
11069
11151
  rungs: AnchorRungFlagsSchema,
11070
11152
  spotifyDailyCalls: number2().int().nullable()
11071
11153
  }));
11154
+ setSpotifyConsumerBudget = oc.route({
11155
+ method: "PUT",
11156
+ operationId: "setSpotifyConsumerBudget",
11157
+ path: "/admin/catalogue/spotify-budget",
11158
+ summary: "Set a Spotify consumer daily budget (operator)",
11159
+ tags: ["Admin"]
11160
+ }).input(object({
11161
+ consumer: _enum(["anchor", "artist_images", "public_search"]),
11162
+ dailyBudget: number2().int().min(0).max(1e6)
11163
+ })).output(object({ ok: literal(true) }));
11072
11164
  LabelReleasesBudgetSchema = object({
11073
11165
  callsSpent: number2().int().nonnegative(),
11074
11166
  dailyBudget: number2().int().nonnegative(),
@@ -11115,6 +11207,7 @@ var init_admin_catalogue = __esm(() => {
11115
11207
  clear_wrong_audio: clearWrongAudio,
11116
11208
  commit_anchor: commitAnchor,
11117
11209
  commit_anchor_batch: commitAnchorBatch,
11210
+ commit_anchor_release: commitAnchorRelease,
11118
11211
  commit_crawl_nodes: commitCrawlNodes,
11119
11212
  crawl_catalogue: crawlCatalogue,
11120
11213
  flag_wrong_audio: flagWrongAudio,
@@ -11143,6 +11236,7 @@ var init_admin_catalogue = __esm(() => {
11143
11236
  resolve_anchor: resolveAnchor,
11144
11237
  resolve_anchor_candidate: resolveAnchorCandidate,
11145
11238
  resolve_anchor_paid_result: resolveAnchorPaidResult,
11239
+ resolve_anchor_release_probe: resolveAnchorReleaseProbe,
11146
11240
  resolve_anchor_review: resolveAnchorReview,
11147
11241
  resolve_crawl_hold: resolveCrawlHold,
11148
11242
  set_anchor_apify: setAnchorApify,
@@ -11150,6 +11244,7 @@ var init_admin_catalogue = __esm(() => {
11150
11244
  set_anchor_search: setAnchorSearch,
11151
11245
  set_capture_budget: setCaptureBudget,
11152
11246
  set_label_releases_budget: setLabelReleasesBudget,
11247
+ set_spotify_consumer_budget: setSpotifyConsumerBudget,
11153
11248
  set_track_dismissed: setTrackDismissed,
11154
11249
  verify_capture: verifyCapture
11155
11250
  };
@@ -11599,7 +11694,7 @@ var init_admin_artists = __esm(() => {
11599
11694
  method: "POST",
11600
11695
  operationId: "backfillArtistImages",
11601
11696
  path: "/admin/backfill/artist-images",
11602
- summary: "Back-fill artist Spotify avatars (image_url) for existing artists (bounded)",
11697
+ summary: "Back-fill artist avatars (image_url) for existing artists (bounded)",
11603
11698
  tags: ["Admin"]
11604
11699
  }).input(object({
11605
11700
  query: object({
@@ -14140,7 +14235,7 @@ var init_admin_labels = __esm(() => {
14140
14235
  method: "PATCH",
14141
14236
  operationId: "updateLabel",
14142
14237
  path: "/admin/labels/{id}",
14143
- summary: "Update a label's crawl scope or arm a re-walk (operator; never storage)",
14238
+ summary: "Update a label's crawl scope or arm a re-walk (operator, or an agent applying a ratified triage round; never storage)",
14144
14239
  tags: ["Admin"]
14145
14240
  }).input(object({
14146
14241
  id: string2(),
@@ -14161,7 +14256,7 @@ var init_admin_labels = __esm(() => {
14161
14256
  method: "PUT",
14162
14257
  operationId: "replaceLabelArtistRules",
14163
14258
  path: "/admin/labels/{id}/artists",
14164
- summary: "Replace one label's complete artist-rule set (operator)",
14259
+ summary: "Replace one label's complete artist-rule set (operator, or an agent applying a ratified triage round)",
14165
14260
  tags: ["Admin"]
14166
14261
  }).input(object({
14167
14262
  id: string2(),
@@ -17678,6 +17773,7 @@ var contract, CONTRACT_OPERATION_NAMES, CONTRACT_OPERATION_ROUTES;
17678
17773
  var init_orpc = __esm(() => {
17679
17774
  init_dist3();
17680
17775
  init_admin_catalogue();
17776
+ init_admin_catalogue();
17681
17777
  init_admin_albums();
17682
17778
  init_admin_artifacts();
17683
17779
  init_admin_artist_rules();
@@ -19946,6 +20042,15 @@ async function requeueAnchorCommand(trackIds, clearPaid = false) {
19946
20042
  async function requeueIsrcRecoveryCommand(input) {
19947
20043
  return adminApiPost("/api/v1/admin/catalogue/isrc-recovery/requeue", input);
19948
20044
  }
20045
+ async function spotifyConsumerBudgetCommand() {
20046
+ return anchorBreakerCommand();
20047
+ }
20048
+ async function setSpotifyConsumerBudgetCommand(consumer, dailyBudget) {
20049
+ return adminApiPut("/api/v1/admin/catalogue/spotify-budget", {
20050
+ consumer,
20051
+ dailyBudget
20052
+ });
20053
+ }
19949
20054
  async function labelReleasesBudgetCommand() {
19950
20055
  return adminApiGet("/api/v1/admin/catalogue/label-releases-budget");
19951
20056
  }
@@ -24737,6 +24842,40 @@ JSON field reference:
24737
24842
  }
24738
24843
  console.log(`LABEL RELEASES BUDGET \u2014 ${state.callsSpent}/${state.dailyBudget} tap calls today \xB7 ${state.spotifyDailyCalls} Spotify calls total`);
24739
24844
  });
24845
+ const spotifyBudget = catalogue.command("spotify-consumer-budget").description("Read or set Spotify daily call budgets by consumer");
24846
+ const showSpotifyConsumerBudget = async (options) => {
24847
+ await Promise.resolve().then(() => init_admin_catalogue2());
24848
+ const state = await spotifyConsumerBudgetCommand();
24849
+ if (options.json || spotifyBudget.opts().json) {
24850
+ printJson({
24851
+ consumerBudgets: state.consumerBudgets,
24852
+ ok: true,
24853
+ spotifyDailyCalls: state.spotifyDailyCalls
24854
+ });
24855
+ return;
24856
+ }
24857
+ for (const [consumer, budget] of Object.entries(state.consumerBudgets)) {
24858
+ console.log(`SPOTIFY BUDGET ${consumer} \u2014 ${budget.callsSpent}/${budget.dailyBudget} calls today`);
24859
+ }
24860
+ };
24861
+ spotifyBudget.option("--json", "Print JSON", false).action(showSpotifyConsumerBudget);
24862
+ spotifyBudget.command("get").option("--json", "Print JSON", false).action(showSpotifyConsumerBudget);
24863
+ spotifyBudget.command("set").requiredOption("--consumer <consumer>", "anchor | artist_images | public_search").requiredOption("--calls <n>", "Daily Spotify calls allowed for this consumer").option("--json", "Print JSON", false).action(async (options) => {
24864
+ if (!["anchor", "artist_images", "public_search"].includes(options.consumer)) {
24865
+ throw new Error("--consumer must be anchor, artist_images, or public_search");
24866
+ }
24867
+ const calls = Number(options.calls);
24868
+ if (!Number.isSafeInteger(calls) || calls < 0 || calls > 1e6) {
24869
+ throw new Error("--calls must be an integer from 0 to 1000000");
24870
+ }
24871
+ await Promise.resolve().then(() => init_admin_catalogue2());
24872
+ await setSpotifyConsumerBudgetCommand(options.consumer, calls);
24873
+ if (options.json || spotifyBudget.opts().json) {
24874
+ printJson({ calls, consumer: options.consumer, ok: true });
24875
+ return;
24876
+ }
24877
+ console.log(`SPOTIFY BUDGET ${options.consumer} \u2014 ${calls} calls per day`);
24878
+ });
24740
24879
  catalogue.command("anchor-breaker").description("Why the anchor rungs are quiet: the throttle breaker, and which rungs are armed").option("--json", "Print JSON", false).action(async (options) => {
24741
24880
  await Promise.resolve().then(() => init_admin_catalogue2());
24742
24881
  const state = await anchorBreakerCommand();
@@ -24940,7 +25079,7 @@ JSON field reference:
24940
25079
  await Promise.resolve().then(() => init_admin_artists2());
24941
25080
  await runBackfillArtists(options, backfillArtistsCommand);
24942
25081
  });
24943
- backfill.command("artist-images").description("Back-fill artist Spotify avatars (image_url) for existing artists").option("--dry-run", "Report which artists would be filled without touching the DB", false).option("--limit <limit>", "Max artists to process", "50").option("--json", "Print JSON", false).action(async (options) => {
25082
+ backfill.command("artist-images").description("Back-fill artist avatars (image_url) for existing artists").option("--dry-run", "Report which artists would be filled without touching the DB", false).option("--limit <limit>", "Max artists to check", "20").option("--json", "Print JSON", false).action(async (options) => {
24944
25083
  await Promise.resolve().then(() => init_admin_artists2());
24945
25084
  await runBackfillArtistImages(options, backfillArtistImagesCommand);
24946
25085
  });
@@ -26032,8 +26171,8 @@ async function runBackfillArtistImages(options, backfillArtistImagesCommand) {
26032
26171
  let dryRun = options.dryRun;
26033
26172
  let queueDepth = 0;
26034
26173
  let rateLimited = false;
26035
- while (filled.length < limit) {
26036
- const remaining = limit - filled.length;
26174
+ while (checkedCount < limit) {
26175
+ const remaining = limit - checkedCount;
26037
26176
  const result = await backfillArtistImagesCommand(remaining, options.dryRun, cursor);
26038
26177
  budgetLimited ||= result.budgetLimited;
26039
26178
  checkedCount += result.checkedCount;
@@ -26068,7 +26207,7 @@ async function runBackfillArtistImages(options, backfillArtistImagesCommand) {
26068
26207
  return;
26069
26208
  }
26070
26209
  const verb = dryRun ? "Would fill" : "Filled";
26071
- console.log(`${verb} ${filled.length} artist avatar(s); checked ${checkedCount}; ${failed.length} failed; ${skipped.length} without a Spotify image; ${queueDepth} queued.`);
26210
+ console.log(`${verb} ${filled.length} artist avatar(s); checked ${checkedCount}; ${failed.length} failed; ${skipped.length} without an image; ${queueDepth} queued.`);
26072
26211
  for (const artistId of filled) {
26073
26212
  console.log(` ${artistId}`);
26074
26213
  }
@@ -28105,6 +28244,7 @@ var stringOptions = new Set([
28105
28244
  "--census-pages",
28106
28245
  "--composition",
28107
28246
  "--consumer-digest",
28247
+ "--consumer",
28108
28248
  "--consumer-item-count",
28109
28249
  "--content-file",
28110
28250
  "--contract",
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.267.0"
34
+ "version": "0.269.0"
35
35
  }