@stage5/lumine 0.2.54 → 0.2.56
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 -12
- package/lib/admin-workflows.js +759 -59
- package/lib/admin.js +77 -3
- package/lib/auth.js +15 -9
- package/lib/commands.js +3 -3
- package/lib/sponsor.js +52 -32
- package/package.json +1 -1
- package/sdk/LUMINE_ADMIN.md +12 -7
package/lib/admin.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { once } from "node:events";
|
|
2
3
|
import { readFileSync } from "node:fs";
|
|
3
4
|
import { assertAuthScope, resolveAuth } from "./auth.js";
|
|
4
5
|
import { requestJson } from "./http.js";
|
|
@@ -8,7 +9,13 @@ import {
|
|
|
8
9
|
validateNewsEditorial,
|
|
9
10
|
writeNewsClaimArtifacts,
|
|
10
11
|
} from "./admin-news.js";
|
|
11
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
forEachPaginatedResultItem,
|
|
14
|
+
getPaginatedResultStorage,
|
|
15
|
+
runAutomaticPagination,
|
|
16
|
+
runBatchSkips,
|
|
17
|
+
writePaginatedResultJson,
|
|
18
|
+
} from "./admin-workflows.js";
|
|
12
19
|
import {
|
|
13
20
|
parseBuildReviewReceipt,
|
|
14
21
|
runManagedBuildReview,
|
|
@@ -380,9 +387,25 @@ export function assertRecommendationWindowResult({ operation, result }) {
|
|
|
380
387
|
}
|
|
381
388
|
}
|
|
382
389
|
|
|
383
|
-
function finishAdminOutput({ options, operation, result }) {
|
|
390
|
+
async function finishAdminOutput({ options, operation, result }) {
|
|
391
|
+
const paginationStorage = getPaginatedResultStorage(result);
|
|
384
392
|
if (options.json) {
|
|
385
|
-
|
|
393
|
+
if (paginationStorage) {
|
|
394
|
+
await writePaginatedResultJson({
|
|
395
|
+
result,
|
|
396
|
+
write: async (chunk) => {
|
|
397
|
+
if (!process.stdout.write(chunk)) {
|
|
398
|
+
await once(process.stdout, "drain");
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
} else {
|
|
403
|
+
console.log(JSON.stringify(result));
|
|
404
|
+
}
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
if (paginationStorage) {
|
|
408
|
+
await printSpooledAdminResult({ result, storage: paginationStorage });
|
|
386
409
|
return result;
|
|
387
410
|
}
|
|
388
411
|
printAdminResult({ operation, result });
|
|
@@ -2375,6 +2398,57 @@ function printAdminMonthlyMediaCosts(monthlyMediaCosts) {
|
|
|
2375
2398
|
);
|
|
2376
2399
|
}
|
|
2377
2400
|
|
|
2401
|
+
async function printSpooledAdminResult({ result, storage }) {
|
|
2402
|
+
const data = result?.data || {};
|
|
2403
|
+
const count = Number(storage.candidateCount || 0);
|
|
2404
|
+
if (storage.collectionKey === "subjects") {
|
|
2405
|
+
console.log(`${count} subject(s):`);
|
|
2406
|
+
await forEachPaginatedResultItem(result, async (subject) => {
|
|
2407
|
+
console.log(
|
|
2408
|
+
`#${subject.id} ${subject.title || "(untitled)"} — ${subject.author?.username || "unknown"} — effort ${subject.effortLevel ?? "unknown"}`,
|
|
2409
|
+
);
|
|
2410
|
+
console.log(` ${subject.url}`);
|
|
2411
|
+
});
|
|
2412
|
+
} else if (storage.collectionKey === "events") {
|
|
2413
|
+
console.log(`${count} audit event(s):`);
|
|
2414
|
+
await forEachPaginatedResultItem(result, async (event) => {
|
|
2415
|
+
const target =
|
|
2416
|
+
event.targetType && event.targetId
|
|
2417
|
+
? ` ${event.targetType}:${event.targetId}`
|
|
2418
|
+
: "";
|
|
2419
|
+
console.log(
|
|
2420
|
+
`#${event.id} run ${event.runId ?? "-"} ${event.action}${target} — ${event.result}${event.changed === true ? " (changed)" : event.changed === false ? " (no change)" : ""}`,
|
|
2421
|
+
);
|
|
2422
|
+
});
|
|
2423
|
+
} else if (storage.collectionKey === "comments") {
|
|
2424
|
+
console.log(`${count} comment(s) for ${data.subject?.url || "this target"}:`);
|
|
2425
|
+
await forEachPaginatedResultItem(result, async (comment) => {
|
|
2426
|
+
console.log(
|
|
2427
|
+
`#${comment.id} ${comment.author?.username || "unknown"}: ${comment.content || "(empty)"}`,
|
|
2428
|
+
);
|
|
2429
|
+
});
|
|
2430
|
+
} else if (storage.collectionKey === "items") {
|
|
2431
|
+
console.log(`${count} recommendation candidate(s):`);
|
|
2432
|
+
await forEachPaginatedResultItem(result, async (item) => {
|
|
2433
|
+
console.log(`#${item.contentId} ${item.contentType}`);
|
|
2434
|
+
if (item.url || item.subjectUrl) {
|
|
2435
|
+
console.log(` ${item.url || item.subjectUrl}`);
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
} else if (storage.collectionKey === "builds") {
|
|
2439
|
+
console.log(`${count} Build candidate(s):`);
|
|
2440
|
+
await forEachPaginatedResultItem(result, async (build) => {
|
|
2441
|
+
console.log(`#${build.id} ${build.title || "(untitled)"}`);
|
|
2442
|
+
if (build.url) console.log(` ${build.url}`);
|
|
2443
|
+
});
|
|
2444
|
+
} else {
|
|
2445
|
+
console.log(
|
|
2446
|
+
`${count} ${storage.collectionKey} candidate(s) saved at ${storage.spoolPath}.`,
|
|
2447
|
+
);
|
|
2448
|
+
}
|
|
2449
|
+
printPagination(data.pagination);
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2378
2452
|
function printAdminResult({ operation, result }) {
|
|
2379
2453
|
const data = result?.data || {};
|
|
2380
2454
|
if (Array.isArray(data.applications)) {
|
package/lib/auth.js
CHANGED
|
@@ -6,6 +6,9 @@ import { requestJson } from "./http.js";
|
|
|
6
6
|
import { sleep, trimTrailingSlash } from "./util.js";
|
|
7
7
|
|
|
8
8
|
export async function login(options) {
|
|
9
|
+
const report = options.loginProgressToStderr
|
|
10
|
+
? (...args) => console.error(...args)
|
|
11
|
+
: (...args) => console.log(...args);
|
|
9
12
|
const start = await requestJson({
|
|
10
13
|
method: "POST",
|
|
11
14
|
url: `${options.apiUrl}/cli/device/start`,
|
|
@@ -23,15 +26,15 @@ export async function login(options) {
|
|
|
23
26
|
});
|
|
24
27
|
|
|
25
28
|
const approvalUrl = start.verificationUriComplete || start.verificationUri;
|
|
26
|
-
|
|
29
|
+
report("Connect Lumine CLI to Twinkle.");
|
|
27
30
|
if (options.openBrowser && approvalUrl) {
|
|
28
|
-
|
|
31
|
+
report("Opening Twinkle in your browser...");
|
|
29
32
|
const opened = await openBrowser(approvalUrl);
|
|
30
|
-
if (!opened)
|
|
33
|
+
if (!opened) report("Could not open the browser automatically.");
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
report(`Approval link: ${approvalUrl}`);
|
|
36
|
+
report(`Code: ${start.userCode}`);
|
|
37
|
+
report("Leave this terminal open. Waiting for approval...");
|
|
35
38
|
|
|
36
39
|
const intervalMs = Math.max(Number(start.interval || 3), 1) * 1000;
|
|
37
40
|
const startedAt = Date.now();
|
|
@@ -52,10 +55,10 @@ export async function login(options) {
|
|
|
52
55
|
userId: tokenResponse.user?.id || null,
|
|
53
56
|
expiresAt: Date.now() + Number(tokenResponse.expiresIn || 0) * 1000,
|
|
54
57
|
});
|
|
55
|
-
|
|
58
|
+
report(
|
|
56
59
|
`Logged in${tokenResponse.user?.username ? ` as ${tokenResponse.user.username}` : ""}.`,
|
|
57
60
|
);
|
|
58
|
-
|
|
61
|
+
report("You can now run `lumine` to choose a project.");
|
|
59
62
|
return;
|
|
60
63
|
}
|
|
61
64
|
|
|
@@ -112,7 +115,10 @@ export async function ensureAuth(options) {
|
|
|
112
115
|
} catch (error) {
|
|
113
116
|
if (options.authToken || !isMissingLoginError(error)) throw error;
|
|
114
117
|
}
|
|
115
|
-
await login(
|
|
118
|
+
await login({
|
|
119
|
+
...options,
|
|
120
|
+
loginProgressToStderr: Boolean(options.json),
|
|
121
|
+
});
|
|
116
122
|
return await resolveAuth(options);
|
|
117
123
|
}
|
|
118
124
|
|
package/lib/commands.js
CHANGED
|
@@ -2730,8 +2730,8 @@ export function printHelp() {
|
|
|
2730
2730
|
lumine agent --provider <codex|claude-code> "<build request>"
|
|
2731
2731
|
lumine sponsor agreement|apply|status|withdraw
|
|
2732
2732
|
lumine sponsor capacity [--concurrency <n>] [--helpers <n>] [--daily-limit <n>] [--weekly-limit <n>]
|
|
2733
|
-
lumine sponsor duty start
|
|
2734
|
-
lumine sponsor duty pause|resume|stop
|
|
2733
|
+
lumine sponsor duty start --provider <codex|claude-code> [--model <name>] [--effort <level>] [--service-tier <tier>]
|
|
2734
|
+
lumine sponsor duty pause|resume|stop
|
|
2735
2735
|
lumine sponsor jobs
|
|
2736
2736
|
lumine app-mcp <published-app-url-or-id> [--no-open]
|
|
2737
2737
|
lumine new [title]
|
|
@@ -2907,7 +2907,7 @@ Options:
|
|
|
2907
2907
|
--since-run Recommendations since the previous completed run (default)
|
|
2908
2908
|
--include-legacy Explicitly include the full historical recommendation queue
|
|
2909
2909
|
--all Automatically read every page in the canonical snapshot
|
|
2910
|
-
--checkpoint <file> Persist
|
|
2910
|
+
--checkpoint <file> Persist bounded pagination metadata or batch progress
|
|
2911
2911
|
--resume Resume the exact request recorded by --checkpoint
|
|
2912
2912
|
--output <file> Save an admin result or newspaper claim as JSON
|
|
2913
2913
|
--output-dir <dir> Directory for managed Build review evidence
|
package/lib/sponsor.js
CHANGED
|
@@ -6,7 +6,7 @@ import { stdin as input, stdout as output } from "node:process";
|
|
|
6
6
|
|
|
7
7
|
import { agentCommand } from "./agent.js";
|
|
8
8
|
import { notifyBuildOwnerOfContribution } from "./api.js";
|
|
9
|
-
import { resolveAuth, writeAuthFile } from "./auth.js";
|
|
9
|
+
import { ensureAuth, resolveAuth, writeAuthFile } from "./auth.js";
|
|
10
10
|
import { readCompleteBuildForumSnapshot } from "./forum.js";
|
|
11
11
|
import { requestJson } from "./http.js";
|
|
12
12
|
import { sleep } from "./util.js";
|
|
@@ -24,7 +24,7 @@ export async function sponsorCommand(options, commandServices) {
|
|
|
24
24
|
.trim()
|
|
25
25
|
.toLowerCase();
|
|
26
26
|
if (area === "agreement") {
|
|
27
|
-
const auth = await
|
|
27
|
+
const auth = await ensureAuth(options);
|
|
28
28
|
const agreement = await sponsorRequest({
|
|
29
29
|
options,
|
|
30
30
|
auth,
|
|
@@ -50,7 +50,7 @@ export async function sponsorCommand(options, commandServices) {
|
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
if (area === "jobs") {
|
|
53
|
-
const auth = await
|
|
53
|
+
const auth = await ensureAuth(options);
|
|
54
54
|
const result = await sponsorRequest({
|
|
55
55
|
options,
|
|
56
56
|
auth,
|
|
@@ -67,7 +67,7 @@ export async function sponsorCommand(options, commandServices) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
async function applyToSponsor(options) {
|
|
70
|
-
const auth = await
|
|
70
|
+
const auth = await ensureAuth(options);
|
|
71
71
|
const agreement = await sponsorRequest({ options, auth, path: "/agreement" });
|
|
72
72
|
if (!options.json) {
|
|
73
73
|
printSponsorAgreement(agreement, { ...options, json: false });
|
|
@@ -135,7 +135,7 @@ async function applyToSponsor(options) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
async function withdrawSponsorApplication(options) {
|
|
138
|
-
const auth = await
|
|
138
|
+
const auth = await ensureAuth(options);
|
|
139
139
|
if (!options.assumeYes && input.isTTY && output.isTTY) {
|
|
140
140
|
const rl = readline.createInterface({ input, output });
|
|
141
141
|
try {
|
|
@@ -162,7 +162,7 @@ async function withdrawSponsorApplication(options) {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
async function updateSponsorCapacity(options) {
|
|
165
|
-
const auth = await
|
|
165
|
+
const auth = await ensureAuth(options);
|
|
166
166
|
const status = await sponsorRequest({ options, auth, path: "/status" });
|
|
167
167
|
if (!status.sponsor) {
|
|
168
168
|
throw new Error("An approved sponsor account is required first.");
|
|
@@ -212,24 +212,41 @@ async function sponsorDutyCommand(options, args, commandServices) {
|
|
|
212
212
|
.trim()
|
|
213
213
|
.toLowerCase();
|
|
214
214
|
if (action === "status") {
|
|
215
|
+
if (args.length > 1) throw new Error(sponsorUsage());
|
|
215
216
|
await printSponsorStatus(options);
|
|
216
217
|
return;
|
|
217
218
|
}
|
|
218
|
-
|
|
219
|
-
|
|
219
|
+
if (args.length > 1 || options.sponsorPersona) {
|
|
220
|
+
throw new Error(
|
|
221
|
+
"Sponsor duty is shared by Zero and Ciel. Remove the persona argument.",
|
|
222
|
+
);
|
|
223
|
+
}
|
|
220
224
|
if (["pause", "resume", "stop"].includes(action)) {
|
|
225
|
+
const auth = await ensureAuth(options);
|
|
226
|
+
const status = await sponsorRequest({ options, auth, path: "/status" });
|
|
227
|
+
const currentDuties = (status.duties || []).filter((duty) =>
|
|
228
|
+
["active", "paused"].includes(String(duty.state || "")),
|
|
229
|
+
);
|
|
230
|
+
if (currentDuties.length === 0) {
|
|
231
|
+
throw new Error("No active sponsor duty session was found.");
|
|
232
|
+
}
|
|
233
|
+
if (currentDuties.length > 1) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
`Multiple legacy duty sessions are still open (${currentDuties.map((duty) => `#${duty.id}`).join(", ")}). Stop them with the CLI version that started them before using shared duty.`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
const dutyId = Number(currentDuties[0].id || 0);
|
|
239
|
+
if (!dutyId) throw new Error("Twinkle returned an invalid duty session.");
|
|
221
240
|
const state =
|
|
222
241
|
action === "resume" ? "active" : action === "stop" ? "stopped" : "paused";
|
|
223
242
|
const result = await sponsorRequest({
|
|
224
243
|
options,
|
|
225
244
|
auth,
|
|
226
245
|
method: "POST",
|
|
227
|
-
path:
|
|
228
|
-
body: { state },
|
|
246
|
+
path: "/duty/state",
|
|
247
|
+
body: { dutySessionId: dutyId, state },
|
|
229
248
|
});
|
|
230
|
-
printJsonOrLines(options, result, [
|
|
231
|
-
`${displayPersona(persona)} duty is now ${state}.`,
|
|
232
|
-
]);
|
|
249
|
+
printJsonOrLines(options, result, [`Sponsor duty is now ${state}.`]);
|
|
233
250
|
return;
|
|
234
251
|
}
|
|
235
252
|
if (action !== "start") throw new Error(sponsorUsage());
|
|
@@ -242,13 +259,14 @@ async function sponsorDutyCommand(options, args, commandServices) {
|
|
|
242
259
|
"--service-tier is currently supported only by the Codex duty adapter.",
|
|
243
260
|
);
|
|
244
261
|
}
|
|
262
|
+
const auth = await ensureAuth(options);
|
|
245
263
|
const started = await sponsorRequest({
|
|
246
264
|
options,
|
|
247
265
|
auth,
|
|
248
266
|
method: "POST",
|
|
249
267
|
path: "/duty/start",
|
|
250
268
|
body: {
|
|
251
|
-
|
|
269
|
+
scope: "shared",
|
|
252
270
|
provider,
|
|
253
271
|
requestedModel: options.model || null,
|
|
254
272
|
requestedEffort: options.sponsorEffort || null,
|
|
@@ -259,7 +277,6 @@ async function sponsorDutyCommand(options, args, commandServices) {
|
|
|
259
277
|
await runSponsorDuty({
|
|
260
278
|
options,
|
|
261
279
|
auth,
|
|
262
|
-
persona,
|
|
263
280
|
provider,
|
|
264
281
|
started,
|
|
265
282
|
commandServices,
|
|
@@ -269,7 +286,6 @@ async function sponsorDutyCommand(options, args, commandServices) {
|
|
|
269
286
|
async function runSponsorDuty({
|
|
270
287
|
options,
|
|
271
288
|
auth,
|
|
272
|
-
persona,
|
|
273
289
|
provider,
|
|
274
290
|
started,
|
|
275
291
|
commandServices,
|
|
@@ -279,6 +295,9 @@ async function runSponsorDuty({
|
|
|
279
295
|
if (!dutyId || !leaseToken) {
|
|
280
296
|
throw new Error("Twinkle did not return a valid sponsor duty lease.");
|
|
281
297
|
}
|
|
298
|
+
if (started.duty?.scope !== "shared") {
|
|
299
|
+
throw new Error("Twinkle did not return a shared sponsor duty lease.");
|
|
300
|
+
}
|
|
282
301
|
let canonicalDuty = started.duty;
|
|
283
302
|
let stopRequested = false;
|
|
284
303
|
let dutyLeaseError = null;
|
|
@@ -332,9 +351,7 @@ async function runSponsorDuty({
|
|
|
332
351
|
Math.max(10, Number(started.heartbeatEverySeconds || 30)) * 1_000,
|
|
333
352
|
);
|
|
334
353
|
|
|
335
|
-
console.log(
|
|
336
|
-
`${displayPersona(persona)} sponsor duty started with ${provider}.`,
|
|
337
|
-
);
|
|
354
|
+
console.log(`Shared Zero/Ciel sponsor duty started with ${provider}.`);
|
|
338
355
|
printDutyRuntime(canonicalDuty);
|
|
339
356
|
console.log(
|
|
340
357
|
"The Workshop is now discoverable to users. Press Ctrl-C for a graceful stop.",
|
|
@@ -364,7 +381,6 @@ async function runSponsorDuty({
|
|
|
364
381
|
sponsorAuth: auth,
|
|
365
382
|
dutyId,
|
|
366
383
|
dutyLeaseToken: leaseToken,
|
|
367
|
-
persona,
|
|
368
384
|
provider,
|
|
369
385
|
claim,
|
|
370
386
|
commandServices,
|
|
@@ -384,8 +400,8 @@ async function runSponsorDuty({
|
|
|
384
400
|
options,
|
|
385
401
|
auth,
|
|
386
402
|
method: "POST",
|
|
387
|
-
path:
|
|
388
|
-
body: { state: "paused" },
|
|
403
|
+
path: "/duty/state",
|
|
404
|
+
body: { dutySessionId: dutyId, state: "paused" },
|
|
389
405
|
});
|
|
390
406
|
canonicalDuty = paused.duty || canonicalDuty;
|
|
391
407
|
}
|
|
@@ -400,8 +416,8 @@ async function runSponsorDuty({
|
|
|
400
416
|
options,
|
|
401
417
|
auth,
|
|
402
418
|
method: "POST",
|
|
403
|
-
path:
|
|
404
|
-
body: { state: "stopped" },
|
|
419
|
+
path: "/duty/state",
|
|
420
|
+
body: { dutySessionId: dutyId, state: "stopped" },
|
|
405
421
|
}).catch((error) => {
|
|
406
422
|
if (!dutyLeaseError) {
|
|
407
423
|
console.error(
|
|
@@ -411,7 +427,7 @@ async function runSponsorDuty({
|
|
|
411
427
|
});
|
|
412
428
|
}
|
|
413
429
|
}
|
|
414
|
-
console.log(
|
|
430
|
+
console.log("Shared Zero/Ciel sponsor duty stopped.");
|
|
415
431
|
}
|
|
416
432
|
|
|
417
433
|
async function processSponsorJob({
|
|
@@ -419,12 +435,12 @@ async function processSponsorJob({
|
|
|
419
435
|
sponsorAuth,
|
|
420
436
|
dutyId,
|
|
421
437
|
dutyLeaseToken,
|
|
422
|
-
persona,
|
|
423
438
|
provider,
|
|
424
439
|
claim,
|
|
425
440
|
commandServices,
|
|
426
441
|
}) {
|
|
427
442
|
const job = claim.job;
|
|
443
|
+
const persona = normalizeJobPersona(job?.persona);
|
|
428
444
|
const jobId = Number(job.id);
|
|
429
445
|
const attemptToken = String(claim.attempt?.token || "");
|
|
430
446
|
const workspaceToken = String(claim.workspaceToken?.accessToken || "");
|
|
@@ -1134,7 +1150,7 @@ async function sponsorRequest({
|
|
|
1134
1150
|
}
|
|
1135
1151
|
|
|
1136
1152
|
async function printSponsorStatus(options) {
|
|
1137
|
-
const auth = await
|
|
1153
|
+
const auth = await ensureAuth(options);
|
|
1138
1154
|
const status = await sponsorRequest({ options, auth, path: "/status" });
|
|
1139
1155
|
if (options.json) {
|
|
1140
1156
|
console.log(JSON.stringify(status, null, 2));
|
|
@@ -1152,8 +1168,12 @@ async function printSponsorStatus(options) {
|
|
|
1152
1168
|
);
|
|
1153
1169
|
}
|
|
1154
1170
|
for (const duty of status.duties || []) {
|
|
1171
|
+
const scope =
|
|
1172
|
+
duty.scope === "shared"
|
|
1173
|
+
? "shared Zero/Ciel"
|
|
1174
|
+
: `legacy assistant user ${duty.personaUserId}`;
|
|
1155
1175
|
console.log(
|
|
1156
|
-
`Duty #${duty.id}:
|
|
1176
|
+
`Duty #${duty.id}: ${scope} · ${duty.state} · ${duty.provider} · model=${duty.requestedModel || "provider default"} · effort=${duty.requestedEffort || "provider default"}`,
|
|
1157
1177
|
);
|
|
1158
1178
|
}
|
|
1159
1179
|
}
|
|
@@ -1252,12 +1272,12 @@ function normalizeProvider(value) {
|
|
|
1252
1272
|
return provider;
|
|
1253
1273
|
}
|
|
1254
1274
|
|
|
1255
|
-
function
|
|
1275
|
+
function normalizeJobPersona(value) {
|
|
1256
1276
|
const persona = String(value || "")
|
|
1257
1277
|
.trim()
|
|
1258
1278
|
.toLowerCase();
|
|
1259
1279
|
if (!PERSONAS.has(persona)) {
|
|
1260
|
-
throw new Error("
|
|
1280
|
+
throw new Error("Twinkle returned an invalid Workshop job assistant.");
|
|
1261
1281
|
}
|
|
1262
1282
|
return persona;
|
|
1263
1283
|
}
|
|
@@ -1284,8 +1304,8 @@ function sponsorUsage() {
|
|
|
1284
1304
|
" lumine sponsor status",
|
|
1285
1305
|
" lumine sponsor withdraw [--yes]",
|
|
1286
1306
|
" lumine sponsor capacity [--concurrency <n>] [--helpers <n>] [--daily-limit <n>] [--weekly-limit <n>]",
|
|
1287
|
-
" lumine sponsor duty start
|
|
1288
|
-
" lumine sponsor duty pause|resume|stop
|
|
1307
|
+
" lumine sponsor duty start --provider <codex|claude-code> [--model <name>] [--effort <level>] [--service-tier <tier>]",
|
|
1308
|
+
" lumine sponsor duty pause|resume|stop",
|
|
1289
1309
|
" lumine sponsor jobs [--limit <n>]",
|
|
1290
1310
|
].join("\n");
|
|
1291
1311
|
}
|
package/package.json
CHANGED
package/sdk/LUMINE_ADMIN.md
CHANGED
|
@@ -663,7 +663,9 @@ artifact snapshot, branch-notice evidence, and requested/resolved provider,
|
|
|
663
663
|
model, effort, service-tier, runtime, usage, and agent-tree records. It never
|
|
664
664
|
includes raw Zero/Ciel chat.
|
|
665
665
|
|
|
666
|
-
`clear` qualifies
|
|
666
|
+
`clear` qualifies a contribution to another user for its flat 50 KP award;
|
|
667
|
+
self-sponsored testing remains ineligible even when its integrity evidence is
|
|
668
|
+
cleared.
|
|
667
669
|
`disqualify` makes it ineligible. `hold` and `flag` require an evidence note and
|
|
668
670
|
remain open. The scan itself never changes sponsor status or applies a sanction.
|
|
669
671
|
Use the separate, audited `sponsor status set` command for an explicit human
|
|
@@ -881,12 +883,15 @@ feed-ID high-water mark and the server timestamp, then traverse the indexed
|
|
|
881
883
|
row moved forward when it was reshared. Explicit legacy scans retain the
|
|
882
884
|
descending primary-key walk. A page
|
|
883
885
|
can be empty while `hasMore` remains true; continue until `exhausted`. `--all`
|
|
884
|
-
does that automatically
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
886
|
+
does that automatically, fsyncs each confirmed page to a private NDJSON
|
|
887
|
+
candidate spool, and writes only bounded cursor, boundary, count, byte-length,
|
|
888
|
+
and digest metadata to the private checkpoint. `--resume` continues only when
|
|
889
|
+
the checkpoint belongs to the same API, run, and exact request and its confirmed
|
|
890
|
+
spool prefix still matches those metadata; an unconfirmed fsynced tail is
|
|
891
|
+
discarded before the next request. The final JSON collection is streamed from
|
|
892
|
+
the spool and can be copied to a separate `--output` file, while `--checkpoint`
|
|
893
|
+
remains resumable operational state. Subject `--after` is inclusive, and every
|
|
894
|
+
opaque cursor is bound to its original filters.
|
|
890
895
|
|
|
891
896
|
For `--all --json`, stdout remains exactly one JSON value. Scan-start, first-
|
|
892
897
|
page, every-tenth-page, and exhaustion progress is written to **stderr** with
|