fluncle 0.209.0 → 0.211.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 +173 -6
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -610,7 +610,7 @@ function parseVersion(version) {
|
|
|
610
610
|
var currentVersion;
|
|
611
611
|
var init_version = __esm(() => {
|
|
612
612
|
init_output();
|
|
613
|
-
currentVersion = "0.
|
|
613
|
+
currentVersion = "0.211.0".trim() ? "0.211.0".trim() : "0.1.0";
|
|
614
614
|
});
|
|
615
615
|
|
|
616
616
|
// src/update-notifier.ts
|
|
@@ -2452,7 +2452,7 @@ function parseVersion2(version) {
|
|
|
2452
2452
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2453
2453
|
var init_version2 = __esm(() => {
|
|
2454
2454
|
init_output();
|
|
2455
|
-
currentVersion2 = "0.
|
|
2455
|
+
currentVersion2 = "0.211.0".trim() ? "0.211.0".trim() : "0.1.0";
|
|
2456
2456
|
});
|
|
2457
2457
|
|
|
2458
2458
|
// ../../packages/registry/src/index.ts
|
|
@@ -4469,6 +4469,101 @@ var init_admin_attention = __esm(() => {
|
|
|
4469
4469
|
};
|
|
4470
4470
|
});
|
|
4471
4471
|
|
|
4472
|
+
// src/commands/admin-telemetry.ts
|
|
4473
|
+
var exports_admin_telemetry = {};
|
|
4474
|
+
__export(exports_admin_telemetry, {
|
|
4475
|
+
telemetryLines: () => telemetryLines,
|
|
4476
|
+
telemetryCommand: () => telemetryCommand
|
|
4477
|
+
});
|
|
4478
|
+
async function telemetryCommand(options) {
|
|
4479
|
+
const params = new URLSearchParams({ limit: String(options.limit) });
|
|
4480
|
+
if (options.cursor !== undefined) {
|
|
4481
|
+
params.set("cursor", options.cursor);
|
|
4482
|
+
}
|
|
4483
|
+
if (options.ok !== undefined) {
|
|
4484
|
+
params.set("ok", String(options.ok));
|
|
4485
|
+
}
|
|
4486
|
+
if (options.since !== undefined) {
|
|
4487
|
+
params.set("since", options.since);
|
|
4488
|
+
}
|
|
4489
|
+
if (options.unit !== undefined) {
|
|
4490
|
+
params.set("unit", options.unit);
|
|
4491
|
+
}
|
|
4492
|
+
if (options.until !== undefined) {
|
|
4493
|
+
params.set("until", options.until);
|
|
4494
|
+
}
|
|
4495
|
+
return adminApiGet(`/api/v1/admin/telemetry/runs?${params.toString()}`);
|
|
4496
|
+
}
|
|
4497
|
+
function cell(value) {
|
|
4498
|
+
if (value === null) {
|
|
4499
|
+
return "-";
|
|
4500
|
+
}
|
|
4501
|
+
if (typeof value === "boolean") {
|
|
4502
|
+
return value ? "1" : "0";
|
|
4503
|
+
}
|
|
4504
|
+
return String(value);
|
|
4505
|
+
}
|
|
4506
|
+
function padded(columns, widths) {
|
|
4507
|
+
return columns.map((column, index) => column.padEnd(widths[index] ?? 0)).join(" ").trimEnd();
|
|
4508
|
+
}
|
|
4509
|
+
function telemetryLines(page) {
|
|
4510
|
+
if (!page.available) {
|
|
4511
|
+
return ["Telemetry database is not configured."];
|
|
4512
|
+
}
|
|
4513
|
+
if (page.rows.length === 0) {
|
|
4514
|
+
return ["No run events matched."];
|
|
4515
|
+
}
|
|
4516
|
+
const rollupHeader = ["UNIT", "RUNS", "LAST", "OK=0", "LIAR", "BLIND"];
|
|
4517
|
+
const rollupRows = page.rollups.map((rollup) => [
|
|
4518
|
+
rollup.unit,
|
|
4519
|
+
String(rollup.runCount),
|
|
4520
|
+
rollup.lastOccurredAt,
|
|
4521
|
+
String(rollup.failedCount),
|
|
4522
|
+
String(rollup.liarCount),
|
|
4523
|
+
String(rollup.blindCount)
|
|
4524
|
+
]);
|
|
4525
|
+
const rollupWidths = rollupHeader.map((header, index) => Math.max(header.length, ...rollupRows.map((row) => row[index]?.length ?? 0)));
|
|
4526
|
+
const runHeader = [
|
|
4527
|
+
"OCCURRED",
|
|
4528
|
+
"UNIT",
|
|
4529
|
+
"OK",
|
|
4530
|
+
"SELF",
|
|
4531
|
+
"CHECKED",
|
|
4532
|
+
"PRODUCED",
|
|
4533
|
+
"QUEUE",
|
|
4534
|
+
"EXIT",
|
|
4535
|
+
"SUMMARY"
|
|
4536
|
+
];
|
|
4537
|
+
const runRows = page.rows.map((row) => [
|
|
4538
|
+
row.occurredAt,
|
|
4539
|
+
row.unit,
|
|
4540
|
+
cell(row.ok),
|
|
4541
|
+
cell(row.selfAssertedOk),
|
|
4542
|
+
cell(row.checked),
|
|
4543
|
+
cell(row.produced),
|
|
4544
|
+
cell(row.queueDepth),
|
|
4545
|
+
String(row.exitCode),
|
|
4546
|
+
row.summaryStatus
|
|
4547
|
+
]);
|
|
4548
|
+
const runWidths = runHeader.map((header, index) => Math.max(header.length, ...runRows.map((row) => row[index]?.length ?? 0)));
|
|
4549
|
+
const lines = [
|
|
4550
|
+
`Unit rollups (${page.totalCount} matching runs)`,
|
|
4551
|
+
padded(rollupHeader, rollupWidths),
|
|
4552
|
+
...rollupRows.map((row) => padded(row, rollupWidths)),
|
|
4553
|
+
"",
|
|
4554
|
+
`Runs (${page.rows.length} on this page)`,
|
|
4555
|
+
padded(runHeader, runWidths),
|
|
4556
|
+
...runRows.map((row) => padded(row, runWidths))
|
|
4557
|
+
];
|
|
4558
|
+
if (page.nextCursor !== null) {
|
|
4559
|
+
lines.push("", `Next cursor: ${page.nextCursor}`);
|
|
4560
|
+
}
|
|
4561
|
+
return lines;
|
|
4562
|
+
}
|
|
4563
|
+
var init_admin_telemetry = __esm(() => {
|
|
4564
|
+
init_api();
|
|
4565
|
+
});
|
|
4566
|
+
|
|
4472
4567
|
// src/commands/add.ts
|
|
4473
4568
|
var exports_add = {};
|
|
4474
4569
|
__export(exports_add, {
|
|
@@ -9660,6 +9755,14 @@ function addAdminCommands(program2) {
|
|
|
9660
9755
|
const { attentionQueueCommand: attentionQueueCommand2 } = await Promise.resolve().then(() => (init_admin_attention(), exports_admin_attention));
|
|
9661
9756
|
await runAdminAttention(options, attentionQueueCommand2);
|
|
9662
9757
|
});
|
|
9758
|
+
const adminTelemetry = configureCommand(admin.command("telemetry").description("Run-ledger telemetry"));
|
|
9759
|
+
adminTelemetry.action(() => {
|
|
9760
|
+
adminTelemetry.outputHelp();
|
|
9761
|
+
});
|
|
9762
|
+
adminTelemetry.command("read").description("Run-ledger rows plus per-unit rollups").option("--unit <unit>", "Only this systemd unit").option("--since <iso>", "Only runs at or after this occurred-at instant").option("--until <iso>", "Only runs at or before this occurred-at instant").option("--ok <true|false>", "Filter by the Worker's derived run verdict").option("--limit <limit>", "Rows to show (1-100)", "50").option("--cursor <cursor>", "Opaque cursor from the previous page").option("--json", "Print the lossless 20-column rows as JSON", false).action(async (options) => {
|
|
9763
|
+
const { telemetryCommand: telemetryCommand2 } = await Promise.resolve().then(() => (init_admin_telemetry(), exports_admin_telemetry));
|
|
9764
|
+
await runAdminTelemetry(options, telemetryCommand2);
|
|
9765
|
+
});
|
|
9663
9766
|
const adminTracks = configureCommand(admin.command("tracks").description("Track admin commands"));
|
|
9664
9767
|
adminTracks.action(() => {
|
|
9665
9768
|
adminTracks.outputHelp();
|
|
@@ -11082,36 +11185,48 @@ async function runBackfillArtistImages(options, backfillArtistImagesCommand2) {
|
|
|
11082
11185
|
const failed = [];
|
|
11083
11186
|
const skipped = [];
|
|
11084
11187
|
let cursor;
|
|
11188
|
+
let budgetLimited = false;
|
|
11189
|
+
let checkedCount = 0;
|
|
11085
11190
|
let dryRun = options.dryRun;
|
|
11086
|
-
|
|
11087
|
-
|
|
11191
|
+
let queueDepth = 0;
|
|
11192
|
+
let rateLimited = false;
|
|
11193
|
+
while (filled.length < limit) {
|
|
11194
|
+
const remaining = limit - filled.length;
|
|
11088
11195
|
const result = await backfillArtistImagesCommand2(remaining, options.dryRun, cursor);
|
|
11196
|
+
budgetLimited ||= result.budgetLimited;
|
|
11197
|
+
checkedCount += result.checkedCount;
|
|
11089
11198
|
dryRun = result.dryRun;
|
|
11090
11199
|
filled.push(...result.filled);
|
|
11091
11200
|
failed.push(...result.failed);
|
|
11201
|
+
queueDepth = result.queueDepth;
|
|
11202
|
+
rateLimited ||= result.rateLimited;
|
|
11092
11203
|
skipped.push(...result.skipped);
|
|
11093
11204
|
if (!options.json) {
|
|
11094
11205
|
const verb2 = result.dryRun ? "would fill" : "filled";
|
|
11095
11206
|
console.log(` \u2026${verb2} ${result.filledCount}; ${result.failedCount} failed; ${result.skippedCount} without an image`);
|
|
11096
11207
|
}
|
|
11097
|
-
if (result.nextCursor === null) {
|
|
11208
|
+
if (result.nextCursor === null || result.rateLimited || result.budgetLimited) {
|
|
11098
11209
|
break;
|
|
11099
11210
|
}
|
|
11100
11211
|
cursor = result.nextCursor;
|
|
11101
11212
|
}
|
|
11102
11213
|
if (options.json) {
|
|
11103
11214
|
printSweepJson({
|
|
11215
|
+
budgetLimited,
|
|
11216
|
+
checkedCount,
|
|
11104
11217
|
dryRun,
|
|
11105
11218
|
failed,
|
|
11106
11219
|
filled,
|
|
11107
11220
|
filledCount: filled.length,
|
|
11221
|
+
queueDepth,
|
|
11222
|
+
rateLimited,
|
|
11108
11223
|
skipped,
|
|
11109
11224
|
skippedCount: skipped.length
|
|
11110
11225
|
}, failed.length);
|
|
11111
11226
|
return;
|
|
11112
11227
|
}
|
|
11113
11228
|
const verb = dryRun ? "Would fill" : "Filled";
|
|
11114
|
-
console.log(`${verb} ${filled.length} artist avatar(s); ${failed.length} failed; ${skipped.length} without a Spotify image.`);
|
|
11229
|
+
console.log(`${verb} ${filled.length} artist avatar(s); checked ${checkedCount}; ${failed.length} failed; ${skipped.length} without a Spotify image; ${queueDepth} queued.`);
|
|
11115
11230
|
for (const artistId of filled) {
|
|
11116
11231
|
console.log(` ${artistId}`);
|
|
11117
11232
|
}
|
|
@@ -12473,6 +12588,32 @@ function parseListLimit(value) {
|
|
|
12473
12588
|
}
|
|
12474
12589
|
return limit;
|
|
12475
12590
|
}
|
|
12591
|
+
function parseTelemetryLimit(value) {
|
|
12592
|
+
const limit = Number.parseInt(value ?? "50", 10);
|
|
12593
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
|
|
12594
|
+
throw new Error("Limit must be an integer between 1 and 100");
|
|
12595
|
+
}
|
|
12596
|
+
return limit;
|
|
12597
|
+
}
|
|
12598
|
+
function parseTelemetryOk(value) {
|
|
12599
|
+
if (value === undefined) {
|
|
12600
|
+
return;
|
|
12601
|
+
}
|
|
12602
|
+
if (value !== "true" && value !== "false") {
|
|
12603
|
+
throw new Error("--ok must be true or false");
|
|
12604
|
+
}
|
|
12605
|
+
return value === "true";
|
|
12606
|
+
}
|
|
12607
|
+
function parseTelemetryTimestamp(value, flag) {
|
|
12608
|
+
if (value === undefined) {
|
|
12609
|
+
return;
|
|
12610
|
+
}
|
|
12611
|
+
const timestamp = new Date(value);
|
|
12612
|
+
if (Number.isNaN(timestamp.getTime())) {
|
|
12613
|
+
throw new Error(`${flag} must be an ISO-8601 timestamp`);
|
|
12614
|
+
}
|
|
12615
|
+
return timestamp.toISOString();
|
|
12616
|
+
}
|
|
12476
12617
|
function parsePage(value) {
|
|
12477
12618
|
const page = Number.parseInt(value ?? "1", 10);
|
|
12478
12619
|
if (!Number.isInteger(page) || page < 1) {
|
|
@@ -12540,6 +12681,28 @@ async function runAdminAttention(options, attentionQueueCommand2) {
|
|
|
12540
12681
|
console.log(attentionQueueLines2(queue).join(`
|
|
12541
12682
|
`));
|
|
12542
12683
|
}
|
|
12684
|
+
async function runAdminTelemetry(options, telemetryCommand2) {
|
|
12685
|
+
const since = parseTelemetryTimestamp(options.since, "--since");
|
|
12686
|
+
const until = parseTelemetryTimestamp(options.until, "--until");
|
|
12687
|
+
if (since !== undefined && until !== undefined && since > until) {
|
|
12688
|
+
throw new Error("--since must be before or equal to --until");
|
|
12689
|
+
}
|
|
12690
|
+
const page = await telemetryCommand2({
|
|
12691
|
+
cursor: options.cursor,
|
|
12692
|
+
limit: parseTelemetryLimit(options.limit),
|
|
12693
|
+
ok: parseTelemetryOk(options.ok),
|
|
12694
|
+
since,
|
|
12695
|
+
unit: options.unit,
|
|
12696
|
+
until
|
|
12697
|
+
});
|
|
12698
|
+
if (options.json) {
|
|
12699
|
+
printJson({ ok: true, ...page });
|
|
12700
|
+
return;
|
|
12701
|
+
}
|
|
12702
|
+
const { telemetryLines: telemetryLines2 } = await Promise.resolve().then(() => (init_admin_telemetry(), exports_admin_telemetry));
|
|
12703
|
+
console.log(telemetryLines2(page).join(`
|
|
12704
|
+
`));
|
|
12705
|
+
}
|
|
12543
12706
|
async function runAdminQueue(options, queueCommand2) {
|
|
12544
12707
|
const limit = parseListLimit(options.limit);
|
|
12545
12708
|
const tracks = await queueCommand2(limit, {
|
|
@@ -13008,6 +13171,7 @@ var stringOptions = new Set([
|
|
|
13008
13171
|
"--min-phrase-words",
|
|
13009
13172
|
"--model",
|
|
13010
13173
|
"--note",
|
|
13174
|
+
"--ok",
|
|
13011
13175
|
"--order",
|
|
13012
13176
|
"--page",
|
|
13013
13177
|
"--parent-id",
|
|
@@ -13029,6 +13193,7 @@ var stringOptions = new Set([
|
|
|
13029
13193
|
"--script-file",
|
|
13030
13194
|
"--seed",
|
|
13031
13195
|
"--seed-state",
|
|
13196
|
+
"--since",
|
|
13032
13197
|
"--soundcloud-url",
|
|
13033
13198
|
"--source",
|
|
13034
13199
|
"--status",
|
|
@@ -13037,6 +13202,8 @@ var stringOptions = new Set([
|
|
|
13037
13202
|
"--token",
|
|
13038
13203
|
"--tracklist-file",
|
|
13039
13204
|
"--tracks",
|
|
13205
|
+
"--unit",
|
|
13206
|
+
"--until",
|
|
13040
13207
|
"--url",
|
|
13041
13208
|
"--verdict",
|
|
13042
13209
|
"--verdict-file",
|
package/package.json
CHANGED