@slock-ai/computer 0.0.5 → 0.0.7
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/dist/index.js +111 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -298,6 +298,19 @@ function adoptionLogPath(slockHome) {
|
|
|
298
298
|
function channelPath(slockHome) {
|
|
299
299
|
return path.join(computerDir(slockHome), "channel");
|
|
300
300
|
}
|
|
301
|
+
function upgradeStagingDir(slockHome, version) {
|
|
302
|
+
return path.join(computerDir(slockHome), "upgrade-staging", version);
|
|
303
|
+
}
|
|
304
|
+
function upgradeSnapshotPath(slockHome) {
|
|
305
|
+
return path.join(computerDir(slockHome), "upgrade-snapshot.json");
|
|
306
|
+
}
|
|
307
|
+
function upgradeLogPath(slockHome) {
|
|
308
|
+
return path.join(computerDir(slockHome), "upgrade.log");
|
|
309
|
+
}
|
|
310
|
+
function formatUpgradeLogTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
311
|
+
const iso = date.toISOString();
|
|
312
|
+
return iso.replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
313
|
+
}
|
|
301
314
|
|
|
302
315
|
// src/output.ts
|
|
303
316
|
var CliExit = class extends Error {
|
|
@@ -1405,6 +1418,44 @@ async function runResident(serverId, deps = {}) {
|
|
|
1405
1418
|
}
|
|
1406
1419
|
var RECONCILE_INTERVAL_MS = 5e3;
|
|
1407
1420
|
var CHILD_RESTART_BACKOFF_MS = 2e3;
|
|
1421
|
+
var START_ENSURE_TIMEOUT_MS = 15e3;
|
|
1422
|
+
var START_ENSURE_POLL_INTERVAL_MS = 100;
|
|
1423
|
+
async function waitForManagedDaemonPids(slockHome, serverIds, deps) {
|
|
1424
|
+
const readPidfile = deps.readPidfile ?? readPidfileAt;
|
|
1425
|
+
const isAlive = deps.isProcessAlive ?? isProcessAlive2;
|
|
1426
|
+
const sleep2 = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1427
|
+
const timeoutMs = deps.ensureTimeoutMs ?? START_ENSURE_TIMEOUT_MS;
|
|
1428
|
+
const pollIntervalMs = deps.ensurePollIntervalMs ?? START_ENSURE_POLL_INTERVAL_MS;
|
|
1429
|
+
const deadline = Date.now() + timeoutMs;
|
|
1430
|
+
const ready = /* @__PURE__ */ new Map();
|
|
1431
|
+
while (ready.size < serverIds.length) {
|
|
1432
|
+
for (const serverId of serverIds) {
|
|
1433
|
+
if (ready.has(serverId)) continue;
|
|
1434
|
+
const pid = await readPidfile(serverDaemonPidPath(slockHome, serverId));
|
|
1435
|
+
if (pid && isAlive(pid)) ready.set(serverId, pid);
|
|
1436
|
+
}
|
|
1437
|
+
if (ready.size === serverIds.length) return ready;
|
|
1438
|
+
const remaining = deadline - Date.now();
|
|
1439
|
+
if (remaining <= 0) return ready;
|
|
1440
|
+
await sleep2(Math.min(pollIntervalMs, remaining));
|
|
1441
|
+
}
|
|
1442
|
+
return ready;
|
|
1443
|
+
}
|
|
1444
|
+
function formatReadySummary(ready, serverIds, opts) {
|
|
1445
|
+
if (opts.serverId && serverIds.length === 1) {
|
|
1446
|
+
const pid = ready.get(opts.serverId);
|
|
1447
|
+
return `Daemon for server ${opts.serverLabel ?? opts.serverId} is running${pid ? ` (pid ${pid})` : ""}.`;
|
|
1448
|
+
}
|
|
1449
|
+
return `Daemons for ${serverIds.length} managed server(s) are running.`;
|
|
1450
|
+
}
|
|
1451
|
+
function failStartEnsureTimeout(slockHome, serverIds, ready, opts) {
|
|
1452
|
+
const missing = serverIds.filter((id) => !ready.has(id));
|
|
1453
|
+
const target = opts.serverId && missing.length === 1 ? `${opts.serverLabel ?? opts.serverId}` : `${missing.length} daemon(s): ${missing.join(", ")}`;
|
|
1454
|
+
fail(
|
|
1455
|
+
"START_DAEMON_TIMEOUT",
|
|
1456
|
+
`Timed out waiting for ${target} to start. Run \`slock-computer status\` and inspect ${supervisorLogPath(slockHome)} plus per-server daemon logs under ~/.slock/computer/servers/<serverId>/daemon.log.`
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1408
1459
|
async function runSupervisorStartupRecovery(slockHome) {
|
|
1409
1460
|
const parentHoldsLock = process.env[PARENT_LOCK_HELD_ENV_VAR] === "1";
|
|
1410
1461
|
try {
|
|
@@ -1586,7 +1637,7 @@ async function runSupervise() {
|
|
|
1586
1637
|
await new Promise(() => {
|
|
1587
1638
|
});
|
|
1588
1639
|
}
|
|
1589
|
-
async function runStart(opts = {},
|
|
1640
|
+
async function runStart(opts = {}, deps = {}) {
|
|
1590
1641
|
const slockHome = resolveSlockHome();
|
|
1591
1642
|
const attached = await listAttachedServerIds(slockHome);
|
|
1592
1643
|
if (attached.length === 0) {
|
|
@@ -1608,9 +1659,11 @@ async function runStart(opts = {}, _deps = {}) {
|
|
|
1608
1659
|
const existing = await readPidfileAt(supervisorPidPath(slockHome));
|
|
1609
1660
|
if (existing && isProcessAlive2(existing)) {
|
|
1610
1661
|
info(`Supervisor already running (pid ${existing}).`);
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1662
|
+
const ready2 = await waitForManagedDaemonPids(slockHome, managedTargets, deps);
|
|
1663
|
+
if (ready2.size !== managedTargets.length) {
|
|
1664
|
+
failStartEnsureTimeout(slockHome, managedTargets, ready2, opts);
|
|
1665
|
+
}
|
|
1666
|
+
info(formatReadySummary(ready2, managedTargets, opts));
|
|
1614
1667
|
return;
|
|
1615
1668
|
}
|
|
1616
1669
|
if (opts.foreground) {
|
|
@@ -1622,12 +1675,17 @@ async function runStart(opts = {}, _deps = {}) {
|
|
|
1622
1675
|
}
|
|
1623
1676
|
let pid;
|
|
1624
1677
|
try {
|
|
1625
|
-
pid = await spawnDetachedSupervisor(slockHome);
|
|
1678
|
+
pid = await (deps.spawnDetachedSupervisor ?? spawnDetachedSupervisor)(slockHome);
|
|
1626
1679
|
} catch (err) {
|
|
1627
1680
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1628
1681
|
fail("SUPERVISOR_SPAWN_FAILED", msg);
|
|
1629
1682
|
}
|
|
1630
1683
|
info(`Supervisor started (pid ${pid}); keeps running after this terminal closes.`);
|
|
1684
|
+
const ready = await waitForManagedDaemonPids(slockHome, managedTargets, deps);
|
|
1685
|
+
if (ready.size !== managedTargets.length) {
|
|
1686
|
+
failStartEnsureTimeout(slockHome, managedTargets, ready, opts);
|
|
1687
|
+
}
|
|
1688
|
+
info(formatReadySummary(ready, managedTargets, opts));
|
|
1631
1689
|
info(
|
|
1632
1690
|
`Managing ${managedTargets.length} of ${attached.length} attached server(s). Logs: ${supervisorLogPath(slockHome)}`
|
|
1633
1691
|
);
|
|
@@ -2642,9 +2700,6 @@ function satisfiesTilde(ver, base) {
|
|
|
2642
2700
|
}
|
|
2643
2701
|
|
|
2644
2702
|
// src/upgrade.ts
|
|
2645
|
-
function upgradeStagingDir(slockHome, version) {
|
|
2646
|
-
return join6(computerDir(slockHome), "upgrade-staging", version);
|
|
2647
|
-
}
|
|
2648
2703
|
async function stagePhase(slockHome, version, deps = {}) {
|
|
2649
2704
|
const npmPack = deps.npmPack ?? defaultNpmPack;
|
|
2650
2705
|
const fsReadFile = deps.fsReadFile ?? readFile11;
|
|
@@ -2754,9 +2809,6 @@ async function cleanupStaged(slockHome, version) {
|
|
|
2754
2809
|
} catch {
|
|
2755
2810
|
}
|
|
2756
2811
|
}
|
|
2757
|
-
function upgradeSnapshotPath(slockHome) {
|
|
2758
|
-
return join6(computerDir(slockHome), "upgrade-snapshot.json");
|
|
2759
|
-
}
|
|
2760
2812
|
async function snapshotPhase(slockHome, snap) {
|
|
2761
2813
|
const path2 = upgradeSnapshotPath(slockHome);
|
|
2762
2814
|
const tmp = `${path2}.tmp`;
|
|
@@ -3298,6 +3350,26 @@ async function locateStagedTarball(stagedPath) {
|
|
|
3298
3350
|
return join6(stagedPath, tgz);
|
|
3299
3351
|
}
|
|
3300
3352
|
|
|
3353
|
+
// src/upgradeLog.ts
|
|
3354
|
+
import { chmod as chmod5, mkdir as mkdir12, open as open2 } from "fs/promises";
|
|
3355
|
+
var FILE_MODE = 384;
|
|
3356
|
+
async function appendUpgradeLogEntry(slockHome, entry) {
|
|
3357
|
+
await mkdir12(computerDir(slockHome), { recursive: true });
|
|
3358
|
+
const path2 = upgradeLogPath(slockHome);
|
|
3359
|
+
const at = entry.at ?? formatUpgradeLogTimestamp();
|
|
3360
|
+
const fullEntry = { ...entry, at };
|
|
3361
|
+
const line = JSON.stringify(fullEntry) + "\n";
|
|
3362
|
+
const handle = await open2(path2, "a", FILE_MODE);
|
|
3363
|
+
try {
|
|
3364
|
+
await handle.write(line);
|
|
3365
|
+
} finally {
|
|
3366
|
+
await handle.close();
|
|
3367
|
+
}
|
|
3368
|
+
if (process.platform !== "win32") {
|
|
3369
|
+
await chmod5(path2, FILE_MODE);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3301
3373
|
// src/upgradeCli.ts
|
|
3302
3374
|
async function defaultSpawnFreshSupervisor(slockHome) {
|
|
3303
3375
|
await spawnDetachedSupervisor(slockHome);
|
|
@@ -3400,14 +3472,35 @@ async function runUpgradeCli(slockHome, opts, deps = {}) {
|
|
|
3400
3472
|
spawnFreshSupervisor: () => spawnFreshSupervisor(slockHome)
|
|
3401
3473
|
}
|
|
3402
3474
|
});
|
|
3475
|
+
const bundle = (version) => ({
|
|
3476
|
+
computerVersion: version
|
|
3477
|
+
});
|
|
3478
|
+
const logTrigger = opts.trigger ?? "cli";
|
|
3403
3479
|
if (outcome.ok) {
|
|
3404
3480
|
info(
|
|
3405
3481
|
`Upgrade ${fromVersion} \u2192 ${targetVersion} succeeded (health-OK in ${outcome.restart?.healthAfterMs ?? 0}ms).`
|
|
3406
3482
|
);
|
|
3483
|
+
await appendUpgradeLogEntry(slockHome, {
|
|
3484
|
+
fromBundle: bundle(fromVersion),
|
|
3485
|
+
toBundle: bundle(targetVersion),
|
|
3486
|
+
channel: channel2,
|
|
3487
|
+
trigger: logTrigger,
|
|
3488
|
+
outcome: "ok"
|
|
3489
|
+
}).catch(() => {
|
|
3490
|
+
});
|
|
3407
3491
|
return;
|
|
3408
3492
|
}
|
|
3409
3493
|
const code = mapFailurePhaseToCode(outcome);
|
|
3410
3494
|
const rolledBack = outcome.rolledBack === true ? " (swap rolled back)" : "";
|
|
3495
|
+
await appendUpgradeLogEntry(slockHome, {
|
|
3496
|
+
fromBundle: bundle(fromVersion),
|
|
3497
|
+
toBundle: bundle(targetVersion),
|
|
3498
|
+
channel: channel2,
|
|
3499
|
+
trigger: logTrigger,
|
|
3500
|
+
outcome: "err",
|
|
3501
|
+
errorCode: code
|
|
3502
|
+
}).catch(() => {
|
|
3503
|
+
});
|
|
3411
3504
|
fail(
|
|
3412
3505
|
code,
|
|
3413
3506
|
`Upgrade failed at phase=${outcome.phase}: ${outcome.reason ?? "unknown"}${rolledBack}.`
|
|
@@ -3473,7 +3566,7 @@ async function defaultCurrentVersion() {
|
|
|
3473
3566
|
}
|
|
3474
3567
|
|
|
3475
3568
|
// src/upgradeTestHarness.ts
|
|
3476
|
-
import { mkdir as
|
|
3569
|
+
import { mkdir as mkdir13, readdir as readdir4, stat as stat3, writeFile as writeFile10 } from "fs/promises";
|
|
3477
3570
|
import { join as join8 } from "path";
|
|
3478
3571
|
import { createHash as createHash4 } from "crypto";
|
|
3479
3572
|
var PHASES = /* @__PURE__ */ new Set([
|
|
@@ -3544,7 +3637,7 @@ function buildSimulatedDeps(slockHome, opts) {
|
|
|
3544
3637
|
if (opts.simulateFail === "extract") {
|
|
3545
3638
|
return { exitCode: 1, stderr: "simulated extract failure" };
|
|
3546
3639
|
}
|
|
3547
|
-
await
|
|
3640
|
+
await mkdir13(join8(destDir, "package"), { recursive: true });
|
|
3548
3641
|
await writeFile10(join8(destDir, "package", "marker.txt"), `NEW@${targetVersion}`);
|
|
3549
3642
|
return { exitCode: 0, stderr: "" };
|
|
3550
3643
|
},
|
|
@@ -3605,7 +3698,7 @@ function buildSimulatedDeps(slockHome, opts) {
|
|
|
3605
3698
|
}
|
|
3606
3699
|
async function arrangeSnapshotFailure(slockHome) {
|
|
3607
3700
|
const snapshotPath = join8(slockHome, "computer", "upgrade-snapshot.json");
|
|
3608
|
-
await
|
|
3701
|
+
await mkdir13(snapshotPath, { recursive: true });
|
|
3609
3702
|
}
|
|
3610
3703
|
async function pathInfo(path2) {
|
|
3611
3704
|
try {
|
|
@@ -3660,12 +3753,12 @@ async function runUpgradeTestHarness(slockHome, opts, writer = (s) => process.st
|
|
|
3660
3753
|
process.exitCode = 1;
|
|
3661
3754
|
return;
|
|
3662
3755
|
}
|
|
3663
|
-
await
|
|
3756
|
+
await mkdir13(slockHome, { recursive: true });
|
|
3664
3757
|
if (opts.simulateFail === "snapshot") {
|
|
3665
3758
|
await arrangeSnapshotFailure(slockHome);
|
|
3666
3759
|
}
|
|
3667
3760
|
const { opts: upgradeOpts } = buildSimulatedDeps(slockHome, opts);
|
|
3668
|
-
await
|
|
3761
|
+
await mkdir13(upgradeOpts.currentBinaryDir, { recursive: true });
|
|
3669
3762
|
let outcome;
|
|
3670
3763
|
try {
|
|
3671
3764
|
outcome = await runUpgrade(slockHome, upgradeOpts);
|
|
@@ -3702,7 +3795,7 @@ async function runUpgradeTestHarness(slockHome, opts, writer = (s) => process.st
|
|
|
3702
3795
|
}
|
|
3703
3796
|
|
|
3704
3797
|
// src/upgradeInstallSmoke.ts
|
|
3705
|
-
import { copyFile, mkdir as
|
|
3798
|
+
import { copyFile, mkdir as mkdir14, readFile as readFile13 } from "fs/promises";
|
|
3706
3799
|
import { createHash as createHash5 } from "crypto";
|
|
3707
3800
|
import { dirname as dirname11, isAbsolute, join as join9, resolve as pathResolve } from "path";
|
|
3708
3801
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -3725,7 +3818,7 @@ async function runUpgradeInstallSmoke(slockHome, opts, deps = {}) {
|
|
|
3725
3818
|
const spawnFreshSupervisor = deps.spawnFreshSupervisor ?? (async (h) => {
|
|
3726
3819
|
await spawnDetachedSupervisor(h);
|
|
3727
3820
|
});
|
|
3728
|
-
await
|
|
3821
|
+
await mkdir14(slockHome, { recursive: true });
|
|
3729
3822
|
const outcome = await runUpgrade(slockHome, {
|
|
3730
3823
|
targetVersion: opts.targetVersion,
|
|
3731
3824
|
fromVersion,
|
package/package.json
CHANGED