fluncle 0.257.0 → 0.259.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 +373 -4
- 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.259.0".trim() ? "0.259.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.259.0".trim() ? "0.259.0".trim() : "0.1.0";
|
|
2339
2339
|
});
|
|
2340
2340
|
|
|
2341
2341
|
// ../../packages/registry/src/index.ts
|
|
@@ -3711,6 +3711,17 @@ var init_src = __esm(() => {
|
|
|
3711
3711
|
title: "Label bios",
|
|
3712
3712
|
weights: { status: "hidden" }
|
|
3713
3713
|
},
|
|
3714
|
+
{
|
|
3715
|
+
command: "fluncle admin labels list --seed-state undecided",
|
|
3716
|
+
exposedContent: ["read the undecided crawl-seed pile and report whether a triage round is due"],
|
|
3717
|
+
kind: "cron",
|
|
3718
|
+
name: "cron.label-triage",
|
|
3719
|
+
operatorNotes: "daily. A PURE trigger — zero model tokens, one countless admin read and a sort. Fires only when 40+ NEVER-LOOKED labels have accumulated; stale ones ride along but never trigger a round. It cannot rule: recording a finding is record_label_triage (agent tier) and ruling is update_label (operator tier), which 403s the box token. The batched research leg is deliberately unwired until the gate proves it reports honestly. Source: docs/agents/hermes/scripts/{label-triage-sweep.ts,label-triage-sweep.sh}.",
|
|
3720
|
+
probeConfig: { cadenceMs: 24 * 60 * MINUTE_MS, cronName: "fluncle-label-triage", kind: "cron" },
|
|
3721
|
+
statusDescription: "reports when the label pile needs a round",
|
|
3722
|
+
title: "Label triage gate",
|
|
3723
|
+
weights: { status: "hidden" }
|
|
3724
|
+
},
|
|
3714
3725
|
{
|
|
3715
3726
|
command: "fluncle admin albums describe --queue",
|
|
3716
3727
|
exposedContent: [
|
|
@@ -3868,6 +3879,24 @@ var init_src = __esm(() => {
|
|
|
3868
3879
|
title: "Healthcheck prober",
|
|
3869
3880
|
weights: { status: "hidden" }
|
|
3870
3881
|
},
|
|
3882
|
+
{
|
|
3883
|
+
command: "fluncle admin digests send",
|
|
3884
|
+
exposedContent: [
|
|
3885
|
+
"send new releases from followed artists and labels to signed-in crew each Friday"
|
|
3886
|
+
],
|
|
3887
|
+
kind: "cron",
|
|
3888
|
+
name: "cron.follow-digest",
|
|
3889
|
+
operatorNotes: "Friday 17:00 Amsterdam, a template-only host-timer sweep. The Worker owns recipient selection, the enabled-by-default kill switch, Resend idempotency keys, and per-call send cap. The box uses only its agent token. Source: docs/agents/hermes/scripts/follow-digest-sweep.*.",
|
|
3890
|
+
probeConfig: {
|
|
3891
|
+
cadenceMs: 7 * 24 * 60 * MINUTE_MS,
|
|
3892
|
+
cronName: "fluncle-follow-digest",
|
|
3893
|
+
kind: "cron",
|
|
3894
|
+
schedule: { time: "17:00", tz: "Europe/Amsterdam", weekday: 5 }
|
|
3895
|
+
},
|
|
3896
|
+
statusDescription: "sends new releases from the artists and labels you follow",
|
|
3897
|
+
title: "Your follows",
|
|
3898
|
+
weights: { status: "secondary" }
|
|
3899
|
+
},
|
|
3871
3900
|
{
|
|
3872
3901
|
command: "fluncle admin newsletter draft",
|
|
3873
3902
|
exposedContent: [
|
|
@@ -10765,6 +10794,7 @@ var init_admin_catalogue = __esm(() => {
|
|
|
10765
10794
|
gateReason: _enum([
|
|
10766
10795
|
"friday_window",
|
|
10767
10796
|
"flag_off",
|
|
10797
|
+
"quota_hold",
|
|
10768
10798
|
"breaker_quota",
|
|
10769
10799
|
"breaker_throttle",
|
|
10770
10800
|
"shared_meter",
|
|
@@ -12796,6 +12826,7 @@ var init__shared = __esm(() => {
|
|
|
12796
12826
|
postedToTelegram: boolean2(),
|
|
12797
12827
|
previewUrl: string2().optional(),
|
|
12798
12828
|
releaseDate: string2().optional(),
|
|
12829
|
+
similar: boolean2().optional(),
|
|
12799
12830
|
sourceAudioFailures: number2().optional(),
|
|
12800
12831
|
sourceAudioKey: string2().optional(),
|
|
12801
12832
|
spotifyUrl: string2(),
|
|
@@ -13519,7 +13550,8 @@ var init_admin_hub_counts = __esm(() => {
|
|
|
13519
13550
|
init_zod();
|
|
13520
13551
|
HubCountsTableResultSchema = object({
|
|
13521
13552
|
corrected: number2(),
|
|
13522
|
-
deferred: number2()
|
|
13553
|
+
deferred: number2(),
|
|
13554
|
+
latestCorrected: number2()
|
|
13523
13555
|
}).meta({ id: "HubCountsTableResult" });
|
|
13524
13556
|
HubCountsReconcileCursorSchema = object({
|
|
13525
13557
|
afterId: string2().min(1).max(512).nullable(),
|
|
@@ -13549,12 +13581,13 @@ var init_admin_hub_counts = __esm(() => {
|
|
|
13549
13581
|
});
|
|
13550
13582
|
|
|
13551
13583
|
// ../../packages/contracts/src/orpc/admin-labels.ts
|
|
13552
|
-
var LabelSeedStateSchema, LabelAdminItemSchema, listLabelsAdmin, updateLabel, listLabelArtistRules, replaceLabelArtistRules, MergeLabelResultSchema, mergeLabel, MB_LABEL_MBID_PATTERN, MintLabelOutcomeSchema, LabelTakeOverResultSchema, mintLabel, LabelAliasSourceSchema, LabelAliasKindSchema, LabelAliasCandidateSchema, listLabelAliases, confirmLabelAlias, rejectLabelAlias, DescribeLabelBodySchema, describeLabel, draftLabelBio, LabelBioWorkItemSchema, listLabelsMissingBio, adminLabelsContract;
|
|
13584
|
+
var LabelSeedStateSchema, LabelTriageVerdictSchema, LabelAdminItemSchema, listLabelsAdmin, updateLabel, listLabelArtistRules, replaceLabelArtistRules, MergeLabelResultSchema, mergeLabel, MB_LABEL_MBID_PATTERN, MintLabelOutcomeSchema, LabelTakeOverResultSchema, mintLabel, LabelAliasSourceSchema, LabelAliasKindSchema, LabelAliasCandidateSchema, listLabelAliases, confirmLabelAlias, rejectLabelAlias, DescribeLabelBodySchema, describeLabel, draftLabelBio, LabelBioWorkItemSchema, listLabelsMissingBio, TriageRuleProposalSchema, RecordLabelTriageBodySchema, recordLabelTriage, adminLabelsContract;
|
|
13553
13585
|
var init_admin_labels = __esm(() => {
|
|
13554
13586
|
init_dist3();
|
|
13555
13587
|
init_zod();
|
|
13556
13588
|
init_admin_artist_rules();
|
|
13557
13589
|
LabelSeedStateSchema = _enum(["disabled", "enabled", "undecided"]).meta({ id: "LabelSeedState" });
|
|
13590
|
+
LabelTriageVerdictSchema = _enum(["dnb", "dnb_partial", "not_dnb", "unclear"]).meta({ id: "LabelTriageVerdict" });
|
|
13558
13591
|
LabelAdminItemSchema = object({
|
|
13559
13592
|
createdAt: string2(),
|
|
13560
13593
|
disambiguation: string2().nullable().optional(),
|
|
@@ -13569,6 +13602,9 @@ var init_admin_labels = __esm(() => {
|
|
|
13569
13602
|
scopeChangedAt: string2().nullable().optional(),
|
|
13570
13603
|
seedState: LabelSeedStateSchema,
|
|
13571
13604
|
slug: string2(),
|
|
13605
|
+
triageCheckedAt: string2().nullable().optional(),
|
|
13606
|
+
triageReason: string2().nullable().optional(),
|
|
13607
|
+
triageVerdict: LabelTriageVerdictSchema.nullable().optional(),
|
|
13572
13608
|
updatedAt: string2()
|
|
13573
13609
|
}).meta({ id: "LabelAdminItem" });
|
|
13574
13610
|
listLabelsAdmin = oc.route({
|
|
@@ -13748,6 +13784,38 @@ var init_admin_labels = __esm(() => {
|
|
|
13748
13784
|
summary: "List labels with findings but no bio yet, oldest first (the bio worklist)",
|
|
13749
13785
|
tags: ["Admin"]
|
|
13750
13786
|
}).input(object({ limit: string2().optional() })).output(object({ labels: array(LabelBioWorkItemSchema), ok: literal(true) }));
|
|
13787
|
+
TriageRuleProposalSchema = object({
|
|
13788
|
+
artistMbid: string2(),
|
|
13789
|
+
artistName: string2(),
|
|
13790
|
+
evidence: string2().optional(),
|
|
13791
|
+
firstCreditCount: number2().int().min(0),
|
|
13792
|
+
verdict: _enum(["allow", "block"])
|
|
13793
|
+
});
|
|
13794
|
+
RecordLabelTriageBodySchema = object({
|
|
13795
|
+
censusSummary: string2().optional(),
|
|
13796
|
+
confidence: _enum(["high", "medium", "low"]),
|
|
13797
|
+
evidence: string2(),
|
|
13798
|
+
offLaneShare: number2().min(0).max(1).optional(),
|
|
13799
|
+
reason: string2().optional(),
|
|
13800
|
+
residualOffLaneShare: number2().min(0).max(1).optional(),
|
|
13801
|
+
roundId: string2(),
|
|
13802
|
+
rules: array(TriageRuleProposalSchema).optional(),
|
|
13803
|
+
verdict: LabelTriageVerdictSchema,
|
|
13804
|
+
verifyAgrees: boolean2().optional(),
|
|
13805
|
+
verifyEvidence: string2().optional()
|
|
13806
|
+
}).meta({ id: "RecordLabelTriageBody" });
|
|
13807
|
+
recordLabelTriage = oc.route({
|
|
13808
|
+
method: "POST",
|
|
13809
|
+
operationId: "recordLabelTriage",
|
|
13810
|
+
path: "/admin/labels/{slug}/triage",
|
|
13811
|
+
summary: "Record what a triage round found (stamps the cursor; never rules)",
|
|
13812
|
+
tags: ["Admin"]
|
|
13813
|
+
}).input(RecordLabelTriageBodySchema.extend({ slug: string2() })).output(object({
|
|
13814
|
+
droppedInertRules: number2().int(),
|
|
13815
|
+
ok: literal(true),
|
|
13816
|
+
superseded: boolean2(),
|
|
13817
|
+
triageCheckedAt: string2()
|
|
13818
|
+
}));
|
|
13751
13819
|
adminLabelsContract = {
|
|
13752
13820
|
confirm_label_alias: confirmLabelAlias,
|
|
13753
13821
|
describe_label: describeLabel,
|
|
@@ -13758,6 +13826,7 @@ var init_admin_labels = __esm(() => {
|
|
|
13758
13826
|
list_labels_missing_bio: listLabelsMissingBio,
|
|
13759
13827
|
merge_label: mergeLabel,
|
|
13760
13828
|
mint_label: mintLabel,
|
|
13829
|
+
record_label_triage: recordLabelTriage,
|
|
13761
13830
|
reject_label_alias: rejectLabelAlias,
|
|
13762
13831
|
replace_label_artist_rules: replaceLabelArtistRules,
|
|
13763
13832
|
update_label: updateLabel
|
|
@@ -15692,6 +15761,113 @@ var init_editions = __esm(() => {
|
|
|
15692
15761
|
};
|
|
15693
15762
|
});
|
|
15694
15763
|
|
|
15764
|
+
// ../../packages/contracts/src/orpc/follow-digest.ts
|
|
15765
|
+
var TokenSchema, sendFollowDigests, getFollowDigestState, setFollowDigestState, unsubscribeFollowDigest, subscribeFollowDigest, listDigestFollows, deleteDigestFollow, followDigestContract;
|
|
15766
|
+
var init_follow_digest = __esm(() => {
|
|
15767
|
+
init_dist3();
|
|
15768
|
+
init_zod();
|
|
15769
|
+
TokenSchema = string2().min(10).max(1024);
|
|
15770
|
+
sendFollowDigests = oc.route({
|
|
15771
|
+
method: "POST",
|
|
15772
|
+
operationId: "sendFollowDigests",
|
|
15773
|
+
path: "/admin/follow-digests/send",
|
|
15774
|
+
summary: "Send the weekly digest to eligible followers in a bounded batch",
|
|
15775
|
+
tags: ["Admin"]
|
|
15776
|
+
}).input(object({
|
|
15777
|
+
cursor: string2().optional(),
|
|
15778
|
+
dryRun: boolean2().optional(),
|
|
15779
|
+
limit: number2().int().min(1).max(50).optional()
|
|
15780
|
+
})).output(object({
|
|
15781
|
+
capped: boolean2(),
|
|
15782
|
+
considered: number2(),
|
|
15783
|
+
dryRun: boolean2(),
|
|
15784
|
+
empty: number2(),
|
|
15785
|
+
failed: number2(),
|
|
15786
|
+
nextCursor: string2().optional(),
|
|
15787
|
+
ok: literal(true),
|
|
15788
|
+
paused: boolean2(),
|
|
15789
|
+
sent: number2(),
|
|
15790
|
+
skipped: number2(),
|
|
15791
|
+
unknown: number2(),
|
|
15792
|
+
weekKey: string2()
|
|
15793
|
+
}));
|
|
15794
|
+
getFollowDigestState = oc.route({
|
|
15795
|
+
method: "GET",
|
|
15796
|
+
operationId: "getFollowDigestState",
|
|
15797
|
+
path: "/admin/follow-digests/state",
|
|
15798
|
+
summary: "Read the follow digest kill switch",
|
|
15799
|
+
tags: ["Admin"]
|
|
15800
|
+
}).output(object({ ok: literal(true), paused: boolean2() }));
|
|
15801
|
+
setFollowDigestState = oc.route({
|
|
15802
|
+
method: "PUT",
|
|
15803
|
+
operationId: "setFollowDigestState",
|
|
15804
|
+
path: "/admin/follow-digests/state",
|
|
15805
|
+
summary: "Pause or resume weekly follow digests",
|
|
15806
|
+
tags: ["Admin"]
|
|
15807
|
+
}).input(object({ paused: boolean2() })).output(object({ ok: literal(true), paused: boolean2() }));
|
|
15808
|
+
unsubscribeFollowDigest = oc.route({
|
|
15809
|
+
inputStructure: "detailed",
|
|
15810
|
+
method: "POST",
|
|
15811
|
+
operationId: "unsubscribeFollowDigest",
|
|
15812
|
+
path: "/follow-digest/unsubscribe",
|
|
15813
|
+
summary: "Unsubscribe a signed follow digest recipient",
|
|
15814
|
+
tags: ["Follow digest"]
|
|
15815
|
+
}).input(object({
|
|
15816
|
+
body: object({
|
|
15817
|
+
"List-Unsubscribe": literal("One-Click").optional(),
|
|
15818
|
+
token: TokenSchema.optional()
|
|
15819
|
+
}).optional(),
|
|
15820
|
+
query: object({ token: TokenSchema.optional() })
|
|
15821
|
+
})).output(object({ ok: literal(true), subscribed: literal(false) }));
|
|
15822
|
+
subscribeFollowDigest = oc.route({
|
|
15823
|
+
inputStructure: "detailed",
|
|
15824
|
+
method: "POST",
|
|
15825
|
+
operationId: "subscribeFollowDigest",
|
|
15826
|
+
path: "/follow-digest/subscribe",
|
|
15827
|
+
summary: "Subscribe a signed follow digest recipient",
|
|
15828
|
+
tags: ["Follow digest"]
|
|
15829
|
+
}).input(object({
|
|
15830
|
+
body: object({ token: TokenSchema.optional() }).optional(),
|
|
15831
|
+
query: object({ token: TokenSchema.optional() })
|
|
15832
|
+
})).output(object({ ok: literal(true), subscribed: literal(true) }));
|
|
15833
|
+
listDigestFollows = oc.route({
|
|
15834
|
+
method: "GET",
|
|
15835
|
+
operationId: "listDigestFollows",
|
|
15836
|
+
path: "/follow-digest/follows",
|
|
15837
|
+
summary: "List follows for a signed digest recipient",
|
|
15838
|
+
tags: ["Follow digest"]
|
|
15839
|
+
}).input(object({ token: TokenSchema })).output(object({
|
|
15840
|
+
follows: array(object({
|
|
15841
|
+
id: string2(),
|
|
15842
|
+
kind: _enum(["artist", "label"]),
|
|
15843
|
+
name: string2(),
|
|
15844
|
+
slug: string2()
|
|
15845
|
+
})),
|
|
15846
|
+
ok: literal(true),
|
|
15847
|
+
subscribed: boolean2()
|
|
15848
|
+
}));
|
|
15849
|
+
deleteDigestFollow = oc.route({
|
|
15850
|
+
inputStructure: "detailed",
|
|
15851
|
+
method: "DELETE",
|
|
15852
|
+
operationId: "deleteDigestFollow",
|
|
15853
|
+
path: "/follow-digest/follows/{id}",
|
|
15854
|
+
summary: "Remove one follow for a signed digest recipient",
|
|
15855
|
+
tags: ["Follow digest"]
|
|
15856
|
+
}).input(object({
|
|
15857
|
+
params: object({ id: string2().min(1) }),
|
|
15858
|
+
query: object({ token: TokenSchema })
|
|
15859
|
+
})).output(object({ ok: literal(true) }));
|
|
15860
|
+
followDigestContract = {
|
|
15861
|
+
delete_digest_follow: deleteDigestFollow,
|
|
15862
|
+
get_follow_digest_state: getFollowDigestState,
|
|
15863
|
+
list_digest_follows: listDigestFollows,
|
|
15864
|
+
send_follow_digests: sendFollowDigests,
|
|
15865
|
+
set_follow_digest_state: setFollowDigestState,
|
|
15866
|
+
subscribe_follow_digest: subscribeFollowDigest,
|
|
15867
|
+
unsubscribe_follow_digest: unsubscribeFollowDigest
|
|
15868
|
+
};
|
|
15869
|
+
});
|
|
15870
|
+
|
|
15695
15871
|
// ../../packages/contracts/src/orpc/health.ts
|
|
15696
15872
|
var getHealth, healthContract;
|
|
15697
15873
|
var init_health = __esm(() => {
|
|
@@ -15709,6 +15885,74 @@ var init_health = __esm(() => {
|
|
|
15709
15885
|
};
|
|
15710
15886
|
});
|
|
15711
15887
|
|
|
15888
|
+
// ../../packages/contracts/src/orpc/me-follows.ts
|
|
15889
|
+
var FollowKindSchema, FollowSchema, SaveFollowBodySchema, listPrivateFollows, savePrivateFollow, deletePrivateFollow, revokePrivateFollowLinkAccess, meFollowsContract;
|
|
15890
|
+
var init_me_follows = __esm(() => {
|
|
15891
|
+
init_dist3();
|
|
15892
|
+
init_zod();
|
|
15893
|
+
FollowKindSchema = _enum(["artist", "label"]).meta({ id: "FollowKind" });
|
|
15894
|
+
FollowSchema = object({
|
|
15895
|
+
createdAt: string2(),
|
|
15896
|
+
entityId: string2(),
|
|
15897
|
+
id: string2(),
|
|
15898
|
+
includeSimilar: boolean2(),
|
|
15899
|
+
kind: FollowKindSchema,
|
|
15900
|
+
name: string2(),
|
|
15901
|
+
slug: string2()
|
|
15902
|
+
}).meta({ id: "Follow" });
|
|
15903
|
+
SaveFollowBodySchema = looseObject({
|
|
15904
|
+
entityId: unknown().optional(),
|
|
15905
|
+
intent: unknown().optional(),
|
|
15906
|
+
kind: unknown().optional()
|
|
15907
|
+
});
|
|
15908
|
+
listPrivateFollows = oc.route({
|
|
15909
|
+
method: "GET",
|
|
15910
|
+
operationId: "listPrivateFollows",
|
|
15911
|
+
path: "/me/follows",
|
|
15912
|
+
summary: "List the artists and labels the signed-in user follows",
|
|
15913
|
+
tags: ["Me"]
|
|
15914
|
+
}).output(object({ follows: array(FollowSchema), ok: literal(true) }));
|
|
15915
|
+
savePrivateFollow = oc.route({
|
|
15916
|
+
method: "POST",
|
|
15917
|
+
operationId: "savePrivateFollow",
|
|
15918
|
+
path: "/me/follows",
|
|
15919
|
+
summary: "Follow an artist or label for the signed-in user",
|
|
15920
|
+
tags: ["Me"]
|
|
15921
|
+
}).input(SaveFollowBodySchema).output(object({
|
|
15922
|
+
follow: object({
|
|
15923
|
+
createdAt: string2(),
|
|
15924
|
+
entityId: string2(),
|
|
15925
|
+
id: string2(),
|
|
15926
|
+
includeSimilar: boolean2(),
|
|
15927
|
+
kind: FollowKindSchema,
|
|
15928
|
+
name: string2(),
|
|
15929
|
+
slug: string2()
|
|
15930
|
+
}),
|
|
15931
|
+
followsEmail: boolean2(),
|
|
15932
|
+
ok: literal(true)
|
|
15933
|
+
}));
|
|
15934
|
+
deletePrivateFollow = oc.route({
|
|
15935
|
+
method: "DELETE",
|
|
15936
|
+
operationId: "deletePrivateFollow",
|
|
15937
|
+
path: "/me/follows/{id}",
|
|
15938
|
+
summary: "Unfollow an artist or label for the signed-in user",
|
|
15939
|
+
tags: ["Me"]
|
|
15940
|
+
}).input(object({ id: string2() })).output(object({ ok: literal(true) }));
|
|
15941
|
+
revokePrivateFollowLinkAccess = oc.route({
|
|
15942
|
+
method: "POST",
|
|
15943
|
+
operationId: "revokePrivateFollowLinkAccess",
|
|
15944
|
+
path: "/me/follow-link-access/revoke",
|
|
15945
|
+
summary: "Revoke emailed follows management links for the signed-in user",
|
|
15946
|
+
tags: ["Me"]
|
|
15947
|
+
}).output(object({ ok: literal(true), token: string2() }));
|
|
15948
|
+
meFollowsContract = {
|
|
15949
|
+
delete_private_follow: deletePrivateFollow,
|
|
15950
|
+
list_private_follows: listPrivateFollows,
|
|
15951
|
+
revoke_private_follow_link_access: revokePrivateFollowLinkAccess,
|
|
15952
|
+
save_private_follow: savePrivateFollow
|
|
15953
|
+
};
|
|
15954
|
+
});
|
|
15955
|
+
|
|
15712
15956
|
// ../../packages/contracts/src/orpc/me-galaxy.ts
|
|
15713
15957
|
var GalaxyProgressSchema, GalaxyMergeBodySchema, GalaxyLogBodySchema, getPrivateGalaxyProgress, mergePrivateGalaxyProgress, collectPrivateGalaxyLog, GalaxyCollectionItemSchema, GalaxyCompletionSchema, listPrivateGalaxyCollection, meGalaxyContract;
|
|
15714
15958
|
var init_me_galaxy = __esm(() => {
|
|
@@ -15921,6 +16165,7 @@ var init_me_saved = __esm(() => {
|
|
|
15921
16165
|
init_zod();
|
|
15922
16166
|
SavedFindingSchema = object({
|
|
15923
16167
|
artists: array(string2()),
|
|
16168
|
+
href: string2().optional(),
|
|
15924
16169
|
imageUrl: string2().optional(),
|
|
15925
16170
|
logId: string2().optional(),
|
|
15926
16171
|
note: string2().optional(),
|
|
@@ -16028,6 +16273,7 @@ var PrivateSubmissionSchema, ProfileBodySchema, getCurrentPrivateUser, getPrivat
|
|
|
16028
16273
|
var init_me2 = __esm(() => {
|
|
16029
16274
|
init_dist3();
|
|
16030
16275
|
init_zod();
|
|
16276
|
+
init_me_follows();
|
|
16031
16277
|
init_me_galaxy();
|
|
16032
16278
|
init_me_preferences();
|
|
16033
16279
|
init_me_recs();
|
|
@@ -16085,6 +16331,8 @@ var init_me2 = __esm(() => {
|
|
|
16085
16331
|
ok: literal(true),
|
|
16086
16332
|
summary: object({
|
|
16087
16333
|
credentials: string2(),
|
|
16334
|
+
followDigest: string2().optional(),
|
|
16335
|
+
follows: string2().optional(),
|
|
16088
16336
|
galaxyProgress: string2(),
|
|
16089
16337
|
preferences: string2().optional(),
|
|
16090
16338
|
recSeeds: string2().optional(),
|
|
@@ -16105,6 +16353,23 @@ var init_me2 = __esm(() => {
|
|
|
16105
16353
|
}).output(object({
|
|
16106
16354
|
export: object({
|
|
16107
16355
|
account: PublicUserSchema,
|
|
16356
|
+
followDigest: object({
|
|
16357
|
+
lastReleaseCount: number2().nullable(),
|
|
16358
|
+
lastSentAt: string2().nullable(),
|
|
16359
|
+
lastWeekKey: string2().nullable(),
|
|
16360
|
+
unsubscribedAt: string2().nullable(),
|
|
16361
|
+
updatedAt: string2()
|
|
16362
|
+
}).nullable().optional(),
|
|
16363
|
+
followDigestDeliveries: array(object({
|
|
16364
|
+
attempts: number2(),
|
|
16365
|
+
claimedAt: string2(),
|
|
16366
|
+
id: string2(),
|
|
16367
|
+
payloadJson: string2(),
|
|
16368
|
+
sentAt: string2().nullable(),
|
|
16369
|
+
status: string2(),
|
|
16370
|
+
weekKey: string2()
|
|
16371
|
+
})).optional(),
|
|
16372
|
+
follows: array(FollowSchema).optional(),
|
|
16108
16373
|
generatedAt: string2(),
|
|
16109
16374
|
id: string2(),
|
|
16110
16375
|
preferences: UserPreferencesSchema,
|
|
@@ -16248,6 +16513,7 @@ var init_me_watches = __esm(() => {
|
|
|
16248
16513
|
kind: unknown().optional()
|
|
16249
16514
|
});
|
|
16250
16515
|
listPrivateWatches = oc.route({
|
|
16516
|
+
deprecated: true,
|
|
16251
16517
|
method: "GET",
|
|
16252
16518
|
operationId: "listPrivateWatches",
|
|
16253
16519
|
path: "/me/watches",
|
|
@@ -16255,6 +16521,7 @@ var init_me_watches = __esm(() => {
|
|
|
16255
16521
|
tags: ["Me"]
|
|
16256
16522
|
}).output(object({ ok: literal(true), watches: array(WatchSchema) }));
|
|
16257
16523
|
savePrivateWatch = oc.route({
|
|
16524
|
+
deprecated: true,
|
|
16258
16525
|
method: "POST",
|
|
16259
16526
|
operationId: "savePrivateWatch",
|
|
16260
16527
|
path: "/me/watches",
|
|
@@ -16271,6 +16538,7 @@ var init_me_watches = __esm(() => {
|
|
|
16271
16538
|
})
|
|
16272
16539
|
}));
|
|
16273
16540
|
deletePrivateWatch = oc.route({
|
|
16541
|
+
deprecated: true,
|
|
16274
16542
|
method: "DELETE",
|
|
16275
16543
|
operationId: "deletePrivateWatch",
|
|
16276
16544
|
path: "/me/watches/{id}",
|
|
@@ -16788,6 +17056,7 @@ var init_orpc = __esm(() => {
|
|
|
16788
17056
|
init_admin_users();
|
|
16789
17057
|
init_devices();
|
|
16790
17058
|
init_editions();
|
|
17059
|
+
init_follow_digest();
|
|
16791
17060
|
init_health();
|
|
16792
17061
|
init_me2();
|
|
16793
17062
|
init_me_frontier();
|
|
@@ -16796,6 +17065,7 @@ var init_orpc = __esm(() => {
|
|
|
16796
17065
|
init_me_recs();
|
|
16797
17066
|
init_me_saved();
|
|
16798
17067
|
init_me_sets();
|
|
17068
|
+
init_me_follows();
|
|
16799
17069
|
init_me_watches();
|
|
16800
17070
|
init_mix();
|
|
16801
17071
|
init_mixtapes2();
|
|
@@ -16808,6 +17078,7 @@ var init_orpc = __esm(() => {
|
|
|
16808
17078
|
init_submissions();
|
|
16809
17079
|
init_tracks();
|
|
16810
17080
|
init_albums2();
|
|
17081
|
+
init_follow_digest();
|
|
16811
17082
|
init_artists2();
|
|
16812
17083
|
init_labels2();
|
|
16813
17084
|
init_mix();
|
|
@@ -16858,6 +17129,7 @@ var init_orpc = __esm(() => {
|
|
|
16858
17129
|
init_me_recs();
|
|
16859
17130
|
init_me_saved();
|
|
16860
17131
|
init_me_sets();
|
|
17132
|
+
init_me_follows();
|
|
16861
17133
|
init_me_watches();
|
|
16862
17134
|
init_mixtapes2();
|
|
16863
17135
|
init_newsletter();
|
|
@@ -16896,6 +17168,7 @@ var init_orpc = __esm(() => {
|
|
|
16896
17168
|
...adminFunnelContract,
|
|
16897
17169
|
...adminHealthContract,
|
|
16898
17170
|
...adminHubCountsContract,
|
|
17171
|
+
...followDigestContract,
|
|
16899
17172
|
...adminLabelsContract,
|
|
16900
17173
|
...adminLogbookContract,
|
|
16901
17174
|
...adminMigrationsContract,
|
|
@@ -16922,6 +17195,7 @@ var init_orpc = __esm(() => {
|
|
|
16922
17195
|
...meRecsContract,
|
|
16923
17196
|
...meSavedContract,
|
|
16924
17197
|
...meSetsContract,
|
|
17198
|
+
...meFollowsContract,
|
|
16925
17199
|
...meWatchesContract,
|
|
16926
17200
|
...mixContract,
|
|
16927
17201
|
...mixtapesContract,
|
|
@@ -17833,6 +18107,22 @@ var init_publish = __esm(() => {
|
|
|
17833
18107
|
init_api();
|
|
17834
18108
|
});
|
|
17835
18109
|
|
|
18110
|
+
// src/commands/digests.ts
|
|
18111
|
+
async function sendFollowDigestsCommand(options) {
|
|
18112
|
+
return adminApiPost("/api/v1/admin/follow-digests/send", options);
|
|
18113
|
+
}
|
|
18114
|
+
async function getFollowDigestStateCommand() {
|
|
18115
|
+
const result = await adminApiGet("/api/v1/admin/follow-digests/state");
|
|
18116
|
+
return result.paused;
|
|
18117
|
+
}
|
|
18118
|
+
async function setFollowDigestStateCommand(paused) {
|
|
18119
|
+
const result = await adminApiPut("/api/v1/admin/follow-digests/state", { paused });
|
|
18120
|
+
return result.paused;
|
|
18121
|
+
}
|
|
18122
|
+
var init_digests = __esm(() => {
|
|
18123
|
+
init_api();
|
|
18124
|
+
});
|
|
18125
|
+
|
|
17836
18126
|
// src/commands/capture.ts
|
|
17837
18127
|
async function captureBudgetCommand() {
|
|
17838
18128
|
return adminApiGet("/api/v1/admin/catalogue/capture-budget");
|
|
@@ -19255,6 +19545,19 @@ async function mintLabelCommand(mbLabelId, seedState, takeOverSlug) {
|
|
|
19255
19545
|
});
|
|
19256
19546
|
return { label: response.label, outcome: response.outcome, takenOver: response.takenOver };
|
|
19257
19547
|
}
|
|
19548
|
+
async function listLabelsAdminCommand(seedState) {
|
|
19549
|
+
const query = seedState === undefined ? "" : `?seedState=${encodeURIComponent(seedState)}`;
|
|
19550
|
+
const response = await adminApiGet(`/api/v1/admin/labels${query}`);
|
|
19551
|
+
return response.labels;
|
|
19552
|
+
}
|
|
19553
|
+
async function recordLabelTriageCommand(slug, payload) {
|
|
19554
|
+
const response = await adminApiPost(`/api/v1/admin/labels/${encodeURIComponent(slug.trim().toLowerCase())}/triage`, payload);
|
|
19555
|
+
return {
|
|
19556
|
+
droppedInertRules: response.droppedInertRules,
|
|
19557
|
+
superseded: response.superseded,
|
|
19558
|
+
triageCheckedAt: response.triageCheckedAt
|
|
19559
|
+
};
|
|
19560
|
+
}
|
|
19258
19561
|
async function describeLabelCommand(slug, options) {
|
|
19259
19562
|
return adminApiPost(`/api/v1/admin/labels/${encodeURIComponent(slug)}/bio`, buildBioBody2(options));
|
|
19260
19563
|
}
|
|
@@ -22378,6 +22681,44 @@ JSON field reference:
|
|
|
22378
22681
|
await Promise.resolve().then(() => init_publish());
|
|
22379
22682
|
await runPublishAdvancePause(false, options, publishAdvancePauseCommand);
|
|
22380
22683
|
});
|
|
22684
|
+
const adminFollowDigests = configureCommand(admin.command("digests").description("Weekly email digest for followed artists and labels"));
|
|
22685
|
+
adminFollowDigests.action(() => adminFollowDigests.outputHelp());
|
|
22686
|
+
adminFollowDigests.command("status").description("Read the follow digest kill switch").option("--json", "Print JSON", false).action(async (options) => {
|
|
22687
|
+
await Promise.resolve().then(() => init_digests());
|
|
22688
|
+
const paused = await getFollowDigestStateCommand();
|
|
22689
|
+
if (options.json) {
|
|
22690
|
+
printJson({ ok: true, paused });
|
|
22691
|
+
} else {
|
|
22692
|
+
console.log(paused ? "Follow digests are paused." : "Follow digests are running.");
|
|
22693
|
+
}
|
|
22694
|
+
});
|
|
22695
|
+
for (const [verb, paused] of [
|
|
22696
|
+
["pause", true],
|
|
22697
|
+
["resume", false]
|
|
22698
|
+
]) {
|
|
22699
|
+
adminFollowDigests.command(verb).description(paused ? "Pause follow digests" : "Resume follow digests").option("--json", "Print JSON", false).action(async (options) => {
|
|
22700
|
+
await Promise.resolve().then(() => init_digests());
|
|
22701
|
+
const result = await setFollowDigestStateCommand(paused);
|
|
22702
|
+
if (options.json) {
|
|
22703
|
+
printJson({ ok: true, paused: result });
|
|
22704
|
+
} else {
|
|
22705
|
+
console.log(result ? "Follow digests are paused." : "Follow digests are running.");
|
|
22706
|
+
}
|
|
22707
|
+
});
|
|
22708
|
+
}
|
|
22709
|
+
adminFollowDigests.command("send").description("Send one bounded follow digest batch").option("--cursor <id>", "Continue after this user id").option("--limit <number>", "Maximum users to consider").option("--dry-run", "Count eligible emails without sending").option("--json", "Print JSON", false).action(async (options) => {
|
|
22710
|
+
await Promise.resolve().then(() => init_digests());
|
|
22711
|
+
const result = await sendFollowDigestsCommand({
|
|
22712
|
+
cursor: options.cursor,
|
|
22713
|
+
dryRun: options.dryRun,
|
|
22714
|
+
limit: options.limit === undefined ? undefined : Number(options.limit)
|
|
22715
|
+
});
|
|
22716
|
+
if (options.json) {
|
|
22717
|
+
printJson(result);
|
|
22718
|
+
} else {
|
|
22719
|
+
console.log(`Considered ${result.considered}; sent ${result.sent}; empty ${result.empty}; next ${result.nextCursor ?? "done"}.`);
|
|
22720
|
+
}
|
|
22721
|
+
});
|
|
22381
22722
|
const adminCapture = configureCommand(admin.command("capture").description("The metered audio-capture budget and its kill switch"));
|
|
22382
22723
|
adminCapture.action(() => {
|
|
22383
22724
|
adminCapture.outputHelp();
|
|
@@ -23064,6 +23405,33 @@ JSON field reference:
|
|
|
23064
23405
|
console.log(line);
|
|
23065
23406
|
}
|
|
23066
23407
|
});
|
|
23408
|
+
labels.command("list").description("List labels with their crawl-seed state and triage cursor").option("--seed-state <state>", "Only this state: enabled, disabled, or undecided").option("--json", "Print JSON", false).action(async (options) => {
|
|
23409
|
+
const seedState = options.seedState;
|
|
23410
|
+
if (seedState !== undefined && seedState !== "enabled" && seedState !== "disabled" && seedState !== "undecided") {
|
|
23411
|
+
throw new Error("Pass --seed-state enabled|disabled|undecided");
|
|
23412
|
+
}
|
|
23413
|
+
await Promise.resolve().then(() => init_admin_labels2());
|
|
23414
|
+
const labels = await listLabelsAdminCommand(seedState);
|
|
23415
|
+
if (options.json) {
|
|
23416
|
+
console.log(JSON.stringify({ labels }, null, 2));
|
|
23417
|
+
return;
|
|
23418
|
+
}
|
|
23419
|
+
for (const label of labels) {
|
|
23420
|
+
const looked = label.triageCheckedAt ? label.triageVerdict : "never looked";
|
|
23421
|
+
console.log(`${label.slug} ${label.seedState} ${looked ?? ""}`.trimEnd());
|
|
23422
|
+
}
|
|
23423
|
+
});
|
|
23424
|
+
labels.command("triage").description("Record what a triage round found for a label (agent; never rules)").argument("<slug>", "The label slug").requiredOption("--payload <file>", "JSON file holding the round's finding for this label").option("--json", "Print JSON", false).action(async (slug, options) => {
|
|
23425
|
+
const payload = JSON.parse(readFileSync6(options.payload, "utf8"));
|
|
23426
|
+
await Promise.resolve().then(() => init_admin_labels2());
|
|
23427
|
+
const result = await recordLabelTriageCommand(slug, payload);
|
|
23428
|
+
if (options.json) {
|
|
23429
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23430
|
+
return;
|
|
23431
|
+
}
|
|
23432
|
+
const dropped = result.droppedInertRules > 0 ? ` \u2014 dropped ${result.droppedInertRules} inert` : "";
|
|
23433
|
+
console.log(`${slug} \u2192 ${payload.verdict}${dropped}${result.superseded ? " (superseded)" : ""}`);
|
|
23434
|
+
});
|
|
23067
23435
|
labels.command("mint").description("Mint a label from its MusicBrainz MBID (operator; idempotent)").argument("<mbid>", "The MusicBrainz label MBID").option("--seed-state <state>", "Rule it on arrival: enabled, disabled, or undecided").option("--take-over <slug>", "Re-point this trackless row's identity onto the minted entity").option("--json", "Print JSON", false).action(async (mbid, options) => {
|
|
23068
23436
|
const seedState = options.seedState;
|
|
23069
23437
|
if (seedState !== undefined && seedState !== "enabled" && seedState !== "disabled" && seedState !== "undecided") {
|
|
@@ -26094,6 +26462,7 @@ var stringOptions = new Set([
|
|
|
26094
26462
|
"--page-digest",
|
|
26095
26463
|
"--page-limit",
|
|
26096
26464
|
"--parent-id",
|
|
26465
|
+
"--payload",
|
|
26097
26466
|
"--plate",
|
|
26098
26467
|
"--plate-background",
|
|
26099
26468
|
"--platform",
|
package/package.json
CHANGED