@stage5/lumine 0.2.65 → 0.2.67
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 +22 -3
- package/lib/admin-runtime-logs.js +786 -0
- package/lib/admin-workflows.js +350 -59
- package/lib/admin.js +586 -47
- package/lib/commands.js +46 -5
- package/lib/sponsor-duty.js +479 -28
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +11 -7
- package/sdk/LUMINE_ADMIN.md +358 -88
package/lib/admin.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
parseBuildReviewReceipt,
|
|
21
21
|
runManagedBuildReview,
|
|
22
22
|
} from "./build-review.js";
|
|
23
|
+
import { runAdminRuntimeLogWorkflow } from "./admin-runtime-logs.js";
|
|
23
24
|
|
|
24
25
|
const MAX_EDITORIAL_FILE_BYTES = 256 * 1024;
|
|
25
26
|
const MAX_COMPOSED_TEXT_FILE_BYTES = 64 * 1024;
|
|
@@ -171,6 +172,7 @@ export async function adminCommand(options) {
|
|
|
171
172
|
scope: operation.mutates ? "build:write" : "build:read",
|
|
172
173
|
});
|
|
173
174
|
let runId = 0;
|
|
175
|
+
let runScope = null;
|
|
174
176
|
let correctionSessionId = 0;
|
|
175
177
|
let correctionSession = null;
|
|
176
178
|
if (adminOperationRequiresRun(operation)) {
|
|
@@ -216,6 +218,10 @@ export async function adminCommand(options) {
|
|
|
216
218
|
}
|
|
217
219
|
throw noActiveRunError();
|
|
218
220
|
}
|
|
221
|
+
if (selectedRun) {
|
|
222
|
+
runScope = canonicalAdminRunScope(selectedRun);
|
|
223
|
+
assertAdminOperationAllowedForRunScope({ operation, runScope });
|
|
224
|
+
}
|
|
219
225
|
if (options.adminIdentity && (selectedRun || correctionSession)) {
|
|
220
226
|
const requestedIdentity = parseIdentity(options.adminIdentity);
|
|
221
227
|
const canonicalIdentity = correctionSession
|
|
@@ -237,7 +243,7 @@ export async function adminCommand(options) {
|
|
|
237
243
|
options.idempotencyKey || (operation.mutates ? `cli:${randomUUID()}` : "");
|
|
238
244
|
let result;
|
|
239
245
|
try {
|
|
240
|
-
const fetchOperation = async (requestPath = operation.path) =>
|
|
246
|
+
const fetchOperation = async (requestPath = operation.path, signal) =>
|
|
241
247
|
requestJson({
|
|
242
248
|
method: operation.method,
|
|
243
249
|
url: `${options.apiUrl}${requestPath}`,
|
|
@@ -247,14 +253,14 @@ export async function adminCommand(options) {
|
|
|
247
253
|
...(runId ? { "x-lumine-admin-run-id": String(runId) } : {}),
|
|
248
254
|
...(correctionSessionId
|
|
249
255
|
? {
|
|
250
|
-
"x-lumine-admin-correction-session-id":
|
|
251
|
-
correctionSessionId,
|
|
252
|
-
),
|
|
256
|
+
"x-lumine-admin-correction-session-id":
|
|
257
|
+
String(correctionSessionId),
|
|
253
258
|
}
|
|
254
259
|
: {}),
|
|
255
260
|
...(requestId ? { "x-lumine-idempotency-key": requestId } : {}),
|
|
256
261
|
},
|
|
257
262
|
timeoutMs: options.timeoutMs,
|
|
263
|
+
signal,
|
|
258
264
|
});
|
|
259
265
|
const transformResult = (rawResult) =>
|
|
260
266
|
transformAdminResult({
|
|
@@ -277,6 +283,13 @@ export async function adminCommand(options) {
|
|
|
277
283
|
runId,
|
|
278
284
|
parseTarget: parseRecommendationTarget,
|
|
279
285
|
});
|
|
286
|
+
} else if (operation.name.startsWith("runtime-logs.")) {
|
|
287
|
+
result = await runAdminRuntimeLogWorkflow({
|
|
288
|
+
options,
|
|
289
|
+
operation,
|
|
290
|
+
authToken: auth.token,
|
|
291
|
+
requestId,
|
|
292
|
+
});
|
|
280
293
|
} else if (options.adminAll) {
|
|
281
294
|
if (options.adminCursor) {
|
|
282
295
|
throw cliValidationError(
|
|
@@ -289,18 +302,21 @@ export async function adminCommand(options) {
|
|
|
289
302
|
runId,
|
|
290
303
|
fetchPage: fetchOperation,
|
|
291
304
|
transformPage: transformResult,
|
|
292
|
-
recordCoverage:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
recordCoverage: shouldRecordAdminQueueCoverage(runScope)
|
|
306
|
+
? async (coverage, signal) =>
|
|
307
|
+
requestJson({
|
|
308
|
+
method: "POST",
|
|
309
|
+
url: `${options.apiUrl}/cli/admin/daily-runs/coverage`,
|
|
310
|
+
authToken: auth.token,
|
|
311
|
+
body: coverage,
|
|
312
|
+
headers: {
|
|
313
|
+
"x-lumine-admin-run-id": String(runId),
|
|
314
|
+
"x-lumine-idempotency-key": `cli:queue-coverage:${runId}:${adminValueFingerprint(coverage).slice(0, 32)}`,
|
|
315
|
+
},
|
|
316
|
+
timeoutMs: options.timeoutMs,
|
|
317
|
+
signal,
|
|
318
|
+
})
|
|
319
|
+
: undefined,
|
|
304
320
|
});
|
|
305
321
|
} else {
|
|
306
322
|
if (options.adminResume) {
|
|
@@ -355,7 +371,7 @@ export async function adminCommand(options) {
|
|
|
355
371
|
assertAiEmailPolicySetResult({ operation, result });
|
|
356
372
|
}
|
|
357
373
|
if (operation.name === "daily-run.start") {
|
|
358
|
-
assertAdminTodoHandoffResult(result);
|
|
374
|
+
assertAdminTodoHandoffResult(result, operation.body.scope);
|
|
359
375
|
}
|
|
360
376
|
if (operation.name === "news.claim") {
|
|
361
377
|
const artifacts = writeNewsClaimArtifacts({
|
|
@@ -382,6 +398,9 @@ function transformAdminResult({
|
|
|
382
398
|
if (operation.name === "recommendations.list") {
|
|
383
399
|
assertRecommendationWindowResult({ operation, result: transformed });
|
|
384
400
|
}
|
|
401
|
+
if (operation.name === "subjects.candidates") {
|
|
402
|
+
assertSubjectWindowResult({ operation, result: transformed });
|
|
403
|
+
}
|
|
385
404
|
if (operation.name === "builds.candidates") {
|
|
386
405
|
transformed = normalizeAdminBuildCandidatesResult({
|
|
387
406
|
result: transformed,
|
|
@@ -431,6 +450,34 @@ export function assertRecommendationWindowResult({ operation, result }) {
|
|
|
431
450
|
}
|
|
432
451
|
}
|
|
433
452
|
|
|
453
|
+
export function assertSubjectWindowResult({ operation, result }) {
|
|
454
|
+
const mode = operation?.pagination?.coverageMode;
|
|
455
|
+
if (!mode || mode === "legacy") return;
|
|
456
|
+
const after = result?.data?.pagination?.after;
|
|
457
|
+
const snapshotTimeStamp = result?.data?.pagination?.snapshotTimeStamp;
|
|
458
|
+
if (
|
|
459
|
+
!Number.isSafeInteger(after) ||
|
|
460
|
+
after < 0 ||
|
|
461
|
+
!Number.isSafeInteger(snapshotTimeStamp) ||
|
|
462
|
+
snapshotTimeStamp < 0
|
|
463
|
+
) {
|
|
464
|
+
const error = new Error(
|
|
465
|
+
"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.",
|
|
466
|
+
);
|
|
467
|
+
error.code = "LUMINE_ADMIN_SUBJECT_WINDOW_UNSUPPORTED";
|
|
468
|
+
error.data = {
|
|
469
|
+
ok: false,
|
|
470
|
+
status: "validation_error",
|
|
471
|
+
error: {
|
|
472
|
+
code: error.code,
|
|
473
|
+
message: error.message,
|
|
474
|
+
details: { requestedMode: mode },
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
434
481
|
async function finishAdminOutput({ options, operation, result }) {
|
|
435
482
|
const paginationStorage = getPaginatedResultStorage(result);
|
|
436
483
|
if (options.json) {
|
|
@@ -449,7 +496,11 @@ async function finishAdminOutput({ options, operation, result }) {
|
|
|
449
496
|
return result;
|
|
450
497
|
}
|
|
451
498
|
if (paginationStorage) {
|
|
452
|
-
await printSpooledAdminResult({
|
|
499
|
+
await printSpooledAdminResult({
|
|
500
|
+
operation,
|
|
501
|
+
result,
|
|
502
|
+
storage: paginationStorage,
|
|
503
|
+
});
|
|
453
504
|
return result;
|
|
454
505
|
}
|
|
455
506
|
printAdminResult({ operation, result });
|
|
@@ -693,7 +744,64 @@ export function resolveOperatorViewFilter({ operation, unviewed, viewed }) {
|
|
|
693
744
|
);
|
|
694
745
|
}
|
|
695
746
|
|
|
747
|
+
function requestedOperatorViewFilter(options) {
|
|
748
|
+
return options.adminUnviewed
|
|
749
|
+
? "unviewed"
|
|
750
|
+
: options.adminViewed
|
|
751
|
+
? "viewed"
|
|
752
|
+
: null;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
export function canonicalAdminRunScope(run) {
|
|
756
|
+
const raw = run?.runScope;
|
|
757
|
+
if (raw === undefined || raw === null || raw === "") return "full";
|
|
758
|
+
const scope = String(raw);
|
|
759
|
+
if (scope === "full" || scope === "featured") return scope;
|
|
760
|
+
throw cliValidationError(
|
|
761
|
+
"The API returned an invalid administrator run scope.",
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
export function shouldRecordAdminQueueCoverage(runScope) {
|
|
766
|
+
return runScope === "full";
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
const FEATURED_RUN_OPERATIONS = new Set([
|
|
770
|
+
"subjects.candidates",
|
|
771
|
+
"subject.get",
|
|
772
|
+
"subject.comments",
|
|
773
|
+
"subject.reveal",
|
|
774
|
+
"subject.feature",
|
|
775
|
+
"subject.unfeature",
|
|
776
|
+
"featured.list",
|
|
777
|
+
"featured.history",
|
|
778
|
+
"featured.add",
|
|
779
|
+
"featured.reorder",
|
|
780
|
+
"featured.rotate",
|
|
781
|
+
"daily-run.complete",
|
|
782
|
+
"daily-run.fail",
|
|
783
|
+
]);
|
|
784
|
+
|
|
785
|
+
export function assertAdminOperationAllowedForRunScope({
|
|
786
|
+
operation,
|
|
787
|
+
runScope,
|
|
788
|
+
}) {
|
|
789
|
+
if (runScope !== "featured") return;
|
|
790
|
+
const subjectCommentAlias =
|
|
791
|
+
operation.name === "post.comments" &&
|
|
792
|
+
/^\/cli\/admin\/subjects\/\d+\/comments(?:\?|$)/.test(operation.path);
|
|
793
|
+
if (FEATURED_RUN_OPERATIONS.has(operation.name) || subjectCommentAlias) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
throw cliValidationError(
|
|
797
|
+
`A Featured-only run does not authorize ${operation.name}. Complete or fail it before starting a full daily review.`,
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
|
|
696
801
|
function adminOperationRequiresRun(operation) {
|
|
802
|
+
if (typeof operation.requiresRun === "boolean") {
|
|
803
|
+
return operation.requiresRun;
|
|
804
|
+
}
|
|
697
805
|
return (
|
|
698
806
|
![
|
|
699
807
|
"identity.list",
|
|
@@ -710,6 +818,14 @@ function adminOperationRequiresRun(operation) {
|
|
|
710
818
|
"escalation.list",
|
|
711
819
|
"escalation.set",
|
|
712
820
|
"notable.add",
|
|
821
|
+
"notable.status",
|
|
822
|
+
"runtime-logs.start",
|
|
823
|
+
"runtime-logs.status",
|
|
824
|
+
"runtime-logs.capture",
|
|
825
|
+
"runtime-logs.complete",
|
|
826
|
+
"runtime-logs.resume",
|
|
827
|
+
"runtime-logs.abandon",
|
|
828
|
+
"energy-budget.report",
|
|
713
829
|
].includes(operation.name) &&
|
|
714
830
|
!operation.name.startsWith("ai-bucket.") &&
|
|
715
831
|
!operation.name.startsWith("ai-email-policy.") &&
|
|
@@ -740,7 +856,10 @@ export function parseAdminOperation(options) {
|
|
|
740
856
|
|
|
741
857
|
if (namespace === "correction" || namespace === "corrections") {
|
|
742
858
|
if (!action || action === "status") {
|
|
743
|
-
return readOperation(
|
|
859
|
+
return readOperation(
|
|
860
|
+
"correction.status",
|
|
861
|
+
"/cli/admin/corrections/status",
|
|
862
|
+
);
|
|
744
863
|
}
|
|
745
864
|
if (action === "start") {
|
|
746
865
|
const commentId = parseRequiredInteger(target, "comment ID", 1);
|
|
@@ -1095,16 +1214,26 @@ export function parseAdminOperation(options) {
|
|
|
1095
1214
|
|
|
1096
1215
|
if (namespace === "daily-run") {
|
|
1097
1216
|
if (action === "start") {
|
|
1217
|
+
const runScope = parseDailyRunScope(options.adminScope || "full");
|
|
1218
|
+
const commentMode = parseCommentMode(options.commentMode || "off");
|
|
1219
|
+
if (runScope === "featured" && commentMode !== "off") {
|
|
1220
|
+
throw cliValidationError(
|
|
1221
|
+
"A Featured-only run requires --comment-mode off.",
|
|
1222
|
+
);
|
|
1223
|
+
}
|
|
1098
1224
|
return writeOperation(
|
|
1099
1225
|
"daily-run.start",
|
|
1100
1226
|
"POST",
|
|
1101
|
-
"
|
|
1227
|
+
runScope === "featured"
|
|
1228
|
+
? "/cli/admin/daily-runs/start/featured"
|
|
1229
|
+
: "/cli/admin/daily-runs/start",
|
|
1102
1230
|
{
|
|
1103
1231
|
identity: options.adminIdentity
|
|
1104
1232
|
? parseIdentity(options.adminIdentity)
|
|
1105
1233
|
: undefined,
|
|
1106
|
-
commentMode
|
|
1107
|
-
|
|
1234
|
+
commentMode,
|
|
1235
|
+
scope: runScope,
|
|
1236
|
+
runKey: options.runKey || defaultDailyRunKey(runScope),
|
|
1108
1237
|
},
|
|
1109
1238
|
);
|
|
1110
1239
|
}
|
|
@@ -1112,6 +1241,25 @@ export function parseAdminOperation(options) {
|
|
|
1112
1241
|
return readOperation("daily-run.status", "/cli/admin/daily-runs/status");
|
|
1113
1242
|
}
|
|
1114
1243
|
if (action === "report") {
|
|
1244
|
+
const positionalRun = String(target || "").trim();
|
|
1245
|
+
const flaggedRun = String(options.adminRun || "").trim();
|
|
1246
|
+
if (
|
|
1247
|
+
extra ||
|
|
1248
|
+
(positionalRun && flaggedRun && positionalRun !== flaggedRun)
|
|
1249
|
+
) {
|
|
1250
|
+
throw cliValidationError(
|
|
1251
|
+
"Usage: lumine admin daily-run report [--run <completed-run-id>] [--json].",
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
const historicalRun = positionalRun || flaggedRun;
|
|
1255
|
+
if (historicalRun) {
|
|
1256
|
+
const runId = parseRequiredInteger(historicalRun, "run ID", 1);
|
|
1257
|
+
return readOperation(
|
|
1258
|
+
"daily-run.report",
|
|
1259
|
+
`/cli/admin/daily-runs/${runId}/report`,
|
|
1260
|
+
{ requiresRun: false, historicalRunId: runId },
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1115
1263
|
return readOperation("daily-run.report", "/cli/admin/daily-runs/report");
|
|
1116
1264
|
}
|
|
1117
1265
|
if (action === "escalation" && target === "add") {
|
|
@@ -1286,13 +1434,21 @@ export function parseAdminOperation(options) {
|
|
|
1286
1434
|
if (action === "get") return subjectGetOperation(target, options);
|
|
1287
1435
|
if (action === "comments") {
|
|
1288
1436
|
const subjectId = parseSubjectId(target);
|
|
1437
|
+
const operatorView = requestedOperatorViewFilter(options);
|
|
1289
1438
|
return readOperation(
|
|
1290
1439
|
"subject.comments",
|
|
1291
1440
|
withQuery(`/cli/admin/subjects/${subjectId}/comments`, {
|
|
1292
1441
|
cursor: options.adminCursor,
|
|
1293
1442
|
limit: options.limit,
|
|
1294
1443
|
}),
|
|
1295
|
-
{
|
|
1444
|
+
{
|
|
1445
|
+
pagination: {
|
|
1446
|
+
collectionKey: "comments",
|
|
1447
|
+
filters: {
|
|
1448
|
+
...(operatorView ? { operatorView } : {}),
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1451
|
+
},
|
|
1296
1452
|
);
|
|
1297
1453
|
}
|
|
1298
1454
|
if (action === "reveal") {
|
|
@@ -1330,6 +1486,29 @@ export function parseAdminOperation(options) {
|
|
|
1330
1486
|
if (action === "list") {
|
|
1331
1487
|
return readOperation("featured.list", "/cli/admin/subjects/featured");
|
|
1332
1488
|
}
|
|
1489
|
+
if (action === "history") {
|
|
1490
|
+
const subjectIds = parseFeaturedSubjectIds(
|
|
1491
|
+
options.adminIds,
|
|
1492
|
+
"--subject-ids",
|
|
1493
|
+
);
|
|
1494
|
+
return readOperation(
|
|
1495
|
+
"featured.history",
|
|
1496
|
+
withQuery("/cli/admin/subjects/featured/history", {
|
|
1497
|
+
subjectIds: subjectIds.join(","),
|
|
1498
|
+
cursor: options.adminCursor,
|
|
1499
|
+
limit: options.limit,
|
|
1500
|
+
}),
|
|
1501
|
+
{
|
|
1502
|
+
pagination: {
|
|
1503
|
+
collectionKey: "events",
|
|
1504
|
+
filters: { subjectIds },
|
|
1505
|
+
},
|
|
1506
|
+
},
|
|
1507
|
+
);
|
|
1508
|
+
}
|
|
1509
|
+
if (action === "add") {
|
|
1510
|
+
return featuredAddOperation(options);
|
|
1511
|
+
}
|
|
1333
1512
|
if (action === "reorder") {
|
|
1334
1513
|
return featuredReorderOperation(options);
|
|
1335
1514
|
}
|
|
@@ -1360,13 +1539,21 @@ export function parseAdminOperation(options) {
|
|
|
1360
1539
|
parsedTarget.type === "subject"
|
|
1361
1540
|
? `/cli/admin/subjects/${parsedTarget.id}/comments`
|
|
1362
1541
|
: `/cli/admin/posts/${parsedTarget.type}/${parsedTarget.id}/comments`;
|
|
1542
|
+
const operatorView = requestedOperatorViewFilter(options);
|
|
1363
1543
|
return readOperation(
|
|
1364
1544
|
"post.comments",
|
|
1365
1545
|
withQuery(path, {
|
|
1366
1546
|
cursor: options.adminCursor,
|
|
1367
1547
|
limit: options.limit,
|
|
1368
1548
|
}),
|
|
1369
|
-
{
|
|
1549
|
+
{
|
|
1550
|
+
pagination: {
|
|
1551
|
+
collectionKey: "comments",
|
|
1552
|
+
filters: {
|
|
1553
|
+
...(operatorView ? { operatorView } : {}),
|
|
1554
|
+
},
|
|
1555
|
+
},
|
|
1556
|
+
},
|
|
1370
1557
|
);
|
|
1371
1558
|
}
|
|
1372
1559
|
if (action === "recommend") {
|
|
@@ -1518,6 +1705,23 @@ export function parseAdminOperation(options) {
|
|
|
1518
1705
|
);
|
|
1519
1706
|
}
|
|
1520
1707
|
|
|
1708
|
+
if (namespace === "notable" && action === "status" && !extra) {
|
|
1709
|
+
const rawTarget = String(target || "").trim();
|
|
1710
|
+
if (!rawTarget) {
|
|
1711
|
+
throw cliValidationError(
|
|
1712
|
+
"Usage: lumine admin notable status <userId|username>.",
|
|
1713
|
+
);
|
|
1714
|
+
}
|
|
1715
|
+
const query = /^\d+$/.test(rawTarget)
|
|
1716
|
+
? { userId: parseRequiredInteger(rawTarget, "user ID", 1) }
|
|
1717
|
+
: { username: rawTarget };
|
|
1718
|
+
return readOperation(
|
|
1719
|
+
"notable.status",
|
|
1720
|
+
withQuery("/cli/admin/notable-users/status", query),
|
|
1721
|
+
{ requiresRun: false },
|
|
1722
|
+
);
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1521
1725
|
if (namespace === "ai-costs") {
|
|
1522
1726
|
if (action === "monthly" && !target && !extra) {
|
|
1523
1727
|
if (options.adminDays) {
|
|
@@ -1527,7 +1731,105 @@ export function parseAdminOperation(options) {
|
|
|
1527
1731
|
}
|
|
1528
1732
|
return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly");
|
|
1529
1733
|
}
|
|
1530
|
-
|
|
1734
|
+
if (action === "day" && !extra) {
|
|
1735
|
+
if (options.adminDays) {
|
|
1736
|
+
throw cliValidationError(
|
|
1737
|
+
"ai-costs day reads one closed UTC day and does not accept --days.",
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
const positionalDay = String(target || "").trim();
|
|
1741
|
+
const flaggedDay = String(options.adminDate || "").trim();
|
|
1742
|
+
if (positionalDay && flaggedDay && positionalDay !== flaggedDay) {
|
|
1743
|
+
throw cliValidationError(
|
|
1744
|
+
"Pass the same UTC day once, either positionally or with --date.",
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
const dayKey = parseUtcDayKey(positionalDay || flaggedDay);
|
|
1748
|
+
return readOperation(
|
|
1749
|
+
"ai-costs.day",
|
|
1750
|
+
`/cli/admin/ai-costs/day/${dayKey}`,
|
|
1751
|
+
{ requiresRun: false },
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
throw cliValidationError(
|
|
1755
|
+
"Usage: lumine admin ai-costs monthly | ai-costs day <YYYY-MM-DD> [--json].",
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
if (namespace === "energy-budget" && !action) {
|
|
1760
|
+
if (options.adminDays) {
|
|
1761
|
+
const days = Number(options.adminDays);
|
|
1762
|
+
if (!Number.isInteger(days) || days < 1 || days > 31) {
|
|
1763
|
+
throw cliValidationError("--days must be an integer between 1 and 31.");
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return readOperation(
|
|
1767
|
+
"energy-budget.report",
|
|
1768
|
+
withQuery("/cli/admin/energy-budget/report", { days: options.adminDays }),
|
|
1769
|
+
{ requiresRun: false },
|
|
1770
|
+
);
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
if (namespace === "runtime-logs") {
|
|
1774
|
+
if (
|
|
1775
|
+
(action === "start" || action === "status" || action === "read") &&
|
|
1776
|
+
!target &&
|
|
1777
|
+
!extra
|
|
1778
|
+
) {
|
|
1779
|
+
if (
|
|
1780
|
+
action !== "start" &&
|
|
1781
|
+
!String(options.adminReviewSession || "").trim()
|
|
1782
|
+
) {
|
|
1783
|
+
throw cliValidationError(
|
|
1784
|
+
"Pass the production-log review session with --review-session <file>.",
|
|
1785
|
+
);
|
|
1786
|
+
}
|
|
1787
|
+
return {
|
|
1788
|
+
name:
|
|
1789
|
+
action === "read" ? "runtime-logs.capture" : `runtime-logs.${action}`,
|
|
1790
|
+
method: action === "status" ? "GET" : "POST",
|
|
1791
|
+
path: "",
|
|
1792
|
+
body: undefined,
|
|
1793
|
+
mutates: action !== "status",
|
|
1794
|
+
requiresRun: false,
|
|
1795
|
+
runtimeLogAction: action === "read" ? "capture" : action,
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
if ((action === "resume" || action === "abandon") && !target && !extra) {
|
|
1799
|
+
return {
|
|
1800
|
+
name: `runtime-logs.${action}`,
|
|
1801
|
+
method: "POST",
|
|
1802
|
+
path: "",
|
|
1803
|
+
body: undefined,
|
|
1804
|
+
mutates: true,
|
|
1805
|
+
requiresRun: false,
|
|
1806
|
+
runtimeLogAction: action,
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
if ((action === "finish" || action === "complete") && !target && !extra) {
|
|
1810
|
+
if (!String(options.adminReviewSession || "").trim()) {
|
|
1811
|
+
throw cliValidationError(
|
|
1812
|
+
"Pass the production-log review session with --review-session <file>.",
|
|
1813
|
+
);
|
|
1814
|
+
}
|
|
1815
|
+
if (!options.adminReviewed) {
|
|
1816
|
+
throw cliValidationError(
|
|
1817
|
+
"Inspect every downloaded runtime-log artifact, then confirm with --reviewed.",
|
|
1818
|
+
);
|
|
1819
|
+
}
|
|
1820
|
+
return {
|
|
1821
|
+
name: "runtime-logs.complete",
|
|
1822
|
+
method: "POST",
|
|
1823
|
+
path: "",
|
|
1824
|
+
body: undefined,
|
|
1825
|
+
mutates: true,
|
|
1826
|
+
requiresRun: false,
|
|
1827
|
+
runtimeLogAction: "complete",
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
throw cliValidationError(
|
|
1831
|
+
"Usage: lumine admin runtime-logs start | status|read --review-session <file> | finish --review-session <file> --reviewed | resume | abandon [--review-session <file>].",
|
|
1832
|
+
);
|
|
1531
1833
|
}
|
|
1532
1834
|
|
|
1533
1835
|
if (namespace === "media-costs") {
|
|
@@ -1779,15 +2081,19 @@ export function parseAdminOperation(options) {
|
|
|
1779
2081
|
}
|
|
1780
2082
|
|
|
1781
2083
|
throw cliValidationError(
|
|
1782
|
-
"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 ...",
|
|
2084
|
+
"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 ...",
|
|
1783
2085
|
);
|
|
1784
2086
|
}
|
|
1785
2087
|
|
|
1786
2088
|
function subjectsListOperation(options) {
|
|
2089
|
+
const operatorView = requestedOperatorViewFilter(options);
|
|
2090
|
+
const subjectWindow = parseSubjectWindow(options);
|
|
1787
2091
|
return readOperation(
|
|
1788
2092
|
"subjects.candidates",
|
|
1789
2093
|
withQuery("/cli/admin/subjects", {
|
|
1790
|
-
|
|
2094
|
+
sinceRun: subjectWindow.mode === "since-run" ? "true" : "",
|
|
2095
|
+
after: subjectWindow.mode === "after" ? subjectWindow.after : "",
|
|
2096
|
+
includeLegacy: subjectWindow.mode === "legacy" ? "true" : "",
|
|
1791
2097
|
cursor: options.adminCursor,
|
|
1792
2098
|
effort: options.adminEffort,
|
|
1793
2099
|
limit: options.limit,
|
|
@@ -1796,11 +2102,15 @@ function subjectsListOperation(options) {
|
|
|
1796
2102
|
pagination: {
|
|
1797
2103
|
collectionKey: "subjects",
|
|
1798
2104
|
coverageQueue: "subjects",
|
|
1799
|
-
coverageMode:
|
|
1800
|
-
after:
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
2105
|
+
coverageMode: subjectWindow.mode,
|
|
2106
|
+
after:
|
|
2107
|
+
subjectWindow.mode === "after"
|
|
2108
|
+
? parseAfterForCoverage(subjectWindow.after)
|
|
2109
|
+
: null,
|
|
2110
|
+
filters: {
|
|
2111
|
+
effort: options.adminEffort || "all",
|
|
2112
|
+
...(operatorView ? { operatorView } : {}),
|
|
2113
|
+
},
|
|
1804
2114
|
},
|
|
1805
2115
|
},
|
|
1806
2116
|
);
|
|
@@ -1890,6 +2200,22 @@ function featuredReorderOperation(options) {
|
|
|
1890
2200
|
);
|
|
1891
2201
|
}
|
|
1892
2202
|
|
|
2203
|
+
function featuredAddOperation(options) {
|
|
2204
|
+
const addIds = parseFeaturedSubjectIds(options.adminIds, "--subject-ids");
|
|
2205
|
+
const postedAfter = String(options.adminPostedAfter || "").trim();
|
|
2206
|
+
if (!postedAfter) {
|
|
2207
|
+
throw cliValidationError(
|
|
2208
|
+
"New Featured additions require --posted-after <ISO-8601-or-Unix-time>.",
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
return writeOperation(
|
|
2212
|
+
"featured.add",
|
|
2213
|
+
"POST",
|
|
2214
|
+
"/cli/admin/subjects/featured/additions",
|
|
2215
|
+
{ addIds, postedAfter },
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
|
|
1893
2219
|
function featuredRotateOperation(options) {
|
|
1894
2220
|
const removeIds = parseFeaturedSubjectIds(
|
|
1895
2221
|
options.adminRemoveIds,
|
|
@@ -1961,6 +2287,42 @@ export function parseRecommendationWindow(options) {
|
|
|
1961
2287
|
return { mode, after: mode === "after" ? options.adminAfter : "" };
|
|
1962
2288
|
}
|
|
1963
2289
|
|
|
2290
|
+
export function parseSubjectWindow(options) {
|
|
2291
|
+
const selected = [
|
|
2292
|
+
options.adminSinceRun ? "since-run" : "",
|
|
2293
|
+
options.adminAfter ? "after" : "",
|
|
2294
|
+
options.adminIncludeLegacy ? "legacy" : "",
|
|
2295
|
+
].filter(Boolean);
|
|
2296
|
+
if (selected.length > 1) {
|
|
2297
|
+
throw cliValidationError(
|
|
2298
|
+
"Choose one Subject window: --since-run, --after, or --include-legacy.",
|
|
2299
|
+
);
|
|
2300
|
+
}
|
|
2301
|
+
const mode = selected[0] || "since-run";
|
|
2302
|
+
if (mode === "after") parseAfterForCoverage(options.adminAfter);
|
|
2303
|
+
return { mode, after: mode === "after" ? options.adminAfter : "" };
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
function parseUtcDayKey(value) {
|
|
2307
|
+
const dayKey = String(value || "").trim();
|
|
2308
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dayKey);
|
|
2309
|
+
if (!match) {
|
|
2310
|
+
throw cliValidationError(
|
|
2311
|
+
"Pass a real UTC calendar date in YYYY-MM-DD format.",
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2314
|
+
const parsed = new Date(`${dayKey}T00:00:00.000Z`);
|
|
2315
|
+
if (
|
|
2316
|
+
!Number.isFinite(parsed.getTime()) ||
|
|
2317
|
+
parsed.toISOString().slice(0, 10) !== dayKey
|
|
2318
|
+
) {
|
|
2319
|
+
throw cliValidationError(
|
|
2320
|
+
"Pass a real UTC calendar date in YYYY-MM-DD format.",
|
|
2321
|
+
);
|
|
2322
|
+
}
|
|
2323
|
+
return dayKey;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
1964
2326
|
function parseAfterForCoverage(value) {
|
|
1965
2327
|
const raw = String(value || "").trim();
|
|
1966
2328
|
if (/^\d+$/.test(raw)) {
|
|
@@ -2151,12 +2513,40 @@ export function formatAdminJsonError(error) {
|
|
|
2151
2513
|
};
|
|
2152
2514
|
}
|
|
2153
2515
|
|
|
2154
|
-
export function assertAdminTodoHandoffResult(result) {
|
|
2516
|
+
export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
|
|
2155
2517
|
const runId = Number(result?.data?.run?.id || 0);
|
|
2518
|
+
const runScope = canonicalAdminRunScope(result?.data?.run);
|
|
2519
|
+
if (expectedRunScope && runScope !== expectedRunScope) {
|
|
2520
|
+
const error = cliValidationError(
|
|
2521
|
+
`The API returned a ${runScope} run when the CLI requested ${expectedRunScope}.`,
|
|
2522
|
+
);
|
|
2523
|
+
error.code = "LUMINE_ADMIN_RUN_SCOPE_UNSUPPORTED";
|
|
2524
|
+
throw error;
|
|
2525
|
+
}
|
|
2156
2526
|
const handoff = result?.data?.carryoverTodos;
|
|
2527
|
+
if (runScope === "featured") {
|
|
2528
|
+
if (
|
|
2529
|
+
!runId ||
|
|
2530
|
+
!handoff ||
|
|
2531
|
+
handoff.included !== false ||
|
|
2532
|
+
!Array.isArray(handoff.items) ||
|
|
2533
|
+
handoff.items.length !== 0 ||
|
|
2534
|
+
Number(handoff.count) !== 0 ||
|
|
2535
|
+
handoff.surfacedForRunId !== null ||
|
|
2536
|
+
Number(handoff.newlySurfacedCount) !== 0
|
|
2537
|
+
) {
|
|
2538
|
+
const error = cliValidationError(
|
|
2539
|
+
"The API did not confirm that carry-over telemetry was suppressed for the Featured-only run.",
|
|
2540
|
+
);
|
|
2541
|
+
error.code = "LUMINE_ADMIN_SCOPED_RUN_UNSUPPORTED";
|
|
2542
|
+
throw error;
|
|
2543
|
+
}
|
|
2544
|
+
return handoff;
|
|
2545
|
+
}
|
|
2157
2546
|
if (
|
|
2158
2547
|
!runId ||
|
|
2159
2548
|
!handoff ||
|
|
2549
|
+
handoff.included === false ||
|
|
2160
2550
|
!Array.isArray(handoff.items) ||
|
|
2161
2551
|
Number(handoff.count) !== handoff.items.length ||
|
|
2162
2552
|
Number(handoff.surfacedForRunId) !== runId ||
|
|
@@ -2223,6 +2613,16 @@ function parseCommentMode(value) {
|
|
|
2223
2613
|
return mode;
|
|
2224
2614
|
}
|
|
2225
2615
|
|
|
2616
|
+
function parseDailyRunScope(value) {
|
|
2617
|
+
const scope = String(value || "full")
|
|
2618
|
+
.trim()
|
|
2619
|
+
.toLowerCase();
|
|
2620
|
+
if (!["full", "featured"].includes(scope)) {
|
|
2621
|
+
throw cliValidationError("--scope must be full or featured.");
|
|
2622
|
+
}
|
|
2623
|
+
return scope;
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2226
2626
|
function parseEscalationStatus(value) {
|
|
2227
2627
|
const status = String(value || "")
|
|
2228
2628
|
.trim()
|
|
@@ -2436,7 +2836,7 @@ function parseChoice(value, label, choices) {
|
|
|
2436
2836
|
return normalized;
|
|
2437
2837
|
}
|
|
2438
2838
|
|
|
2439
|
-
function defaultDailyRunKey() {
|
|
2839
|
+
function defaultDailyRunKey(runScope = "full") {
|
|
2440
2840
|
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
2441
2841
|
timeZone: "Asia/Bangkok",
|
|
2442
2842
|
year: "numeric",
|
|
@@ -2446,7 +2846,10 @@ function defaultDailyRunKey() {
|
|
|
2446
2846
|
const value = Object.fromEntries(
|
|
2447
2847
|
parts.map((part) => [part.type, part.value]),
|
|
2448
2848
|
);
|
|
2449
|
-
|
|
2849
|
+
const day = `${value.year}-${value.month}-${value.day}`;
|
|
2850
|
+
return runScope === "full"
|
|
2851
|
+
? `daily:${day}`
|
|
2852
|
+
: `scoped:${runScope}:${day}:${randomUUID()}`;
|
|
2450
2853
|
}
|
|
2451
2854
|
|
|
2452
2855
|
function cliValidationError(message) {
|
|
@@ -2524,6 +2927,48 @@ function printAdminMonthlyAiCosts(monthlyAiCosts) {
|
|
|
2524
2927
|
}
|
|
2525
2928
|
}
|
|
2526
2929
|
|
|
2930
|
+
function printAdminDailyAiCosts(dailyAiCosts) {
|
|
2931
|
+
console.log(
|
|
2932
|
+
`Application AI-cost ledger for ${dailyAiCosts.day.dayKey} (closed UTC day): ${formatAdminUsd(dailyAiCosts.summary?.estimatedCostUsd)} across ${Number(dailyAiCosts.summary?.requestCount || 0)} request(s).`,
|
|
2933
|
+
);
|
|
2934
|
+
for (const row of dailyAiCosts.byProviderModel || []) {
|
|
2935
|
+
console.log(
|
|
2936
|
+
` ${row.provider || "unknown"}/${row.model || "unknown"}: ${formatAdminUsd(row.estimatedCostUsd)} · ${Number(row.totalTokens || 0)} token(s) · ${Number(row.requestCount || 0)} request(s).`,
|
|
2937
|
+
);
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
function printAdminEnergyBudget(energyBudget) {
|
|
2942
|
+
const headline = energyBudget.lastCompletedDay;
|
|
2943
|
+
if (headline) {
|
|
2944
|
+
console.log(
|
|
2945
|
+
`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).`,
|
|
2946
|
+
);
|
|
2947
|
+
} else {
|
|
2948
|
+
console.log("AI Energy budget health: no completed UTC day in the requested window.");
|
|
2949
|
+
}
|
|
2950
|
+
console.log(
|
|
2951
|
+
"day | charged | overflow | users | rechg | runs | calls/run avg/p90 | $/run avg/p90 | stops chg/unchg | busy | telemetry rows",
|
|
2952
|
+
);
|
|
2953
|
+
for (const day of energyBudget.byDay || []) {
|
|
2954
|
+
const m = day.telemetry.metrics;
|
|
2955
|
+
const runs = day.runs.total;
|
|
2956
|
+
console.log(
|
|
2957
|
+
`${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}`,
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
console.log("* = in-progress UTC day; never headline it.");
|
|
2961
|
+
const flags = energyBudget.flags || [];
|
|
2962
|
+
if (flags.length === 0) {
|
|
2963
|
+
console.log("Flags: none.");
|
|
2964
|
+
return;
|
|
2965
|
+
}
|
|
2966
|
+
console.log(`Flags (${flags.length}) — record each as a carry-over todo and escalate; never auto-enforce:`);
|
|
2967
|
+
for (const flag of flags) {
|
|
2968
|
+
console.log(` ${flag.dayKey} ${flag.code}: ${flag.message}`);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2527
2972
|
function formatAdminMediaUsd(value) {
|
|
2528
2973
|
const amount = Number(value);
|
|
2529
2974
|
if (!Number.isFinite(amount)) return "unavailable";
|
|
@@ -2650,10 +3095,16 @@ function printAdminMonthlyMediaCosts(monthlyMediaCosts) {
|
|
|
2650
3095
|
);
|
|
2651
3096
|
}
|
|
2652
3097
|
|
|
2653
|
-
async function printSpooledAdminResult({ result, storage }) {
|
|
3098
|
+
async function printSpooledAdminResult({ operation, result, storage }) {
|
|
2654
3099
|
const data = result?.data || {};
|
|
2655
3100
|
const count = Number(storage.candidateCount || 0);
|
|
2656
|
-
if (
|
|
3101
|
+
if (operation.name === "featured.history") {
|
|
3102
|
+
printFeaturedHistorySummary(data);
|
|
3103
|
+
console.log(`${count} Featured history event(s):`);
|
|
3104
|
+
await forEachPaginatedResultItem(result, async (event) => {
|
|
3105
|
+
printFeaturedHistoryEvent(event);
|
|
3106
|
+
});
|
|
3107
|
+
} else if (storage.collectionKey === "subjects") {
|
|
2657
3108
|
console.log(`${count} subject(s):`);
|
|
2658
3109
|
await forEachPaginatedResultItem(result, async (subject) => {
|
|
2659
3110
|
console.log(
|
|
@@ -2779,6 +3230,28 @@ function printAdminResult({ operation, result }) {
|
|
|
2779
3230
|
);
|
|
2780
3231
|
return;
|
|
2781
3232
|
}
|
|
3233
|
+
if (data.review && data.artifacts?.reviewSessionPath) {
|
|
3234
|
+
console.log(
|
|
3235
|
+
`Production-log review #${data.review.id}: ${data.completionStatus || data.review.status}.`,
|
|
3236
|
+
);
|
|
3237
|
+
console.log(`Review session: ${data.artifacts.reviewSessionPath}`);
|
|
3238
|
+
if (data.artifacts.latestSnapshot?.snapshotPath) {
|
|
3239
|
+
console.log(
|
|
3240
|
+
`Latest captured bytes: ${data.artifacts.latestSnapshot.snapshotPath}`,
|
|
3241
|
+
);
|
|
3242
|
+
}
|
|
3243
|
+
if (
|
|
3244
|
+
data.completionStatus === "needs_review" ||
|
|
3245
|
+
data.completionStatus === "post_clear_review_required"
|
|
3246
|
+
) {
|
|
3247
|
+
console.log(
|
|
3248
|
+
data.completionStatus === "post_clear_review_required"
|
|
3249
|
+
? "The API error log was cleared in place. Review the post-clear snapshot, then rerun finish with --reviewed to close the lease."
|
|
3250
|
+
: "New bytes arrived at the final boundary. Review the latest snapshot, then rerun finish with --reviewed.",
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
return;
|
|
3254
|
+
}
|
|
2782
3255
|
if (data.review) {
|
|
2783
3256
|
console.log(
|
|
2784
3257
|
`Confirmed Build #${data.review.buildId} runtime at published artifact #${data.review.publishedArtifactVersionId}.`,
|
|
@@ -2791,6 +3264,14 @@ function printAdminResult({ operation, result }) {
|
|
|
2791
3264
|
printAdminMonthlyAiCosts(data.monthlyAiCosts);
|
|
2792
3265
|
return;
|
|
2793
3266
|
}
|
|
3267
|
+
if (data.dailyAiCosts) {
|
|
3268
|
+
printAdminDailyAiCosts(data.dailyAiCosts);
|
|
3269
|
+
return;
|
|
3270
|
+
}
|
|
3271
|
+
if (data.energyBudget) {
|
|
3272
|
+
printAdminEnergyBudget(data.energyBudget);
|
|
3273
|
+
return;
|
|
3274
|
+
}
|
|
2794
3275
|
if (data.monthlyMediaCosts) {
|
|
2795
3276
|
printAdminMonthlyMediaCosts(data.monthlyMediaCosts);
|
|
2796
3277
|
return;
|
|
@@ -2810,8 +3291,9 @@ function printAdminResult({ operation, result }) {
|
|
|
2810
3291
|
}
|
|
2811
3292
|
if (data.report) {
|
|
2812
3293
|
const report = data.report;
|
|
3294
|
+
const historical = report.basis?.kind === "historical_reconstruction";
|
|
2813
3295
|
console.log(
|
|
2814
|
-
|
|
3296
|
+
`${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).`}`,
|
|
2815
3297
|
);
|
|
2816
3298
|
for (const coverage of report.queueCoverage) {
|
|
2817
3299
|
console.log(
|
|
@@ -2826,10 +3308,21 @@ function printAdminResult({ operation, result }) {
|
|
|
2826
3308
|
` ${String(escalation.severity || "attention").toUpperCase()} ${target} — ${escalation.summary}`,
|
|
2827
3309
|
);
|
|
2828
3310
|
}
|
|
2829
|
-
|
|
3311
|
+
if (historical) {
|
|
3312
|
+
console.log(
|
|
3313
|
+
"The live brief and carry-over todo state were not snapshotted for this completed run.",
|
|
3314
|
+
);
|
|
3315
|
+
} else {
|
|
3316
|
+
printTodoItems(report.carryoverTodos?.items || [], "Unfinished work");
|
|
3317
|
+
}
|
|
2830
3318
|
if (report.sponsorIntegrity) {
|
|
3319
|
+
const pendingApplications = Number.isSafeInteger(
|
|
3320
|
+
report.sponsorIntegrity.pendingApplications,
|
|
3321
|
+
)
|
|
3322
|
+
? `; ${report.sponsorIntegrity.pendingApplications} pending application(s)`
|
|
3323
|
+
: "; historical pending-application count unavailable";
|
|
2831
3324
|
console.log(
|
|
2832
|
-
`Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s)
|
|
3325
|
+
`Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s)${pendingApplications}.`,
|
|
2833
3326
|
);
|
|
2834
3327
|
}
|
|
2835
3328
|
const surfaces = report.brief?.engagementPulse?.surfaces;
|
|
@@ -2849,10 +3342,12 @@ function printAdminResult({ operation, result }) {
|
|
|
2849
3342
|
if (deltas.length)
|
|
2850
3343
|
console.log(`Engagement deltas: ${deltas.join(", ")}.`);
|
|
2851
3344
|
}
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
3345
|
+
if (!historical) {
|
|
3346
|
+
const notableCount = Array.isArray(report.brief?.notableCandidates)
|
|
3347
|
+
? report.brief.notableCandidates.length
|
|
3348
|
+
: 0;
|
|
3349
|
+
console.log(`Notable-user candidates in this brief: ${notableCount}.`);
|
|
3350
|
+
}
|
|
2856
3351
|
return;
|
|
2857
3352
|
}
|
|
2858
3353
|
if (data.inspection) {
|
|
@@ -2916,6 +3411,15 @@ function printAdminResult({ operation, result }) {
|
|
|
2916
3411
|
printTodoItems([data.todo], "Canonical todo");
|
|
2917
3412
|
return;
|
|
2918
3413
|
}
|
|
3414
|
+
if (Object.hasOwn(data, "isNotable") && data.user) {
|
|
3415
|
+
console.log(
|
|
3416
|
+
`${data.user.username} (user #${data.user.id}) is${data.isNotable ? "" : " not"} currently in Notable Users.`,
|
|
3417
|
+
);
|
|
3418
|
+
if (data.notableUser?.reason) {
|
|
3419
|
+
console.log(`Reason: ${data.notableUser.reason}`);
|
|
3420
|
+
}
|
|
3421
|
+
return;
|
|
3422
|
+
}
|
|
2919
3423
|
if (data.bucket && Array.isArray(data.memberUserIds)) {
|
|
2920
3424
|
const added = Array.isArray(data.accounts)
|
|
2921
3425
|
? `; added ${data.accounts.length} explicit account(s)`
|
|
@@ -2930,13 +3434,13 @@ function printAdminResult({ operation, result }) {
|
|
|
2930
3434
|
console.log("No active delegated administrator daily run.");
|
|
2931
3435
|
if (data.lastRun) {
|
|
2932
3436
|
console.log(
|
|
2933
|
-
`Last run #${data.lastRun.id}: ${data.lastRun.status}; identity ${data.lastRun.identity.key}; comments ${data.lastRun.commentMode}.`,
|
|
3437
|
+
`Last run #${data.lastRun.id}: ${data.lastRun.status}; scope ${canonicalAdminRunScope(data.lastRun)}; identity ${data.lastRun.identity.key}; comments ${data.lastRun.commentMode}.`,
|
|
2934
3438
|
);
|
|
2935
3439
|
}
|
|
2936
3440
|
return;
|
|
2937
3441
|
}
|
|
2938
3442
|
console.log(
|
|
2939
|
-
`Run #${data.run.id}: ${data.run.status}; identity ${data.run.identity.key}; comments ${data.run.commentMode}.`,
|
|
3443
|
+
`Run #${data.run.id}: ${data.run.status}; scope ${canonicalAdminRunScope(data.run)}; identity ${data.run.identity.key}; comments ${data.run.commentMode}.`,
|
|
2940
3444
|
);
|
|
2941
3445
|
if (data.scheduledDay && data.scheduledIdentity) {
|
|
2942
3446
|
console.log(
|
|
@@ -2967,11 +3471,20 @@ function printAdminResult({ operation, result }) {
|
|
|
2967
3471
|
);
|
|
2968
3472
|
console.log(
|
|
2969
3473
|
data.activeRun
|
|
2970
|
-
? `Active run #${data.activeRun.id}: ${data.activeRun.identity.key}; comments ${data.activeRun.commentMode}.`
|
|
3474
|
+
? `Active run #${data.activeRun.id}: scope ${canonicalAdminRunScope(data.activeRun)}; identity ${data.activeRun.identity.key}; comments ${data.activeRun.commentMode}.`
|
|
2971
3475
|
: "No active delegated administrator daily run.",
|
|
2972
3476
|
);
|
|
2973
3477
|
return;
|
|
2974
3478
|
}
|
|
3479
|
+
if (operation.name === "featured.history") {
|
|
3480
|
+
printFeaturedHistorySummary(data);
|
|
3481
|
+
console.log(`${(data.events || []).length} Featured history event(s):`);
|
|
3482
|
+
for (const event of data.events || []) {
|
|
3483
|
+
printFeaturedHistoryEvent(event);
|
|
3484
|
+
}
|
|
3485
|
+
printPagination(data.pagination);
|
|
3486
|
+
return;
|
|
3487
|
+
}
|
|
2975
3488
|
if (Array.isArray(data.subjects)) {
|
|
2976
3489
|
console.log(`${data.subjects.length} subject(s):`);
|
|
2977
3490
|
for (const subject of data.subjects) {
|
|
@@ -3138,6 +3651,32 @@ function printAdminResult({ operation, result }) {
|
|
|
3138
3651
|
);
|
|
3139
3652
|
}
|
|
3140
3653
|
|
|
3654
|
+
function printFeaturedHistorySummary(data) {
|
|
3655
|
+
const coverage = data.coverage || {};
|
|
3656
|
+
console.log(
|
|
3657
|
+
coverage.complete
|
|
3658
|
+
? `Featured history coverage begins at ${coverage.startedAt}.`
|
|
3659
|
+
: "Featured history coverage is not complete.",
|
|
3660
|
+
);
|
|
3661
|
+
for (const subject of data.subjects || []) {
|
|
3662
|
+
const lifetime = subject.knownFeatured
|
|
3663
|
+
? "previously Featured"
|
|
3664
|
+
: subject.neverFeatured === true
|
|
3665
|
+
? "never Featured"
|
|
3666
|
+
: "history unknown";
|
|
3667
|
+
console.log(
|
|
3668
|
+
`#${subject.id} ${subject.title || "(untitled)"} — ${lifetime}${subject.featured?.member ? ` — current position ${subject.featured.order}` : ""}`,
|
|
3669
|
+
);
|
|
3670
|
+
console.log(` ${subject.url}`);
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
function printFeaturedHistoryEvent(event) {
|
|
3675
|
+
console.log(
|
|
3676
|
+
`#${event.id} subject:${event.subjectId} ${event.action} ${event.fromPosition ?? "-"}->${event.toPosition ?? "-"} — ${event.operation}`,
|
|
3677
|
+
);
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3141
3680
|
function printTodoItems(items, heading) {
|
|
3142
3681
|
console.log(`${heading}: ${items.length} item(s).`);
|
|
3143
3682
|
for (const todo of items) {
|