@morty-build/cli 0.3.0 → 0.4.1
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/LICENSE +202 -0
- package/NOTICE +2 -1
- package/README.md +65 -0
- package/dist/{chunk-HIGGFLQ3.js → chunk-IXGJ5G6B.js} +2 -2
- package/dist/{chunk-HIGGFLQ3.js.map → chunk-IXGJ5G6B.js.map} +2 -2
- package/dist/{chunk-SYR2NZQ5.js → chunk-ME4HCJOA.js} +3 -2
- package/dist/chunk-ME4HCJOA.js.map +7 -0
- package/dist/cli/handler/daemon/install.js +3 -3
- package/dist/cli/handler/daemon/install.js.map +1 -1
- package/dist/cli/handler/daemon/start.js +1 -1
- package/dist/cli/handler/daemon/start.js.map +1 -1
- package/dist/cli/handler/daemon/upgrade.js +1 -1
- package/dist/cli/handler/daemon/upgrade.js.map +1 -1
- package/dist/cli/handler/pair/pair.js +1 -1
- package/dist/cli/handler/pair/pair.js.map +1 -1
- package/dist/{cli-QFRCPBAC.js → cli-TTSS5YD2.js} +83 -180
- package/dist/{cli-QFRCPBAC.js.map → cli-TTSS5YD2.js.map} +3 -3
- package/dist/cli.js +2 -2
- package/dist/daemon/control/local-client.d.ts +2 -2
- package/dist/daemon/control/local-client.d.ts.map +1 -1
- package/dist/daemon/control/local-client.js +4 -7
- package/dist/daemon/control/local-client.js.map +1 -1
- package/dist/daemon/control/local-server.d.ts +1 -1
- package/dist/daemon/control/local-server.d.ts.map +1 -1
- package/dist/daemon/control/local-server.js +2 -2
- package/dist/daemon/control/local-server.js.map +1 -1
- package/dist/daemon/control/protocol.d.ts +7 -7
- package/dist/daemon/control/protocol.d.ts.map +1 -1
- package/dist/daemon/control/protocol.js +6 -13
- package/dist/daemon/control/protocol.js.map +1 -1
- package/dist/daemon/lifecycle/daemon-client.d.ts +1 -1
- package/dist/daemon/lifecycle/daemon-client.d.ts.map +1 -1
- package/dist/daemon/lifecycle/daemon-client.js +13 -13
- package/dist/daemon/lifecycle/daemon-client.js.map +1 -1
- package/dist/daemon/lifecycle/daemon.js +11 -24
- package/dist/daemon/lifecycle/daemon.js.map +1 -1
- package/dist/engine.js +2 -2
- package/dist/storage/daemon/daemon-lock.d.ts +6 -4
- package/dist/storage/daemon/daemon-lock.d.ts.map +1 -1
- package/dist/storage/daemon/daemon-lock.js +30 -140
- package/dist/storage/daemon/daemon-lock.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-SYR2NZQ5.js.map +0 -7
|
@@ -36,10 +36,10 @@ import {
|
|
|
36
36
|
validateLocalPath,
|
|
37
37
|
validatePairingId,
|
|
38
38
|
writeInstallationFile
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-IXGJ5G6B.js";
|
|
40
40
|
import {
|
|
41
41
|
package_default
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-ME4HCJOA.js";
|
|
43
43
|
|
|
44
44
|
// ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
45
45
|
var CommanderError = class extends Error {
|
|
@@ -4194,26 +4194,15 @@ var RuntimeAgentProcesses = class {
|
|
|
4194
4194
|
|
|
4195
4195
|
// src/storage/daemon/daemon-lock.ts
|
|
4196
4196
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
4197
|
-
import {
|
|
4197
|
+
import { access, rename, unlink } from "node:fs/promises";
|
|
4198
4198
|
import { join as join9 } from "node:path";
|
|
4199
4199
|
import { DatabaseSync } from "node:sqlite";
|
|
4200
|
-
import { setTimeout as delay } from "node:timers/promises";
|
|
4201
4200
|
var SQLITE_BUSY = 5;
|
|
4202
|
-
var OWNERSHIP_CONTENTION_MILLISECONDS = 2e3;
|
|
4203
|
-
async function removeLockFile(path2) {
|
|
4204
|
-
const released = `${path2}.${randomUUID4()}.released`;
|
|
4205
|
-
try {
|
|
4206
|
-
await rename(path2, released);
|
|
4207
|
-
} catch {
|
|
4208
|
-
return;
|
|
4209
|
-
}
|
|
4210
|
-
await unlink(released).catch(() => void 0);
|
|
4211
|
-
}
|
|
4212
4201
|
function holdDaemonOwnership(path2) {
|
|
4213
4202
|
const database = new DatabaseSync(path2);
|
|
4214
4203
|
try {
|
|
4215
|
-
database.exec("BEGIN
|
|
4216
|
-
database.
|
|
4204
|
+
database.exec("BEGIN IMMEDIATE");
|
|
4205
|
+
return () => database.close();
|
|
4217
4206
|
} catch (cause) {
|
|
4218
4207
|
database.close();
|
|
4219
4208
|
if (cause instanceof Error && "errcode" in cause && cause.errcode === SQLITE_BUSY) {
|
|
@@ -4221,112 +4210,46 @@ function holdDaemonOwnership(path2) {
|
|
|
4221
4210
|
}
|
|
4222
4211
|
throw cause;
|
|
4223
4212
|
}
|
|
4224
|
-
try {
|
|
4225
|
-
database.exec(
|
|
4226
|
-
"CREATE TABLE IF NOT EXISTS daemon_owner (singleton INTEGER PRIMARY KEY CHECK (singleton = 1), pid INTEGER NOT NULL)"
|
|
4227
|
-
);
|
|
4228
|
-
const previous = database.prepare("SELECT pid FROM daemon_owner").get();
|
|
4229
|
-
database.prepare("INSERT OR REPLACE INTO daemon_owner (singleton, pid) VALUES (1, ?)").run(process.pid);
|
|
4230
|
-
database.exec("COMMIT");
|
|
4231
|
-
return {
|
|
4232
|
-
previousOwner: typeof previous?.["pid"] === "number" ? previous["pid"] : null,
|
|
4233
|
-
release: () => database.close()
|
|
4234
|
-
};
|
|
4235
|
-
} catch (cause) {
|
|
4236
|
-
database.close();
|
|
4237
|
-
throw cause;
|
|
4238
|
-
}
|
|
4239
|
-
}
|
|
4240
|
-
async function takeLockFile(path2, previousOwner) {
|
|
4241
|
-
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
4242
|
-
try {
|
|
4243
|
-
await createInstallationFile(path2, `${process.pid.toString()}
|
|
4244
|
-
`);
|
|
4245
|
-
return async () => await removeLockFile(path2);
|
|
4246
|
-
} catch (cause) {
|
|
4247
|
-
if (!isNodeError(cause, "EEXIST")) {
|
|
4248
|
-
throw cause;
|
|
4249
|
-
}
|
|
4250
|
-
const encoded = await readFile5(path2, "utf8").catch(() => "");
|
|
4251
|
-
const pid = Number(encoded.trim());
|
|
4252
|
-
if (Number.isSafeInteger(pid) && pid > 1 && pid !== previousOwner) {
|
|
4253
|
-
try {
|
|
4254
|
-
process.kill(pid, 0);
|
|
4255
|
-
return null;
|
|
4256
|
-
} catch (probeCause) {
|
|
4257
|
-
if (!isNodeError(probeCause, "ESRCH")) {
|
|
4258
|
-
return null;
|
|
4259
|
-
}
|
|
4260
|
-
}
|
|
4261
|
-
}
|
|
4262
|
-
await removeLockFile(path2);
|
|
4263
|
-
}
|
|
4264
|
-
}
|
|
4265
|
-
return null;
|
|
4266
|
-
}
|
|
4267
|
-
async function contendForDaemonOwnership(stateDirectory, filename) {
|
|
4268
|
-
const path2 = join9(stateDirectory, filename);
|
|
4269
|
-
const deadline = Date.now() + OWNERSHIP_CONTENTION_MILLISECONDS;
|
|
4270
|
-
for (; ; ) {
|
|
4271
|
-
const ownership = holdDaemonOwnership(`${path2}.sqlite`);
|
|
4272
|
-
if (ownership !== null) {
|
|
4273
|
-
return ownership;
|
|
4274
|
-
}
|
|
4275
|
-
if (await daemonLockExists(stateDirectory, filename) || Date.now() >= deadline) {
|
|
4276
|
-
return null;
|
|
4277
|
-
}
|
|
4278
|
-
await delay(20 + Math.random() * 30);
|
|
4279
|
-
}
|
|
4280
4213
|
}
|
|
4281
4214
|
async function acquireDaemonLock(stateDirectory, filename = "manager.lock") {
|
|
4282
4215
|
const path2 = join9(stateDirectory, filename);
|
|
4283
|
-
const
|
|
4284
|
-
if (
|
|
4216
|
+
const release = holdDaemonOwnership(`${path2}.sqlite`);
|
|
4217
|
+
if (release === null) {
|
|
4285
4218
|
return null;
|
|
4286
4219
|
}
|
|
4287
|
-
let releaseLockFile = null;
|
|
4288
4220
|
try {
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
}
|
|
4295
|
-
if (releaseLockFile === null) {
|
|
4296
|
-
return null;
|
|
4221
|
+
await writeInstallationFile(path2, `${process.pid.toString()}
|
|
4222
|
+
`, AbortSignal.timeout(1e4));
|
|
4223
|
+
} catch (cause) {
|
|
4224
|
+
release();
|
|
4225
|
+
throw cause;
|
|
4297
4226
|
}
|
|
4298
|
-
const release = releaseLockFile;
|
|
4299
4227
|
return async () => {
|
|
4300
|
-
|
|
4301
|
-
|
|
4228
|
+
try {
|
|
4229
|
+
const detached = `${path2}.${randomUUID4()}.released`;
|
|
4230
|
+
await rename(path2, detached);
|
|
4231
|
+
await unlink(detached);
|
|
4232
|
+
} finally {
|
|
4233
|
+
release();
|
|
4234
|
+
}
|
|
4302
4235
|
};
|
|
4303
4236
|
}
|
|
4304
4237
|
async function daemonLockExists(stateDirectory, filename = "manager.lock") {
|
|
4238
|
+
const path2 = join9(stateDirectory, `${filename}.sqlite`);
|
|
4305
4239
|
try {
|
|
4306
|
-
|
|
4307
|
-
if (!Number.isSafeInteger(pid) || pid <= 1) {
|
|
4308
|
-
return true;
|
|
4309
|
-
}
|
|
4310
|
-
try {
|
|
4311
|
-
process.kill(pid, 0);
|
|
4312
|
-
} catch (cause) {
|
|
4313
|
-
if (isNodeError(cause, "ESRCH")) {
|
|
4314
|
-
return false;
|
|
4315
|
-
}
|
|
4316
|
-
if (!isNodeError(cause, "EPERM")) {
|
|
4317
|
-
throw cause;
|
|
4318
|
-
}
|
|
4319
|
-
}
|
|
4320
|
-
return true;
|
|
4240
|
+
await access(path2);
|
|
4321
4241
|
} catch (cause) {
|
|
4322
4242
|
if (isNodeError(cause, "ENOENT")) {
|
|
4323
4243
|
return false;
|
|
4324
4244
|
}
|
|
4325
|
-
if (isNodeError(cause, "EPERM")) {
|
|
4326
|
-
return true;
|
|
4327
|
-
}
|
|
4328
4245
|
throw cause;
|
|
4329
4246
|
}
|
|
4247
|
+
const release = holdDaemonOwnership(path2);
|
|
4248
|
+
if (release === null) {
|
|
4249
|
+
return true;
|
|
4250
|
+
}
|
|
4251
|
+
release();
|
|
4252
|
+
return false;
|
|
4330
4253
|
}
|
|
4331
4254
|
|
|
4332
4255
|
// src/daemon/control/local-client.ts
|
|
@@ -4335,7 +4258,7 @@ import { createConnection } from "node:net";
|
|
|
4335
4258
|
|
|
4336
4259
|
// src/storage/daemon/control-token.ts
|
|
4337
4260
|
import { randomBytes } from "node:crypto";
|
|
4338
|
-
import { readFile as
|
|
4261
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
4339
4262
|
import { join as join10 } from "node:path";
|
|
4340
4263
|
function controlTokenPath(stateDirectory) {
|
|
4341
4264
|
return join10(stateDirectory, "manager.token");
|
|
@@ -4343,7 +4266,7 @@ function controlTokenPath(stateDirectory) {
|
|
|
4343
4266
|
async function readOrCreateControlToken(stateDirectory) {
|
|
4344
4267
|
const path2 = controlTokenPath(stateDirectory);
|
|
4345
4268
|
try {
|
|
4346
|
-
return (await
|
|
4269
|
+
return (await readFile5(path2, "utf8")).trim();
|
|
4347
4270
|
} catch (cause) {
|
|
4348
4271
|
if (!isNodeError(cause, "ENOENT")) {
|
|
4349
4272
|
throw cause;
|
|
@@ -4358,7 +4281,7 @@ async function readOrCreateControlToken(stateDirectory) {
|
|
|
4358
4281
|
if (!isNodeError(cause, "EEXIST")) {
|
|
4359
4282
|
throw cause;
|
|
4360
4283
|
}
|
|
4361
|
-
return (await
|
|
4284
|
+
return (await readFile5(path2, "utf8")).trim();
|
|
4362
4285
|
}
|
|
4363
4286
|
}
|
|
4364
4287
|
|
|
@@ -4366,8 +4289,8 @@ async function readOrCreateControlToken(stateDirectory) {
|
|
|
4366
4289
|
var CONTROL_TIMEOUT_MILLISECONDS = 13e4;
|
|
4367
4290
|
var MAXIMUM_MESSAGE_BYTES = 64 * 1024;
|
|
4368
4291
|
var managerPlatform = platformSupportFor(process.platform);
|
|
4369
|
-
function controlSocketPath(stateDirectory
|
|
4370
|
-
const installationHash = createHash("sha256").update(
|
|
4292
|
+
function controlSocketPath(stateDirectory) {
|
|
4293
|
+
const installationHash = createHash("sha256").update(stateDirectory).digest("hex").slice(0, 32);
|
|
4371
4294
|
return managerPlatform.controlSocketPath(installationHash);
|
|
4372
4295
|
}
|
|
4373
4296
|
async function readSocketMessage(socket, signal) {
|
|
@@ -4416,11 +4339,11 @@ async function readSocketMessage(socket, signal) {
|
|
|
4416
4339
|
signal.addEventListener("abort", abort, { once: true });
|
|
4417
4340
|
});
|
|
4418
4341
|
}
|
|
4419
|
-
async function sendLocalRequest(stateDirectory,
|
|
4342
|
+
async function sendLocalRequest(stateDirectory, command, signal) {
|
|
4420
4343
|
const token = await readOrCreateControlToken(stateDirectory);
|
|
4421
4344
|
const deadline = AbortSignal.any([signal, AbortSignal.timeout(CONTROL_TIMEOUT_MILLISECONDS)]);
|
|
4422
4345
|
deadline.throwIfAborted();
|
|
4423
|
-
const path2 = controlSocketPath(stateDirectory
|
|
4346
|
+
const path2 = controlSocketPath(stateDirectory);
|
|
4424
4347
|
await managerPlatform.validateControlPeer(path2, deadline);
|
|
4425
4348
|
const socket = createConnection(path2);
|
|
4426
4349
|
try {
|
|
@@ -4446,11 +4369,11 @@ async function sendLocalRequest(stateDirectory, endpoint, command, signal) {
|
|
|
4446
4369
|
|
|
4447
4370
|
// src/daemon/control/local-server.ts
|
|
4448
4371
|
import { createServer } from "node:net";
|
|
4449
|
-
async function serveLocalControl(stateDirectory,
|
|
4372
|
+
async function serveLocalControl(stateDirectory, signal, handle, onListening = () => void 0, onResponse = () => void 0) {
|
|
4450
4373
|
signal.throwIfAborted();
|
|
4451
4374
|
const token = await readOrCreateControlToken(stateDirectory);
|
|
4452
4375
|
const platform = platformSupportFor(process.platform);
|
|
4453
|
-
const path2 = controlSocketPath(stateDirectory
|
|
4376
|
+
const path2 = controlSocketPath(stateDirectory);
|
|
4454
4377
|
const secured = Promise.withResolvers();
|
|
4455
4378
|
void secured.promise.catch(() => void 0);
|
|
4456
4379
|
const sockets = /* @__PURE__ */ new Set();
|
|
@@ -4592,7 +4515,7 @@ var DaemonRuntimeError = class extends Error {
|
|
|
4592
4515
|
};
|
|
4593
4516
|
async function reloadDaemon(stateDirectory, signal) {
|
|
4594
4517
|
try {
|
|
4595
|
-
const response = await sendLocalRequest(stateDirectory,
|
|
4518
|
+
const response = await sendLocalRequest(stateDirectory, { kind: "reload" }, signal);
|
|
4596
4519
|
if (typeof response !== "object" || response === null || !("kind" in response) || response.kind !== "reloaded") {
|
|
4597
4520
|
throw new Error("Saved configuration could not be applied to the running daemon");
|
|
4598
4521
|
}
|
|
@@ -4604,7 +4527,7 @@ async function reloadDaemon(stateDirectory, signal) {
|
|
|
4604
4527
|
}
|
|
4605
4528
|
async function releaseIdleAgentProcesses(stateDirectory, signal) {
|
|
4606
4529
|
try {
|
|
4607
|
-
const response = await sendLocalRequest(stateDirectory,
|
|
4530
|
+
const response = await sendLocalRequest(stateDirectory, { kind: "release" }, signal);
|
|
4608
4531
|
if (typeof response === "object" && response !== null && "kind" in response && response.kind === "released") {
|
|
4609
4532
|
return;
|
|
4610
4533
|
}
|
|
@@ -4739,8 +4662,8 @@ async function runDaemonRuntime(version, combined, shutdown, rejectionGuard) {
|
|
|
4739
4662
|
let reload = Promise.resolve();
|
|
4740
4663
|
const handle = async (request) => {
|
|
4741
4664
|
if (typeof request === "object" && request !== null && "kind" in request) {
|
|
4742
|
-
if (request.kind === "status"
|
|
4743
|
-
return { kind: "status", protocolVersion:
|
|
4665
|
+
if (request.kind === "status") {
|
|
4666
|
+
return { kind: "status", protocolVersion: 3, daemon: { pid: process.pid, version } };
|
|
4744
4667
|
}
|
|
4745
4668
|
if (request.kind === "stop") {
|
|
4746
4669
|
return { kind: "stopped" };
|
|
@@ -4751,7 +4674,7 @@ async function runDaemonRuntime(version, combined, shutdown, rejectionGuard) {
|
|
|
4751
4674
|
return { kind: "released" };
|
|
4752
4675
|
}
|
|
4753
4676
|
if (typeof request !== "object" || request === null || !("kind" in request) || request.kind !== "reload") {
|
|
4754
|
-
return { kind: "error", code: "
|
|
4677
|
+
return { kind: "error", code: "unsupported_operation", message: "Unknown local control operation" };
|
|
4755
4678
|
}
|
|
4756
4679
|
const running = new Set(active.keys());
|
|
4757
4680
|
const pending = reload.then(reconcile).then(async () => await refreshRunningCatalogs(running));
|
|
@@ -4769,32 +4692,17 @@ async function runDaemonRuntime(version, combined, shutdown, rejectionGuard) {
|
|
|
4769
4692
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4770
4693
|
})
|
|
4771
4694
|
);
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
combined,
|
|
4780
|
-
handle,
|
|
4781
|
-
() => void 0,
|
|
4782
|
-
(response) => {
|
|
4783
|
-
if (typeof response === "object" && response !== null && "kind" in response && response.kind === "stopped") {
|
|
4784
|
-
shutdown.abort();
|
|
4785
|
-
}
|
|
4786
|
-
}
|
|
4787
|
-
);
|
|
4788
|
-
} finally {
|
|
4695
|
+
await serveLocalControl(
|
|
4696
|
+
control.stateDirectory,
|
|
4697
|
+
combined,
|
|
4698
|
+
handle,
|
|
4699
|
+
() => void 0,
|
|
4700
|
+
(response) => {
|
|
4701
|
+
if (typeof response === "object" && response !== null && "kind" in response && response.kind === "stopped") {
|
|
4789
4702
|
shutdown.abort();
|
|
4790
4703
|
}
|
|
4791
|
-
})
|
|
4792
|
-
);
|
|
4793
|
-
for (const result of results) {
|
|
4794
|
-
if (result.status === "rejected") {
|
|
4795
|
-
throw result.reason;
|
|
4796
4704
|
}
|
|
4797
|
-
|
|
4705
|
+
);
|
|
4798
4706
|
if (shutdown.signal.reason instanceof DaemonRuntimeError) {
|
|
4799
4707
|
throw shutdown.signal.reason;
|
|
4800
4708
|
}
|
|
@@ -4809,28 +4717,25 @@ async function runDaemonRuntime(version, combined, shutdown, rejectionGuard) {
|
|
|
4809
4717
|
}
|
|
4810
4718
|
|
|
4811
4719
|
// src/cli/handler/daemon/install.ts
|
|
4812
|
-
import { readFile as
|
|
4720
|
+
import { readFile as readFile6, rm as rm4 } from "node:fs/promises";
|
|
4813
4721
|
import { join as join11 } from "node:path";
|
|
4814
4722
|
|
|
4815
4723
|
// src/daemon/lifecycle/daemon-client.ts
|
|
4816
4724
|
import { spawn as spawn2 } from "node:child_process";
|
|
4817
4725
|
import { once as once2 } from "node:events";
|
|
4818
|
-
import { setTimeout as
|
|
4726
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
4819
4727
|
|
|
4820
4728
|
// src/daemon/control/protocol.ts
|
|
4821
4729
|
var lifecycleResponse = external_exports.discriminatedUnion("kind", [
|
|
4822
|
-
external_exports.
|
|
4730
|
+
external_exports.strictObject({
|
|
4823
4731
|
kind: external_exports.literal("status"),
|
|
4824
|
-
protocolVersion: external_exports.literal(
|
|
4825
|
-
|
|
4732
|
+
protocolVersion: external_exports.literal(3),
|
|
4733
|
+
daemon: external_exports.strictObject({ pid: external_exports.number().int().positive(), version: external_exports.string() }).readonly()
|
|
4826
4734
|
}),
|
|
4827
|
-
external_exports.
|
|
4828
|
-
external_exports.
|
|
4735
|
+
external_exports.strictObject({ kind: external_exports.literal("stopped") }),
|
|
4736
|
+
external_exports.strictObject({ kind: external_exports.literal("error"), code: external_exports.string(), message: external_exports.string() })
|
|
4829
4737
|
]).readonly();
|
|
4830
|
-
function
|
|
4831
|
-
if (typeof value === "object" && value !== null && "kind" in value && typeof value.kind === "string" && !["status", "stopped", "error"].includes(value.kind)) {
|
|
4832
|
-
return null;
|
|
4833
|
-
}
|
|
4738
|
+
function decodeLifecycleResponse(value) {
|
|
4834
4739
|
return lifecycleResponse.parse(value);
|
|
4835
4740
|
}
|
|
4836
4741
|
|
|
@@ -4873,7 +4778,7 @@ async function waitForDaemonExit(stateDirectory, signal) {
|
|
|
4873
4778
|
}
|
|
4874
4779
|
throw deadline.reason;
|
|
4875
4780
|
}
|
|
4876
|
-
async function ensureDaemon(stateDirectory,
|
|
4781
|
+
async function ensureDaemon(stateDirectory, signal) {
|
|
4877
4782
|
const running = await readDaemonVersion(stateDirectory, signal);
|
|
4878
4783
|
if (running !== null) {
|
|
4879
4784
|
return running;
|
|
@@ -4884,11 +4789,9 @@ async function ensureDaemon(stateDirectory, _version, signal) {
|
|
|
4884
4789
|
}
|
|
4885
4790
|
async function readDaemonVersion(stateDirectory, signal) {
|
|
4886
4791
|
try {
|
|
4887
|
-
const response =
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
if (response?.kind === "status") {
|
|
4891
|
-
return response.worker?.version ?? null;
|
|
4792
|
+
const response = decodeLifecycleResponse(await sendLocalRequest(stateDirectory, { kind: "status" }, signal));
|
|
4793
|
+
if (response.kind === "status") {
|
|
4794
|
+
return response.daemon.version;
|
|
4892
4795
|
}
|
|
4893
4796
|
} catch (cause) {
|
|
4894
4797
|
if (!isNodeError(cause, "ENOENT") && !isNodeError(cause, "ECONNREFUSED")) {
|
|
@@ -4902,18 +4805,18 @@ async function waitForDaemon(stateDirectory, version, entry, signal) {
|
|
|
4902
4805
|
let child;
|
|
4903
4806
|
while (!signal.aborted) {
|
|
4904
4807
|
try {
|
|
4905
|
-
const response =
|
|
4906
|
-
await sendLocalRequest(stateDirectory,
|
|
4808
|
+
const response = decodeLifecycleResponse(
|
|
4809
|
+
await sendLocalRequest(stateDirectory, { kind: "status" }, signal)
|
|
4907
4810
|
);
|
|
4908
|
-
if (response
|
|
4811
|
+
if (response.kind === "error") {
|
|
4909
4812
|
throw new Error(response.message);
|
|
4910
4813
|
}
|
|
4911
|
-
if (response
|
|
4814
|
+
if (response.kind === "status") {
|
|
4912
4815
|
if (daemonStarted) {
|
|
4913
4816
|
process.stdout.write(`Morty daemon ${version} started
|
|
4914
4817
|
`);
|
|
4915
4818
|
}
|
|
4916
|
-
return response.
|
|
4819
|
+
return response.daemon.version;
|
|
4917
4820
|
}
|
|
4918
4821
|
throw new Error("The daemon could not return its status");
|
|
4919
4822
|
} catch (cause) {
|
|
@@ -4946,13 +4849,13 @@ async function stopDaemon(stateDirectory, signal) {
|
|
|
4946
4849
|
while (true) {
|
|
4947
4850
|
deadline.throwIfAborted();
|
|
4948
4851
|
try {
|
|
4949
|
-
const response =
|
|
4950
|
-
await sendLocalRequest(stateDirectory,
|
|
4852
|
+
const response = decodeLifecycleResponse(
|
|
4853
|
+
await sendLocalRequest(stateDirectory, { kind: "stop" }, deadline)
|
|
4951
4854
|
);
|
|
4952
|
-
if (response
|
|
4855
|
+
if (response.kind === "error") {
|
|
4953
4856
|
throw new Error(response.message);
|
|
4954
4857
|
}
|
|
4955
|
-
if (response
|
|
4858
|
+
if (response.kind !== "stopped") {
|
|
4956
4859
|
throw new Error("The Morty daemon returned an unexpected response");
|
|
4957
4860
|
}
|
|
4958
4861
|
await waitForDaemonExit(stateDirectory, deadline);
|
|
@@ -4965,7 +4868,7 @@ async function stopDaemon(stateDirectory, signal) {
|
|
|
4965
4868
|
if (!await daemonLockExists(stateDirectory)) {
|
|
4966
4869
|
return { kind: "stopped" };
|
|
4967
4870
|
}
|
|
4968
|
-
await
|
|
4871
|
+
await delay(50, void 0, { signal: deadline });
|
|
4969
4872
|
}
|
|
4970
4873
|
}
|
|
4971
4874
|
}
|
|
@@ -4998,7 +4901,7 @@ async function install(options, context) {
|
|
|
4998
4901
|
switched = true;
|
|
4999
4902
|
await recordInstallationState({ kind: "switched", previous, candidate }, signal);
|
|
5000
4903
|
if (running !== null) {
|
|
5001
|
-
const started = await ensureDaemon(control.stateDirectory,
|
|
4904
|
+
const started = await ensureDaemon(control.stateDirectory, signal);
|
|
5002
4905
|
if (started !== candidate.version) {
|
|
5003
4906
|
throw new Error("A competing startup selected another Morty version");
|
|
5004
4907
|
}
|
|
@@ -5014,13 +4917,13 @@ async function install(options, context) {
|
|
|
5014
4917
|
if (previous !== null) {
|
|
5015
4918
|
await selectRelease(previous, recovery);
|
|
5016
4919
|
if (running !== null) {
|
|
5017
|
-
await ensureDaemon(control.stateDirectory,
|
|
4920
|
+
await ensureDaemon(control.stateDirectory, recovery);
|
|
5018
4921
|
}
|
|
5019
4922
|
} else {
|
|
5020
4923
|
await rm4(join11(executableDirectory(), "current.json"), { force: true });
|
|
5021
4924
|
}
|
|
5022
4925
|
} else if (running !== null && previous !== null) {
|
|
5023
|
-
await ensureDaemon(control.stateDirectory,
|
|
4926
|
+
await ensureDaemon(control.stateDirectory, recovery);
|
|
5024
4927
|
}
|
|
5025
4928
|
await recordInstallationState({ kind: "failed", recovered: true, installed: previous }, recovery);
|
|
5026
4929
|
} catch (recoveryError) {
|
|
@@ -5067,7 +4970,7 @@ function registerInstallCommands(program2, context) {
|
|
|
5067
4970
|
process.stdout.write(`Installed: ${release?.version ?? "not installed"}
|
|
5068
4971
|
`);
|
|
5069
4972
|
try {
|
|
5070
|
-
const operation = await
|
|
4973
|
+
const operation = await readFile6(join11(executableDirectory(), "operation.json"), {
|
|
5071
4974
|
encoding: "utf8",
|
|
5072
4975
|
signal: context.shutdownSignal
|
|
5073
4976
|
});
|
|
@@ -5103,7 +5006,7 @@ function registerReleaseCommand(program2, context) {
|
|
|
5103
5006
|
function registerStartCommand(program2, context) {
|
|
5104
5007
|
program2.command("start").description("ensure the daemon is running and optionally activate a saved connection").addOption(valueOption("--connection <connection-id>", "saved Runtime connection identifier")).action(async (options) => {
|
|
5105
5008
|
const control = await openMortyControlInstallation(context.shutdownSignal, process.env);
|
|
5106
|
-
await ensureDaemon(control.stateDirectory, context.
|
|
5009
|
+
await ensureDaemon(control.stateDirectory, context.shutdownSignal);
|
|
5107
5010
|
const installation = await openMortyCliInstallation(context.shutdownSignal, process.env);
|
|
5108
5011
|
if (options.connection !== void 0) {
|
|
5109
5012
|
await installation.setConnectionActivation(options.connection, "active", context.shutdownSignal);
|
|
@@ -5118,7 +5021,7 @@ function registerUpgradeCommand(program2, context) {
|
|
|
5118
5021
|
program2.command("restart").description("restart the daemon using the installed Morty release").action(async () => {
|
|
5119
5022
|
const control = await openMortyControlInstallation(context.shutdownSignal, process.env);
|
|
5120
5023
|
await stopDaemon(control.stateDirectory, context.shutdownSignal);
|
|
5121
|
-
const version = await ensureDaemon(control.stateDirectory, context.
|
|
5024
|
+
const version = await ensureDaemon(control.stateDirectory, context.shutdownSignal);
|
|
5122
5025
|
process.stdout.write(`Morty daemon ${version} restarted.
|
|
5123
5026
|
`);
|
|
5124
5027
|
});
|
|
@@ -5143,7 +5046,7 @@ import { fork } from "node:child_process";
|
|
|
5143
5046
|
import { join as join14, resolve as resolve3 } from "node:path";
|
|
5144
5047
|
|
|
5145
5048
|
// src/storage/diagnostics/relay-probe-files.ts
|
|
5146
|
-
import { mkdir as mkdir3, readFile as
|
|
5049
|
+
import { mkdir as mkdir3, readFile as readFile7, rm as rm5, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
5147
5050
|
import { join as join12 } from "node:path";
|
|
5148
5051
|
var ProbeConfigurationFileError = class extends Error {
|
|
5149
5052
|
code = "probe_config_invalid";
|
|
@@ -5157,7 +5060,7 @@ async function readPrivateProbeConfiguration(path2, signal) {
|
|
|
5157
5060
|
);
|
|
5158
5061
|
}
|
|
5159
5062
|
try {
|
|
5160
|
-
return JSON.parse(await
|
|
5063
|
+
return JSON.parse(await readFile7(path2, { encoding: "utf8", signal }));
|
|
5161
5064
|
} catch {
|
|
5162
5065
|
signal.throwIfAborted();
|
|
5163
5066
|
throw new ProbeConfigurationFileError("The pairing configuration is not valid JSON");
|
|
@@ -5727,7 +5630,7 @@ function registerDiagnoseCommand(program2, context) {
|
|
|
5727
5630
|
import { join as join16, relative as relative3, resolve as resolve4 } from "node:path";
|
|
5728
5631
|
|
|
5729
5632
|
// src/storage/logs/log-files.ts
|
|
5730
|
-
import { lstat as lstat2, readdir as readdir4, readFile as
|
|
5633
|
+
import { lstat as lstat2, readdir as readdir4, readFile as readFile8 } from "node:fs/promises";
|
|
5731
5634
|
import { join as join15, relative as relative2 } from "node:path";
|
|
5732
5635
|
var LOG_FILE_NAME_PATTERN = /^[\w.-]{1,128}\.log$/u;
|
|
5733
5636
|
var INSTALLATIONS_DIRECTORY = "installations";
|
|
@@ -5804,7 +5707,7 @@ async function readOwnedLogFile(path2, signal) {
|
|
|
5804
5707
|
return { kind: "skipped" };
|
|
5805
5708
|
}
|
|
5806
5709
|
try {
|
|
5807
|
-
return { kind: "read", content: await
|
|
5710
|
+
return { kind: "read", content: await readFile8(path2, { encoding: "utf8", signal }) };
|
|
5808
5711
|
} catch (cause) {
|
|
5809
5712
|
if (signal.aborted) {
|
|
5810
5713
|
throw cause;
|
|
@@ -6031,7 +5934,7 @@ function registerPairAction(command, context) {
|
|
|
6031
5934
|
).addOption(valueOption("--pairing <runtime-pairing-id>", "Runtime pairing identifier")).addOption(valueOption("--workspace <directory>", "default workspace directory")).action(async (options) => {
|
|
6032
5935
|
const requested = await requirePairOptions(options, command, process.stdin, context.shutdownSignal);
|
|
6033
5936
|
const control = await openMortyControlInstallation(context.shutdownSignal, process.env);
|
|
6034
|
-
await ensureDaemon(control.stateDirectory, context.
|
|
5937
|
+
await ensureDaemon(control.stateDirectory, context.shutdownSignal);
|
|
6035
5938
|
const installation = await openMortyCliInstallation(context.shutdownSignal, process.env);
|
|
6036
5939
|
process.stdout.write(`morty version: ${context.version}
|
|
6037
5940
|
`);
|
|
@@ -6223,4 +6126,4 @@ async function runCLI() {
|
|
|
6223
6126
|
export {
|
|
6224
6127
|
runCLI
|
|
6225
6128
|
};
|
|
6226
|
-
//# sourceMappingURL=cli-
|
|
6129
|
+
//# sourceMappingURL=cli-TTSS5YD2.js.map
|