@stage5/lumine 0.2.66 → 0.2.68
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/README.md +26 -1
- package/lib/admin-featured.js +559 -0
- package/lib/admin-runtime-logs.js +786 -0
- package/lib/admin-workflows.js +121 -46
- package/lib/admin.js +474 -40
- package/lib/commands.js +52 -8
- package/lib/sponsor-duty.js +479 -28
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +2 -2
- package/sdk/LUMINE_ADMIN.md +515 -83
package/lib/admin.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
readAdminJsonFile,
|
|
9
9
|
validateNewsEditorial,
|
|
10
10
|
writeNewsClaimArtifacts,
|
|
11
|
+
writeAdminJsonFile,
|
|
11
12
|
} from "./admin-news.js";
|
|
12
13
|
import {
|
|
13
14
|
forEachPaginatedResultItem,
|
|
@@ -20,6 +21,8 @@ import {
|
|
|
20
21
|
parseBuildReviewReceipt,
|
|
21
22
|
runManagedBuildReview,
|
|
22
23
|
} from "./build-review.js";
|
|
24
|
+
import { runAdminRuntimeLogWorkflow } from "./admin-runtime-logs.js";
|
|
25
|
+
import { readApprovedFeaturedPlan, runFeaturedWorkflow } from "./admin-featured.js";
|
|
23
26
|
|
|
24
27
|
const MAX_EDITORIAL_FILE_BYTES = 256 * 1024;
|
|
25
28
|
const MAX_COMPOSED_TEXT_FILE_BYTES = 64 * 1024;
|
|
@@ -242,7 +245,7 @@ export async function adminCommand(options) {
|
|
|
242
245
|
options.idempotencyKey || (operation.mutates ? `cli:${randomUUID()}` : "");
|
|
243
246
|
let result;
|
|
244
247
|
try {
|
|
245
|
-
const fetchOperation = async (requestPath = operation.path) =>
|
|
248
|
+
const fetchOperation = async (requestPath = operation.path, signal) =>
|
|
246
249
|
requestJson({
|
|
247
250
|
method: operation.method,
|
|
248
251
|
url: `${options.apiUrl}${requestPath}`,
|
|
@@ -252,14 +255,14 @@ export async function adminCommand(options) {
|
|
|
252
255
|
...(runId ? { "x-lumine-admin-run-id": String(runId) } : {}),
|
|
253
256
|
...(correctionSessionId
|
|
254
257
|
? {
|
|
255
|
-
"x-lumine-admin-correction-session-id":
|
|
256
|
-
correctionSessionId,
|
|
257
|
-
),
|
|
258
|
+
"x-lumine-admin-correction-session-id":
|
|
259
|
+
String(correctionSessionId),
|
|
258
260
|
}
|
|
259
261
|
: {}),
|
|
260
262
|
...(requestId ? { "x-lumine-idempotency-key": requestId } : {}),
|
|
261
263
|
},
|
|
262
264
|
timeoutMs: options.timeoutMs,
|
|
265
|
+
signal,
|
|
263
266
|
});
|
|
264
267
|
const transformResult = (rawResult) =>
|
|
265
268
|
transformAdminResult({
|
|
@@ -269,7 +272,9 @@ export async function adminCommand(options) {
|
|
|
269
272
|
recommendationContentTypes,
|
|
270
273
|
viewFilter,
|
|
271
274
|
});
|
|
272
|
-
if (operation.
|
|
275
|
+
if (operation.featuredWorkflow) {
|
|
276
|
+
result = await runFeaturedWorkflow({ options, operation, authToken: auth.token, runId });
|
|
277
|
+
} else if (operation.name === "build.review") {
|
|
273
278
|
result = await runManagedBuildReview({
|
|
274
279
|
options,
|
|
275
280
|
authToken: auth.token,
|
|
@@ -282,6 +287,13 @@ export async function adminCommand(options) {
|
|
|
282
287
|
runId,
|
|
283
288
|
parseTarget: parseRecommendationTarget,
|
|
284
289
|
});
|
|
290
|
+
} else if (operation.name.startsWith("runtime-logs.")) {
|
|
291
|
+
result = await runAdminRuntimeLogWorkflow({
|
|
292
|
+
options,
|
|
293
|
+
operation,
|
|
294
|
+
authToken: auth.token,
|
|
295
|
+
requestId,
|
|
296
|
+
});
|
|
285
297
|
} else if (options.adminAll) {
|
|
286
298
|
if (options.adminCursor) {
|
|
287
299
|
throw cliValidationError(
|
|
@@ -295,7 +307,7 @@ export async function adminCommand(options) {
|
|
|
295
307
|
fetchPage: fetchOperation,
|
|
296
308
|
transformPage: transformResult,
|
|
297
309
|
recordCoverage: shouldRecordAdminQueueCoverage(runScope)
|
|
298
|
-
? async (coverage) =>
|
|
310
|
+
? async (coverage, signal) =>
|
|
299
311
|
requestJson({
|
|
300
312
|
method: "POST",
|
|
301
313
|
url: `${options.apiUrl}/cli/admin/daily-runs/coverage`,
|
|
@@ -306,6 +318,7 @@ export async function adminCommand(options) {
|
|
|
306
318
|
"x-lumine-idempotency-key": `cli:queue-coverage:${runId}:${adminValueFingerprint(coverage).slice(0, 32)}`,
|
|
307
319
|
},
|
|
308
320
|
timeoutMs: options.timeoutMs,
|
|
321
|
+
signal,
|
|
309
322
|
})
|
|
310
323
|
: undefined,
|
|
311
324
|
});
|
|
@@ -316,9 +329,26 @@ export async function adminCommand(options) {
|
|
|
316
329
|
result = transformResult(await fetchOperation());
|
|
317
330
|
}
|
|
318
331
|
} catch (error) {
|
|
332
|
+
if (operation.featuredWorkflow && error.featuredProgress) {
|
|
333
|
+
const serverError = error.data?.error;
|
|
334
|
+
error.data = {
|
|
335
|
+
ok: false,
|
|
336
|
+
status: "partial_failure",
|
|
337
|
+
error: {
|
|
338
|
+
code: serverError?.code || error.code || "LUMINE_ADMIN_FEATURED_WORKFLOW_FAILED",
|
|
339
|
+
message: error.message,
|
|
340
|
+
details: {
|
|
341
|
+
...(serverError && typeof serverError === "object" ? serverError.details : {}),
|
|
342
|
+
...error.featuredProgress,
|
|
343
|
+
retryInstruction: "Resume the exact command with --resume; confirmed items are not replayed.",
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
}
|
|
319
348
|
if (
|
|
320
349
|
operation.mutates &&
|
|
321
350
|
requestId &&
|
|
351
|
+
!operation.featuredWorkflow &&
|
|
322
352
|
operation.name !== "post.skip-batch"
|
|
323
353
|
) {
|
|
324
354
|
const retryInstruction = `Retry with --idempotency-key ${requestId}.`;
|
|
@@ -389,6 +419,9 @@ function transformAdminResult({
|
|
|
389
419
|
if (operation.name === "recommendations.list") {
|
|
390
420
|
assertRecommendationWindowResult({ operation, result: transformed });
|
|
391
421
|
}
|
|
422
|
+
if (operation.name === "subjects.candidates") {
|
|
423
|
+
assertSubjectWindowResult({ operation, result: transformed });
|
|
424
|
+
}
|
|
392
425
|
if (operation.name === "builds.candidates") {
|
|
393
426
|
transformed = normalizeAdminBuildCandidatesResult({
|
|
394
427
|
result: transformed,
|
|
@@ -438,8 +471,44 @@ export function assertRecommendationWindowResult({ operation, result }) {
|
|
|
438
471
|
}
|
|
439
472
|
}
|
|
440
473
|
|
|
474
|
+
export function assertSubjectWindowResult({ operation, result }) {
|
|
475
|
+
const mode = operation?.pagination?.coverageMode;
|
|
476
|
+
if (!mode || mode === "legacy") return;
|
|
477
|
+
const after = result?.data?.pagination?.after;
|
|
478
|
+
const snapshotTimeStamp = result?.data?.pagination?.snapshotTimeStamp;
|
|
479
|
+
if (
|
|
480
|
+
!Number.isSafeInteger(after) ||
|
|
481
|
+
after < 0 ||
|
|
482
|
+
!Number.isSafeInteger(snapshotTimeStamp) ||
|
|
483
|
+
snapshotTimeStamp < 0
|
|
484
|
+
) {
|
|
485
|
+
const error = new Error(
|
|
486
|
+
"The deployed API did not confirm the bounded Subject window and snapshot. Deploy the matching API before using this CLI; use --include-legacy only for an intentional historical scan.",
|
|
487
|
+
);
|
|
488
|
+
error.code = "LUMINE_ADMIN_SUBJECT_WINDOW_UNSUPPORTED";
|
|
489
|
+
error.data = {
|
|
490
|
+
ok: false,
|
|
491
|
+
status: "validation_error",
|
|
492
|
+
error: {
|
|
493
|
+
code: error.code,
|
|
494
|
+
message: error.message,
|
|
495
|
+
details: { requestedMode: mode },
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
throw error;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
441
502
|
async function finishAdminOutput({ options, operation, result }) {
|
|
442
503
|
const paginationStorage = getPaginatedResultStorage(result);
|
|
504
|
+
if (
|
|
505
|
+
options.adminOutput &&
|
|
506
|
+
!paginationStorage &&
|
|
507
|
+
operation.name !== "news.claim" &&
|
|
508
|
+
operation.name !== "post.skip-batch"
|
|
509
|
+
) {
|
|
510
|
+
writeAdminResultOutput({ filePath: options.adminOutput, result, operation });
|
|
511
|
+
}
|
|
443
512
|
if (options.json) {
|
|
444
513
|
if (paginationStorage) {
|
|
445
514
|
await writePaginatedResultJson({
|
|
@@ -467,6 +536,27 @@ async function finishAdminOutput({ options, operation, result }) {
|
|
|
467
536
|
return result;
|
|
468
537
|
}
|
|
469
538
|
|
|
539
|
+
export function writeAdminResultOutput({ filePath, result, operation }) {
|
|
540
|
+
try {
|
|
541
|
+
return writeAdminJsonFile(filePath, result, { privateFile: true });
|
|
542
|
+
} catch (cause) {
|
|
543
|
+
const error = new Error(
|
|
544
|
+
`The canonical ${operation.name} result was received, but --output could not be saved: ${cause.message}. Do not repeat a successful mutation just to save its output.`,
|
|
545
|
+
);
|
|
546
|
+
error.code = "LUMINE_ADMIN_OUTPUT_WRITE_FAILED";
|
|
547
|
+
error.data = {
|
|
548
|
+
ok: false,
|
|
549
|
+
status: "error",
|
|
550
|
+
error: {
|
|
551
|
+
code: error.code,
|
|
552
|
+
message: error.message,
|
|
553
|
+
details: { canonicalResult: result, outputPath: String(filePath) },
|
|
554
|
+
},
|
|
555
|
+
};
|
|
556
|
+
throw error;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
470
560
|
export function normalizeAdminBuildCandidatesResult({ result, siteUrl }) {
|
|
471
561
|
const builds = Array.isArray(result?.builds) ? result.builds : [];
|
|
472
562
|
const nextCursor = String(result?.cursor || "").trim() || null;
|
|
@@ -716,8 +806,10 @@ export function canonicalAdminRunScope(run) {
|
|
|
716
806
|
const raw = run?.runScope;
|
|
717
807
|
if (raw === undefined || raw === null || raw === "") return "full";
|
|
718
808
|
const scope = String(raw);
|
|
719
|
-
if (
|
|
720
|
-
throw cliValidationError(
|
|
809
|
+
if (["full", "featured", "newspaper"].includes(scope)) return scope;
|
|
810
|
+
throw cliValidationError(
|
|
811
|
+
"The API returned an invalid administrator run scope.",
|
|
812
|
+
);
|
|
721
813
|
}
|
|
722
814
|
|
|
723
815
|
export function shouldRecordAdminQueueCoverage(runScope) {
|
|
@@ -736,6 +828,12 @@ const FEATURED_RUN_OPERATIONS = new Set([
|
|
|
736
828
|
"featured.add",
|
|
737
829
|
"featured.reorder",
|
|
738
830
|
"featured.rotate",
|
|
831
|
+
"featured.plan",
|
|
832
|
+
"featured.apply",
|
|
833
|
+
"featured.comments.scan",
|
|
834
|
+
"featured.comments.acknowledge",
|
|
835
|
+
"featured.comments.recommend",
|
|
836
|
+
"featured.comments.report",
|
|
739
837
|
"daily-run.complete",
|
|
740
838
|
"daily-run.fail",
|
|
741
839
|
]);
|
|
@@ -744,6 +842,14 @@ export function assertAdminOperationAllowedForRunScope({
|
|
|
744
842
|
operation,
|
|
745
843
|
runScope,
|
|
746
844
|
}) {
|
|
845
|
+
if (runScope === "newspaper") {
|
|
846
|
+
if (
|
|
847
|
+
["news.status", "news.claim", "news.submit", "news.print", "daily-run.complete", "daily-run.fail"].includes(operation.name)
|
|
848
|
+
) return;
|
|
849
|
+
throw cliValidationError(
|
|
850
|
+
`A newspaper-only run does not authorize ${operation.name}.`,
|
|
851
|
+
);
|
|
852
|
+
}
|
|
747
853
|
if (runScope !== "featured") return;
|
|
748
854
|
const subjectCommentAlias =
|
|
749
855
|
operation.name === "post.comments" &&
|
|
@@ -752,11 +858,14 @@ export function assertAdminOperationAllowedForRunScope({
|
|
|
752
858
|
return;
|
|
753
859
|
}
|
|
754
860
|
throw cliValidationError(
|
|
755
|
-
`A Featured-only run does not authorize ${operation.name}.
|
|
861
|
+
`A Featured-only run does not authorize ${operation.name}. Use the review-bound Featured comment workflow for encouragement; do not start unrelated daily work to bypass scope.`,
|
|
756
862
|
);
|
|
757
863
|
}
|
|
758
864
|
|
|
759
865
|
function adminOperationRequiresRun(operation) {
|
|
866
|
+
if (typeof operation.requiresRun === "boolean") {
|
|
867
|
+
return operation.requiresRun;
|
|
868
|
+
}
|
|
760
869
|
return (
|
|
761
870
|
![
|
|
762
871
|
"identity.list",
|
|
@@ -773,6 +882,14 @@ function adminOperationRequiresRun(operation) {
|
|
|
773
882
|
"escalation.list",
|
|
774
883
|
"escalation.set",
|
|
775
884
|
"notable.add",
|
|
885
|
+
"notable.status",
|
|
886
|
+
"runtime-logs.start",
|
|
887
|
+
"runtime-logs.status",
|
|
888
|
+
"runtime-logs.capture",
|
|
889
|
+
"runtime-logs.complete",
|
|
890
|
+
"runtime-logs.resume",
|
|
891
|
+
"runtime-logs.abandon",
|
|
892
|
+
"energy-budget.report",
|
|
776
893
|
].includes(operation.name) &&
|
|
777
894
|
!operation.name.startsWith("ai-bucket.") &&
|
|
778
895
|
!operation.name.startsWith("ai-email-policy.") &&
|
|
@@ -803,7 +920,10 @@ export function parseAdminOperation(options) {
|
|
|
803
920
|
|
|
804
921
|
if (namespace === "correction" || namespace === "corrections") {
|
|
805
922
|
if (!action || action === "status") {
|
|
806
|
-
return readOperation(
|
|
923
|
+
return readOperation(
|
|
924
|
+
"correction.status",
|
|
925
|
+
"/cli/admin/corrections/status",
|
|
926
|
+
);
|
|
807
927
|
}
|
|
808
928
|
if (action === "start") {
|
|
809
929
|
const commentId = parseRequiredInteger(target, "comment ID", 1);
|
|
@@ -1160,17 +1280,17 @@ export function parseAdminOperation(options) {
|
|
|
1160
1280
|
if (action === "start") {
|
|
1161
1281
|
const runScope = parseDailyRunScope(options.adminScope || "full");
|
|
1162
1282
|
const commentMode = parseCommentMode(options.commentMode || "off");
|
|
1163
|
-
if (runScope
|
|
1283
|
+
if (runScope !== "full" && commentMode !== "off") {
|
|
1164
1284
|
throw cliValidationError(
|
|
1165
|
-
"A
|
|
1285
|
+
"A scoped run requires --comment-mode off.",
|
|
1166
1286
|
);
|
|
1167
1287
|
}
|
|
1168
1288
|
return writeOperation(
|
|
1169
1289
|
"daily-run.start",
|
|
1170
1290
|
"POST",
|
|
1171
|
-
runScope === "
|
|
1172
|
-
? "/cli/admin/daily-runs/start
|
|
1173
|
-
:
|
|
1291
|
+
runScope === "full"
|
|
1292
|
+
? "/cli/admin/daily-runs/start"
|
|
1293
|
+
: `/cli/admin/daily-runs/start/${runScope}`,
|
|
1174
1294
|
{
|
|
1175
1295
|
identity: options.adminIdentity
|
|
1176
1296
|
? parseIdentity(options.adminIdentity)
|
|
@@ -1185,6 +1305,25 @@ export function parseAdminOperation(options) {
|
|
|
1185
1305
|
return readOperation("daily-run.status", "/cli/admin/daily-runs/status");
|
|
1186
1306
|
}
|
|
1187
1307
|
if (action === "report") {
|
|
1308
|
+
const positionalRun = String(target || "").trim();
|
|
1309
|
+
const flaggedRun = String(options.adminRun || "").trim();
|
|
1310
|
+
if (
|
|
1311
|
+
extra ||
|
|
1312
|
+
(positionalRun && flaggedRun && positionalRun !== flaggedRun)
|
|
1313
|
+
) {
|
|
1314
|
+
throw cliValidationError(
|
|
1315
|
+
"Usage: lumine admin daily-run report [--run <completed-run-id>] [--json].",
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
const historicalRun = positionalRun || flaggedRun;
|
|
1319
|
+
if (historicalRun) {
|
|
1320
|
+
const runId = parseRequiredInteger(historicalRun, "run ID", 1);
|
|
1321
|
+
return readOperation(
|
|
1322
|
+
"daily-run.report",
|
|
1323
|
+
`/cli/admin/daily-runs/${runId}/report`,
|
|
1324
|
+
{ requiresRun: false, historicalRunId: runId },
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1188
1327
|
return readOperation("daily-run.report", "/cli/admin/daily-runs/report");
|
|
1189
1328
|
}
|
|
1190
1329
|
if (action === "escalation" && target === "add") {
|
|
@@ -1408,6 +1547,30 @@ export function parseAdminOperation(options) {
|
|
|
1408
1547
|
}
|
|
1409
1548
|
|
|
1410
1549
|
if (namespace === "featured") {
|
|
1550
|
+
if (action === "comments") {
|
|
1551
|
+
if (!["scan", "acknowledge", "recommend", "report"].includes(target)) {
|
|
1552
|
+
throw cliValidationError("Usage: featured comments scan|acknowledge|recommend|report --checkpoint <file>.");
|
|
1553
|
+
}
|
|
1554
|
+
if (options.adminAll || options.adminCursor || options.adminUnviewed || options.adminViewed || options.adminAfter) {
|
|
1555
|
+
throw cliValidationError("The Featured review covers every comment; filtered or caller-supplied cursors are not supported.");
|
|
1556
|
+
}
|
|
1557
|
+
return { ...writeOperation(`featured.comments.${target}`, "POST", "/cli/admin/subjects/featured/reviews", {}),
|
|
1558
|
+
mutates: target !== "report", featuredWorkflow: target };
|
|
1559
|
+
}
|
|
1560
|
+
if (action === "plan") {
|
|
1561
|
+
if (!options.adminPostedAfter) throw cliValidationError("A Featured plan requires --posted-after <timestamp>.");
|
|
1562
|
+
return writeOperation("featured.plan", "POST", "/cli/admin/subjects/featured/plan", {
|
|
1563
|
+
removeIds: parseFeaturedSubjectIds(options.adminRemoveIds, "--remove-subject-ids"),
|
|
1564
|
+
addIds: parseFeaturedSubjectIds(options.adminAddIds, "--add-subject-ids"),
|
|
1565
|
+
...(options.adminIds ? { finalIds: parseOrderedIds(options.adminIds) } : {}),
|
|
1566
|
+
postedAfter: options.adminPostedAfter,
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
if (action === "apply") {
|
|
1570
|
+
readApprovedFeaturedPlan(options.adminFile, options.adminApprove);
|
|
1571
|
+
return { ...writeOperation("featured.apply", "POST", "/cli/admin/subjects/featured/plan/apply", {}),
|
|
1572
|
+
featuredWorkflow: "apply" };
|
|
1573
|
+
}
|
|
1411
1574
|
if (action === "list") {
|
|
1412
1575
|
return readOperation("featured.list", "/cli/admin/subjects/featured");
|
|
1413
1576
|
}
|
|
@@ -1453,7 +1616,7 @@ export function parseAdminOperation(options) {
|
|
|
1453
1616
|
if (namespace === "post") {
|
|
1454
1617
|
if (action === "get") return postGetOperation(target, options);
|
|
1455
1618
|
if (action === "comments") {
|
|
1456
|
-
const parsedTarget =
|
|
1619
|
+
const parsedTarget = parseAdminCommentTarget({
|
|
1457
1620
|
target,
|
|
1458
1621
|
explicitType: options.adminType,
|
|
1459
1622
|
});
|
|
@@ -1630,6 +1793,23 @@ export function parseAdminOperation(options) {
|
|
|
1630
1793
|
);
|
|
1631
1794
|
}
|
|
1632
1795
|
|
|
1796
|
+
if (namespace === "notable" && action === "status" && !extra) {
|
|
1797
|
+
const rawTarget = String(target || "").trim();
|
|
1798
|
+
if (!rawTarget) {
|
|
1799
|
+
throw cliValidationError(
|
|
1800
|
+
"Usage: lumine admin notable status <userId|username>.",
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
const query = /^\d+$/.test(rawTarget)
|
|
1804
|
+
? { userId: parseRequiredInteger(rawTarget, "user ID", 1) }
|
|
1805
|
+
: { username: rawTarget };
|
|
1806
|
+
return readOperation(
|
|
1807
|
+
"notable.status",
|
|
1808
|
+
withQuery("/cli/admin/notable-users/status", query),
|
|
1809
|
+
{ requiresRun: false },
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1633
1813
|
if (namespace === "ai-costs") {
|
|
1634
1814
|
if (action === "monthly" && !target && !extra) {
|
|
1635
1815
|
if (options.adminDays) {
|
|
@@ -1637,9 +1817,109 @@ export function parseAdminOperation(options) {
|
|
|
1637
1817
|
"ai-costs monthly uses UTC calendar months and does not accept --days.",
|
|
1638
1818
|
);
|
|
1639
1819
|
}
|
|
1640
|
-
return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly"
|
|
1820
|
+
return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly", {
|
|
1821
|
+
requiresRun: false,
|
|
1822
|
+
});
|
|
1641
1823
|
}
|
|
1642
|
-
|
|
1824
|
+
if (action === "day" && !extra) {
|
|
1825
|
+
if (options.adminDays) {
|
|
1826
|
+
throw cliValidationError(
|
|
1827
|
+
"ai-costs day reads one closed UTC day and does not accept --days.",
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
const positionalDay = String(target || "").trim();
|
|
1831
|
+
const flaggedDay = String(options.adminDate || "").trim();
|
|
1832
|
+
if (positionalDay && flaggedDay && positionalDay !== flaggedDay) {
|
|
1833
|
+
throw cliValidationError(
|
|
1834
|
+
"Pass the same UTC day once, either positionally or with --date.",
|
|
1835
|
+
);
|
|
1836
|
+
}
|
|
1837
|
+
const dayKey = parseUtcDayKey(positionalDay || flaggedDay);
|
|
1838
|
+
return readOperation(
|
|
1839
|
+
"ai-costs.day",
|
|
1840
|
+
`/cli/admin/ai-costs/day/${dayKey}`,
|
|
1841
|
+
{ requiresRun: false },
|
|
1842
|
+
);
|
|
1843
|
+
}
|
|
1844
|
+
throw cliValidationError(
|
|
1845
|
+
"Usage: lumine admin ai-costs monthly | ai-costs day <YYYY-MM-DD> [--json].",
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
if (namespace === "energy-budget" && !action) {
|
|
1850
|
+
if (options.adminDays) {
|
|
1851
|
+
const days = Number(options.adminDays);
|
|
1852
|
+
if (!Number.isInteger(days) || days < 1 || days > 31) {
|
|
1853
|
+
throw cliValidationError("--days must be an integer between 1 and 31.");
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
return readOperation(
|
|
1857
|
+
"energy-budget.report",
|
|
1858
|
+
withQuery("/cli/admin/energy-budget/report", { days: options.adminDays }),
|
|
1859
|
+
{ requiresRun: false },
|
|
1860
|
+
);
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
if (namespace === "runtime-logs") {
|
|
1864
|
+
if (
|
|
1865
|
+
(action === "start" || action === "status" || action === "read") &&
|
|
1866
|
+
!target &&
|
|
1867
|
+
!extra
|
|
1868
|
+
) {
|
|
1869
|
+
if (
|
|
1870
|
+
action !== "start" &&
|
|
1871
|
+
!String(options.adminReviewSession || "").trim()
|
|
1872
|
+
) {
|
|
1873
|
+
throw cliValidationError(
|
|
1874
|
+
"Pass the production-log review session with --review-session <file>.",
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
return {
|
|
1878
|
+
name:
|
|
1879
|
+
action === "read" ? "runtime-logs.capture" : `runtime-logs.${action}`,
|
|
1880
|
+
method: action === "status" ? "GET" : "POST",
|
|
1881
|
+
path: "",
|
|
1882
|
+
body: undefined,
|
|
1883
|
+
mutates: action !== "status",
|
|
1884
|
+
requiresRun: false,
|
|
1885
|
+
runtimeLogAction: action === "read" ? "capture" : action,
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
if ((action === "resume" || action === "abandon") && !target && !extra) {
|
|
1889
|
+
return {
|
|
1890
|
+
name: `runtime-logs.${action}`,
|
|
1891
|
+
method: "POST",
|
|
1892
|
+
path: "",
|
|
1893
|
+
body: undefined,
|
|
1894
|
+
mutates: true,
|
|
1895
|
+
requiresRun: false,
|
|
1896
|
+
runtimeLogAction: action,
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
if ((action === "finish" || action === "complete") && !target && !extra) {
|
|
1900
|
+
if (!String(options.adminReviewSession || "").trim()) {
|
|
1901
|
+
throw cliValidationError(
|
|
1902
|
+
"Pass the production-log review session with --review-session <file>.",
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1905
|
+
if (!options.adminReviewed) {
|
|
1906
|
+
throw cliValidationError(
|
|
1907
|
+
"Inspect every downloaded runtime-log artifact, then confirm with --reviewed.",
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1910
|
+
return {
|
|
1911
|
+
name: "runtime-logs.complete",
|
|
1912
|
+
method: "POST",
|
|
1913
|
+
path: "",
|
|
1914
|
+
body: undefined,
|
|
1915
|
+
mutates: true,
|
|
1916
|
+
requiresRun: false,
|
|
1917
|
+
runtimeLogAction: "complete",
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
throw cliValidationError(
|
|
1921
|
+
"Usage: lumine admin runtime-logs start | status|read --review-session <file> | finish --review-session <file> --reviewed | resume | abandon [--review-session <file>].",
|
|
1922
|
+
);
|
|
1643
1923
|
}
|
|
1644
1924
|
|
|
1645
1925
|
if (namespace === "media-costs") {
|
|
@@ -1891,16 +2171,19 @@ export function parseAdminOperation(options) {
|
|
|
1891
2171
|
}
|
|
1892
2172
|
|
|
1893
2173
|
throw cliValidationError(
|
|
1894
|
-
"Usage: lumine admin identity|economy|rescue|sponsor|daily-run|escalation|todo|recommendations|builds|post|subjects|subject|featured|comment|announcement|chat|news|audit|brief|ai-costs|media-costs|bot-output|notable ...",
|
|
2174
|
+
"Usage: lumine admin identity|economy|rescue|sponsor|daily-run|escalation|todo|recommendations|builds|post|subjects|subject|featured|comment|announcement|chat|news|audit|brief|ai-costs|media-costs|energy-budget|runtime-logs|bot-output|notable ...",
|
|
1895
2175
|
);
|
|
1896
2176
|
}
|
|
1897
2177
|
|
|
1898
2178
|
function subjectsListOperation(options) {
|
|
1899
2179
|
const operatorView = requestedOperatorViewFilter(options);
|
|
2180
|
+
const subjectWindow = parseSubjectWindow(options);
|
|
1900
2181
|
return readOperation(
|
|
1901
2182
|
"subjects.candidates",
|
|
1902
2183
|
withQuery("/cli/admin/subjects", {
|
|
1903
|
-
|
|
2184
|
+
sinceRun: subjectWindow.mode === "since-run" ? "true" : "",
|
|
2185
|
+
after: subjectWindow.mode === "after" ? subjectWindow.after : "",
|
|
2186
|
+
includeLegacy: subjectWindow.mode === "legacy" ? "true" : "",
|
|
1904
2187
|
cursor: options.adminCursor,
|
|
1905
2188
|
effort: options.adminEffort,
|
|
1906
2189
|
limit: options.limit,
|
|
@@ -1909,10 +2192,11 @@ function subjectsListOperation(options) {
|
|
|
1909
2192
|
pagination: {
|
|
1910
2193
|
collectionKey: "subjects",
|
|
1911
2194
|
coverageQueue: "subjects",
|
|
1912
|
-
coverageMode:
|
|
1913
|
-
after:
|
|
1914
|
-
|
|
1915
|
-
|
|
2195
|
+
coverageMode: subjectWindow.mode,
|
|
2196
|
+
after:
|
|
2197
|
+
subjectWindow.mode === "after"
|
|
2198
|
+
? parseAfterForCoverage(subjectWindow.after)
|
|
2199
|
+
: null,
|
|
1916
2200
|
filters: {
|
|
1917
2201
|
effort: options.adminEffort || "all",
|
|
1918
2202
|
...(operatorView ? { operatorView } : {}),
|
|
@@ -2007,10 +2291,7 @@ function featuredReorderOperation(options) {
|
|
|
2007
2291
|
}
|
|
2008
2292
|
|
|
2009
2293
|
function featuredAddOperation(options) {
|
|
2010
|
-
const addIds = parseFeaturedSubjectIds(
|
|
2011
|
-
options.adminIds,
|
|
2012
|
-
"--subject-ids",
|
|
2013
|
-
);
|
|
2294
|
+
const addIds = parseFeaturedSubjectIds(options.adminIds, "--subject-ids");
|
|
2014
2295
|
const postedAfter = String(options.adminPostedAfter || "").trim();
|
|
2015
2296
|
if (!postedAfter) {
|
|
2016
2297
|
throw cliValidationError(
|
|
@@ -2052,6 +2333,7 @@ function featuredRotateOperation(options) {
|
|
|
2052
2333
|
{
|
|
2053
2334
|
removeIds,
|
|
2054
2335
|
addIds,
|
|
2336
|
+
...(options.adminPostedAfter ? { postedAfter: options.adminPostedAfter } : {}),
|
|
2055
2337
|
},
|
|
2056
2338
|
);
|
|
2057
2339
|
}
|
|
@@ -2096,6 +2378,42 @@ export function parseRecommendationWindow(options) {
|
|
|
2096
2378
|
return { mode, after: mode === "after" ? options.adminAfter : "" };
|
|
2097
2379
|
}
|
|
2098
2380
|
|
|
2381
|
+
export function parseSubjectWindow(options) {
|
|
2382
|
+
const selected = [
|
|
2383
|
+
options.adminSinceRun ? "since-run" : "",
|
|
2384
|
+
options.adminAfter ? "after" : "",
|
|
2385
|
+
options.adminIncludeLegacy ? "legacy" : "",
|
|
2386
|
+
].filter(Boolean);
|
|
2387
|
+
if (selected.length > 1) {
|
|
2388
|
+
throw cliValidationError(
|
|
2389
|
+
"Choose one Subject window: --since-run, --after, or --include-legacy.",
|
|
2390
|
+
);
|
|
2391
|
+
}
|
|
2392
|
+
const mode = selected[0] || "since-run";
|
|
2393
|
+
if (mode === "after") parseAfterForCoverage(options.adminAfter);
|
|
2394
|
+
return { mode, after: mode === "after" ? options.adminAfter : "" };
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
function parseUtcDayKey(value) {
|
|
2398
|
+
const dayKey = String(value || "").trim();
|
|
2399
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dayKey);
|
|
2400
|
+
if (!match) {
|
|
2401
|
+
throw cliValidationError(
|
|
2402
|
+
"Pass a real UTC calendar date in YYYY-MM-DD format.",
|
|
2403
|
+
);
|
|
2404
|
+
}
|
|
2405
|
+
const parsed = new Date(`${dayKey}T00:00:00.000Z`);
|
|
2406
|
+
if (
|
|
2407
|
+
!Number.isFinite(parsed.getTime()) ||
|
|
2408
|
+
parsed.toISOString().slice(0, 10) !== dayKey
|
|
2409
|
+
) {
|
|
2410
|
+
throw cliValidationError(
|
|
2411
|
+
"Pass a real UTC calendar date in YYYY-MM-DD format.",
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2414
|
+
return dayKey;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2099
2417
|
function parseAfterForCoverage(value) {
|
|
2100
2418
|
const raw = String(value || "").trim();
|
|
2101
2419
|
if (/^\d+$/.test(raw)) {
|
|
@@ -2297,7 +2615,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
|
|
|
2297
2615
|
throw error;
|
|
2298
2616
|
}
|
|
2299
2617
|
const handoff = result?.data?.carryoverTodos;
|
|
2300
|
-
if (runScope
|
|
2618
|
+
if (runScope !== "full") {
|
|
2301
2619
|
if (
|
|
2302
2620
|
!runId ||
|
|
2303
2621
|
!handoff ||
|
|
@@ -2309,7 +2627,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
|
|
|
2309
2627
|
Number(handoff.newlySurfacedCount) !== 0
|
|
2310
2628
|
) {
|
|
2311
2629
|
const error = cliValidationError(
|
|
2312
|
-
"The API did not confirm that carry-over telemetry was suppressed for the
|
|
2630
|
+
"The API did not confirm that carry-over telemetry was suppressed for the scoped run.",
|
|
2313
2631
|
);
|
|
2314
2632
|
error.code = "LUMINE_ADMIN_SCOPED_RUN_UNSUPPORTED";
|
|
2315
2633
|
throw error;
|
|
@@ -2387,9 +2705,11 @@ function parseCommentMode(value) {
|
|
|
2387
2705
|
}
|
|
2388
2706
|
|
|
2389
2707
|
function parseDailyRunScope(value) {
|
|
2390
|
-
const scope = String(value || "full")
|
|
2391
|
-
|
|
2392
|
-
|
|
2708
|
+
const scope = String(value || "full")
|
|
2709
|
+
.trim()
|
|
2710
|
+
.toLowerCase();
|
|
2711
|
+
if (!["full", "featured", "newspaper"].includes(scope)) {
|
|
2712
|
+
throw cliValidationError("--scope must be full, featured, or newspaper.");
|
|
2393
2713
|
}
|
|
2394
2714
|
return scope;
|
|
2395
2715
|
}
|
|
@@ -2698,6 +3018,48 @@ function printAdminMonthlyAiCosts(monthlyAiCosts) {
|
|
|
2698
3018
|
}
|
|
2699
3019
|
}
|
|
2700
3020
|
|
|
3021
|
+
function printAdminDailyAiCosts(dailyAiCosts) {
|
|
3022
|
+
console.log(
|
|
3023
|
+
`Application AI-cost ledger for ${dailyAiCosts.day.dayKey} (closed UTC day): ${formatAdminUsd(dailyAiCosts.summary?.estimatedCostUsd)} across ${Number(dailyAiCosts.summary?.requestCount || 0)} request(s).`,
|
|
3024
|
+
);
|
|
3025
|
+
for (const row of dailyAiCosts.byProviderModel || []) {
|
|
3026
|
+
console.log(
|
|
3027
|
+
` ${row.provider || "unknown"}/${row.model || "unknown"}: ${formatAdminUsd(row.estimatedCostUsd)} · ${Number(row.totalTokens || 0)} token(s) · ${Number(row.requestCount || 0)} request(s).`,
|
|
3028
|
+
);
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
function printAdminEnergyBudget(energyBudget) {
|
|
3033
|
+
const headline = energyBudget.lastCompletedDay;
|
|
3034
|
+
if (headline) {
|
|
3035
|
+
console.log(
|
|
3036
|
+
`AI Energy budget health, last completed UTC day ${headline.dayKey}: ${formatAdminUsd(headline.chargedUsd)} charged, ${formatAdminUsd(headline.overflowUsd)} overflow, ${headline.users} user(s), ${headline.recharges} recharge(s), ${headline.runs.total.runs} run(s), ${headline.telemetry.metrics.busy_refusal.count} busy refusal(s).`,
|
|
3037
|
+
);
|
|
3038
|
+
} else {
|
|
3039
|
+
console.log("AI Energy budget health: no completed UTC day in the requested window.");
|
|
3040
|
+
}
|
|
3041
|
+
console.log(
|
|
3042
|
+
"day | charged | overflow | users | rechg | runs | calls/run avg/p90 | $/run avg/p90 | stops chg/unchg | busy | telemetry rows",
|
|
3043
|
+
);
|
|
3044
|
+
for (const day of energyBudget.byDay || []) {
|
|
3045
|
+
const m = day.telemetry.metrics;
|
|
3046
|
+
const runs = day.runs.total;
|
|
3047
|
+
console.log(
|
|
3048
|
+
`${day.dayKey}${day.inProgress ? "*" : " "}| ${formatAdminUsd(day.chargedUsd).padStart(7)} | ${formatAdminUsd(day.overflowUsd).padStart(8)} | ${String(day.users).padStart(5)} | ${String(day.recharges).padStart(5)} | ${String(runs.runs).padStart(4)} | ${String(runs.callsPerRun.avg).padStart(7)}/${String(runs.callsPerRun.p90).padEnd(9)} | ${formatAdminUsd(runs.usdPerRun.avg).padStart(6)}/${formatAdminUsd(runs.usdPerRun.p90).padEnd(6)} | ${String(m.budget_stop_changed.count).padStart(7)}/${String(m.budget_stop_unchanged.count).padEnd(7)} | ${String(m.busy_refusal.count).padStart(4)} | ${day.telemetry.rowCount}`,
|
|
3049
|
+
);
|
|
3050
|
+
}
|
|
3051
|
+
console.log("* = in-progress UTC day; never headline it.");
|
|
3052
|
+
const flags = energyBudget.flags || [];
|
|
3053
|
+
if (flags.length === 0) {
|
|
3054
|
+
console.log("Flags: none.");
|
|
3055
|
+
return;
|
|
3056
|
+
}
|
|
3057
|
+
console.log(`Flags (${flags.length}) — record each as a carry-over todo and escalate; never auto-enforce:`);
|
|
3058
|
+
for (const flag of flags) {
|
|
3059
|
+
console.log(` ${flag.dayKey} ${flag.code}: ${flag.message}`);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
|
|
2701
3063
|
function formatAdminMediaUsd(value) {
|
|
2702
3064
|
const amount = Number(value);
|
|
2703
3065
|
if (!Number.isFinite(amount)) return "unavailable";
|
|
@@ -2885,6 +3247,18 @@ async function printSpooledAdminResult({ operation, result, storage }) {
|
|
|
2885
3247
|
|
|
2886
3248
|
function printAdminResult({ operation, result }) {
|
|
2887
3249
|
const data = result?.data || {};
|
|
3250
|
+
if (operation.name === "featured.plan") {
|
|
3251
|
+
for (const pair of data.plan?.replacements || []) {
|
|
3252
|
+
console.log(`${pair.remove.id} ${pair.remove.title} -> ${pair.add.id} ${pair.add.title}`);
|
|
3253
|
+
}
|
|
3254
|
+
console.log(`Proposed final order: ${(data.plan?.finalIds || []).join(",")}`);
|
|
3255
|
+
console.log(`Plan hash: ${data.planHash}. Obtain Mikey's approval before using featured apply --file <plan.json> --approve ${data.planHash}.`);
|
|
3256
|
+
return;
|
|
3257
|
+
}
|
|
3258
|
+
if (operation.featuredWorkflow) {
|
|
3259
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
2888
3262
|
if (Array.isArray(data.applications)) {
|
|
2889
3263
|
console.log(`${data.applications.length} sponsor application(s):`);
|
|
2890
3264
|
for (const application of data.applications) {
|
|
@@ -2959,6 +3333,28 @@ function printAdminResult({ operation, result }) {
|
|
|
2959
3333
|
);
|
|
2960
3334
|
return;
|
|
2961
3335
|
}
|
|
3336
|
+
if (data.review && data.artifacts?.reviewSessionPath) {
|
|
3337
|
+
console.log(
|
|
3338
|
+
`Production-log review #${data.review.id}: ${data.completionStatus || data.review.status}.`,
|
|
3339
|
+
);
|
|
3340
|
+
console.log(`Review session: ${data.artifacts.reviewSessionPath}`);
|
|
3341
|
+
if (data.artifacts.latestSnapshot?.snapshotPath) {
|
|
3342
|
+
console.log(
|
|
3343
|
+
`Latest captured bytes: ${data.artifacts.latestSnapshot.snapshotPath}`,
|
|
3344
|
+
);
|
|
3345
|
+
}
|
|
3346
|
+
if (
|
|
3347
|
+
data.completionStatus === "needs_review" ||
|
|
3348
|
+
data.completionStatus === "post_clear_review_required"
|
|
3349
|
+
) {
|
|
3350
|
+
console.log(
|
|
3351
|
+
data.completionStatus === "post_clear_review_required"
|
|
3352
|
+
? "The API error log was cleared in place. Review the post-clear snapshot, then rerun finish with --reviewed to close the lease."
|
|
3353
|
+
: "New bytes arrived at the final boundary. Review the latest snapshot, then rerun finish with --reviewed.",
|
|
3354
|
+
);
|
|
3355
|
+
}
|
|
3356
|
+
return;
|
|
3357
|
+
}
|
|
2962
3358
|
if (data.review) {
|
|
2963
3359
|
console.log(
|
|
2964
3360
|
`Confirmed Build #${data.review.buildId} runtime at published artifact #${data.review.publishedArtifactVersionId}.`,
|
|
@@ -2971,6 +3367,14 @@ function printAdminResult({ operation, result }) {
|
|
|
2971
3367
|
printAdminMonthlyAiCosts(data.monthlyAiCosts);
|
|
2972
3368
|
return;
|
|
2973
3369
|
}
|
|
3370
|
+
if (data.dailyAiCosts) {
|
|
3371
|
+
printAdminDailyAiCosts(data.dailyAiCosts);
|
|
3372
|
+
return;
|
|
3373
|
+
}
|
|
3374
|
+
if (data.energyBudget) {
|
|
3375
|
+
printAdminEnergyBudget(data.energyBudget);
|
|
3376
|
+
return;
|
|
3377
|
+
}
|
|
2974
3378
|
if (data.monthlyMediaCosts) {
|
|
2975
3379
|
printAdminMonthlyMediaCosts(data.monthlyMediaCosts);
|
|
2976
3380
|
return;
|
|
@@ -2990,14 +3394,22 @@ function printAdminResult({ operation, result }) {
|
|
|
2990
3394
|
}
|
|
2991
3395
|
if (data.report) {
|
|
2992
3396
|
const report = data.report;
|
|
3397
|
+
const historical = report.basis?.kind === "historical_reconstruction";
|
|
2993
3398
|
console.log(
|
|
2994
|
-
|
|
3399
|
+
`${historical ? "Historical reconstruction for run" : "Run"} #${report.run.id}: ${report.mutations.successfulMutationCount} successful mutation(s), ${report.queueCoverage.length} queue coverage record(s), ${report.escalations.length} escalation(s)${historical ? "." : `, ${report.carryoverTodos?.count || 0} unfinished todo(s).`}`,
|
|
2995
3400
|
);
|
|
2996
3401
|
for (const coverage of report.queueCoverage) {
|
|
2997
3402
|
console.log(
|
|
2998
3403
|
` ${coverage.queue}: ${coverage.candidateCount} candidate(s), ${coverage.scannedCount} row(s) scanned across ${coverage.pages} page(s).`,
|
|
2999
3404
|
);
|
|
3000
3405
|
}
|
|
3406
|
+
for (const item of report.featuredReviews || []) {
|
|
3407
|
+
const coverage = item.coverage;
|
|
3408
|
+
const counts = item.encouragement || {};
|
|
3409
|
+
console.log(
|
|
3410
|
+
` Featured review #${item.review?.id || coverage?.reviewId}: ${coverage?.reviewed ? `${coverage.coveredSubjectIds.length}/${coverage.subjectCount} Subjects read, ${coverage.commentsRead} comments` : "not acknowledged as read"}; ${coverage?.complete ? "complete" : "incomplete"}; ${counts.newBasicRecommendations || 0} confirmed new basic recommendations, ${counts.alreadyDone || 0} already done, ${counts.rewardEligibilityGrants || 0} reward-permission grants, ${counts.directRewardsCreated || 0} direct rewards.`,
|
|
3411
|
+
);
|
|
3412
|
+
}
|
|
3001
3413
|
for (const escalation of report.escalations) {
|
|
3002
3414
|
const target =
|
|
3003
3415
|
escalation.url ||
|
|
@@ -3006,10 +3418,21 @@ function printAdminResult({ operation, result }) {
|
|
|
3006
3418
|
` ${String(escalation.severity || "attention").toUpperCase()} ${target} — ${escalation.summary}`,
|
|
3007
3419
|
);
|
|
3008
3420
|
}
|
|
3009
|
-
|
|
3421
|
+
if (historical) {
|
|
3422
|
+
console.log(
|
|
3423
|
+
"The live brief and carry-over todo state were not snapshotted for this completed run.",
|
|
3424
|
+
);
|
|
3425
|
+
} else {
|
|
3426
|
+
printTodoItems(report.carryoverTodos?.items || [], "Unfinished work");
|
|
3427
|
+
}
|
|
3010
3428
|
if (report.sponsorIntegrity) {
|
|
3429
|
+
const pendingApplications = Number.isSafeInteger(
|
|
3430
|
+
report.sponsorIntegrity.pendingApplications,
|
|
3431
|
+
)
|
|
3432
|
+
? `; ${report.sponsorIntegrity.pendingApplications} pending application(s)`
|
|
3433
|
+
: "; historical pending-application count unavailable";
|
|
3011
3434
|
console.log(
|
|
3012
|
-
`Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s)
|
|
3435
|
+
`Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s)${pendingApplications}.`,
|
|
3013
3436
|
);
|
|
3014
3437
|
}
|
|
3015
3438
|
const surfaces = report.brief?.engagementPulse?.surfaces;
|
|
@@ -3029,10 +3452,12 @@ function printAdminResult({ operation, result }) {
|
|
|
3029
3452
|
if (deltas.length)
|
|
3030
3453
|
console.log(`Engagement deltas: ${deltas.join(", ")}.`);
|
|
3031
3454
|
}
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3455
|
+
if (!historical) {
|
|
3456
|
+
const notableCount = Array.isArray(report.brief?.notableCandidates)
|
|
3457
|
+
? report.brief.notableCandidates.length
|
|
3458
|
+
: 0;
|
|
3459
|
+
console.log(`Notable-user candidates in this brief: ${notableCount}.`);
|
|
3460
|
+
}
|
|
3036
3461
|
return;
|
|
3037
3462
|
}
|
|
3038
3463
|
if (data.inspection) {
|
|
@@ -3096,6 +3521,15 @@ function printAdminResult({ operation, result }) {
|
|
|
3096
3521
|
printTodoItems([data.todo], "Canonical todo");
|
|
3097
3522
|
return;
|
|
3098
3523
|
}
|
|
3524
|
+
if (Object.hasOwn(data, "isNotable") && data.user) {
|
|
3525
|
+
console.log(
|
|
3526
|
+
`${data.user.username} (user #${data.user.id}) is${data.isNotable ? "" : " not"} currently in Notable Users.`,
|
|
3527
|
+
);
|
|
3528
|
+
if (data.notableUser?.reason) {
|
|
3529
|
+
console.log(`Reason: ${data.notableUser.reason}`);
|
|
3530
|
+
}
|
|
3531
|
+
return;
|
|
3532
|
+
}
|
|
3099
3533
|
if (data.bucket && Array.isArray(data.memberUserIds)) {
|
|
3100
3534
|
const added = Array.isArray(data.accounts)
|
|
3101
3535
|
? `; added ${data.accounts.length} explicit account(s)`
|