@stage5/lumine 0.2.58 → 0.2.59
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/lib/sponsor-duty.js +62 -5
- package/package.json +1 -1
package/lib/sponsor-duty.js
CHANGED
|
@@ -234,7 +234,7 @@ async function reconcileExistingStateBeforeStart({
|
|
|
234
234
|
}
|
|
235
235
|
const preservedWorkspaces = dutyWorkspacePaths(existingState);
|
|
236
236
|
if (preservedWorkspaces.length > 0) {
|
|
237
|
-
const archivePath = await archiveSponsorState(options);
|
|
237
|
+
const archivePath = await archiveSponsorState(options, existingState);
|
|
238
238
|
console.error(
|
|
239
239
|
`lumine: preserved the expired duty record at ${archivePath}.`,
|
|
240
240
|
);
|
|
@@ -408,7 +408,7 @@ async function changeDutyState(options, action) {
|
|
|
408
408
|
const preservedWorkspaces = dutyWorkspacePaths(localState);
|
|
409
409
|
const localArchive =
|
|
410
410
|
preservedWorkspaces.length > 0
|
|
411
|
-
? await archiveSponsorState(options)
|
|
411
|
+
? await archiveSponsorState(options, localState)
|
|
412
412
|
: null;
|
|
413
413
|
if (!localArchive) await removeSponsorState(options);
|
|
414
414
|
printJsonOrLines(
|
|
@@ -472,7 +472,7 @@ async function changeDutyState(options, action) {
|
|
|
472
472
|
if (nextState === "stopped") {
|
|
473
473
|
preservedWorkspaces = dutyWorkspacePaths(localState);
|
|
474
474
|
if (preservedWorkspaces.length > 0) {
|
|
475
|
-
localArchive = await archiveSponsorState(options);
|
|
475
|
+
localArchive = await archiveSponsorState(options, localState);
|
|
476
476
|
} else {
|
|
477
477
|
await removeSponsorState(options);
|
|
478
478
|
}
|
|
@@ -1412,7 +1412,17 @@ async function sponsorLockIsStale(lockPath) {
|
|
|
1412
1412
|
}
|
|
1413
1413
|
}
|
|
1414
1414
|
|
|
1415
|
-
async function archiveSponsorState(options) {
|
|
1415
|
+
async function archiveSponsorState(options, state) {
|
|
1416
|
+
for (const jobState of Object.values(state.jobs || {})) {
|
|
1417
|
+
await scrubJobCredentials(jobState);
|
|
1418
|
+
}
|
|
1419
|
+
for (const preserved of Array.isArray(state.preservedWorkspaces)
|
|
1420
|
+
? state.preservedWorkspaces
|
|
1421
|
+
: []) {
|
|
1422
|
+
await scrubPreservedWorkspaceCredential(preserved);
|
|
1423
|
+
}
|
|
1424
|
+
state.duty = { ...state.duty, leaseToken: null };
|
|
1425
|
+
await writeSponsorState(options, state);
|
|
1416
1426
|
const filePath = sponsorDutyStatePath(options);
|
|
1417
1427
|
const archivePath = `${filePath}.stopped-${Date.now()}`;
|
|
1418
1428
|
await fs.rename(filePath, archivePath);
|
|
@@ -1422,6 +1432,7 @@ async function archiveSponsorState(options) {
|
|
|
1422
1432
|
|
|
1423
1433
|
async function removeCompletedJob({ options, state, jobId }) {
|
|
1424
1434
|
const jobState = requireJobState(state, jobId);
|
|
1435
|
+
await scrubJobCredentials(jobState);
|
|
1425
1436
|
const nextJobs = { ...(state.jobs || {}) };
|
|
1426
1437
|
delete nextJobs[String(jobId)];
|
|
1427
1438
|
state.jobs = nextJobs;
|
|
@@ -1435,6 +1446,7 @@ async function removeCompletedJob({ options, state, jobId }) {
|
|
|
1435
1446
|
|
|
1436
1447
|
async function preserveFailedJobWorkspace({ options, state, jobId, reason }) {
|
|
1437
1448
|
const jobState = requireJobState(state, jobId);
|
|
1449
|
+
await scrubJobCredentials(jobState);
|
|
1438
1450
|
const nextJobs = { ...(state.jobs || {}) };
|
|
1439
1451
|
delete nextJobs[String(jobId)];
|
|
1440
1452
|
state.jobs = nextJobs;
|
|
@@ -1449,6 +1461,7 @@ async function preserveFailedJobWorkspace({ options, state, jobId, reason }) {
|
|
|
1449
1461
|
workspaceDir: jobState.workspaceDir,
|
|
1450
1462
|
reason: reason.slice(0, 1000),
|
|
1451
1463
|
preservedAt: new Date().toISOString(),
|
|
1464
|
+
credentialsRemovedAt: jobState.credentialsRemovedAt,
|
|
1452
1465
|
},
|
|
1453
1466
|
];
|
|
1454
1467
|
await writeSponsorState(options, state);
|
|
@@ -1473,6 +1486,50 @@ function dutyWorkspacePaths(state) {
|
|
|
1473
1486
|
}
|
|
1474
1487
|
|
|
1475
1488
|
async function cleanupJobFiles(jobState) {
|
|
1489
|
+
const tempDir = resolveJobTempDir(jobState);
|
|
1490
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
async function scrubJobCredentials(jobState) {
|
|
1494
|
+
const tempDir = resolveJobTempDir(jobState);
|
|
1495
|
+
const expectedAuthFile = path.join(tempDir, "job-auth.json");
|
|
1496
|
+
const authFile = path.resolve(
|
|
1497
|
+
String(jobState?.authFile || expectedAuthFile),
|
|
1498
|
+
);
|
|
1499
|
+
if (authFile !== expectedAuthFile) {
|
|
1500
|
+
throw new Error(
|
|
1501
|
+
"Refused to remove an unrecognized Workshop credential file.",
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
await fs.unlink(authFile).catch((error) => {
|
|
1505
|
+
if (error.code !== "ENOENT") throw error;
|
|
1506
|
+
});
|
|
1507
|
+
jobState.authFile = null;
|
|
1508
|
+
jobState.workspaceToken = null;
|
|
1509
|
+
if (jobState.attempt) {
|
|
1510
|
+
jobState.attempt = { ...jobState.attempt, token: null };
|
|
1511
|
+
}
|
|
1512
|
+
jobState.credentialsRemovedAt = new Date().toISOString();
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
async function scrubPreservedWorkspaceCredential(preserved) {
|
|
1516
|
+
const workspaceDir = path.resolve(String(preserved?.workspaceDir || ""));
|
|
1517
|
+
if (path.basename(workspaceDir) !== "workspace") return;
|
|
1518
|
+
const tempDir = path.dirname(workspaceDir);
|
|
1519
|
+
try {
|
|
1520
|
+
resolveJobTempDir({ tempDir });
|
|
1521
|
+
} catch {
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
const credentialState = {
|
|
1525
|
+
tempDir,
|
|
1526
|
+
authFile: path.join(tempDir, "job-auth.json"),
|
|
1527
|
+
};
|
|
1528
|
+
await scrubJobCredentials(credentialState);
|
|
1529
|
+
preserved.credentialsRemovedAt = credentialState.credentialsRemovedAt;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
function resolveJobTempDir(jobState) {
|
|
1476
1533
|
const tempRoot = path.resolve(os.tmpdir());
|
|
1477
1534
|
const tempDir = path.resolve(String(jobState?.tempDir || ""));
|
|
1478
1535
|
if (
|
|
@@ -1482,7 +1539,7 @@ async function cleanupJobFiles(jobState) {
|
|
|
1482
1539
|
) {
|
|
1483
1540
|
throw new Error("Refused to remove an unrecognized Workshop directory.");
|
|
1484
1541
|
}
|
|
1485
|
-
|
|
1542
|
+
return tempDir;
|
|
1486
1543
|
}
|
|
1487
1544
|
|
|
1488
1545
|
export function detectSponsorAgentSession({
|