@moxt-ai/mobius 0.0.316 → 0.0.317
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/agent/discovery/agent-discovery-context.d.ts +2 -0
- package/dist/agent/discovery/agent-discovery-context.d.ts.map +1 -1
- package/dist/agent/specification/vendors/pi-agent.d.ts.map +1 -1
- package/dist/agent/specification/vendors/pi-agent.js +1 -2
- package/dist/agent/specification/vendors/pi-agent.js.map +1 -1
- package/dist/cli/handler/agents/index.d.ts.map +1 -1
- package/dist/cli/handler/agents/index.js +2 -1
- package/dist/cli/handler/agents/index.js.map +1 -1
- package/dist/cli.js +77 -38
- package/dist/cli.js.map +4 -4
- package/dist/daemon/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/daemon/pairing/pair-local-machine.js +5 -1
- package/dist/daemon/pairing/pair-local-machine.js.map +1 -1
- package/dist/daemon/upgrades/data.d.ts.map +1 -1
- package/dist/daemon/upgrades/data.js +4 -1
- package/dist/daemon/upgrades/data.js.map +1 -1
- package/dist/runtime/config.d.ts +7 -1
- package/dist/runtime/config.d.ts.map +1 -1
- package/dist/runtime/config.js +9 -3
- package/dist/runtime/config.js.map +1 -1
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +2 -1
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime.js +37 -25
- package/dist/runtime.js.map +4 -4
- package/dist/storage/daemon/release-files.d.ts.map +1 -1
- package/dist/storage/daemon/release-files.js +2 -1
- package/dist/storage/daemon/release-files.js.map +1 -1
- package/dist/storage/daemon/version-data.d.ts +5 -2
- package/dist/storage/daemon/version-data.d.ts.map +1 -1
- package/dist/storage/daemon/version-data.js +30 -7
- package/dist/storage/daemon/version-data.js.map +1 -1
- package/dist/storage/installation/installation-files.d.ts.map +1 -1
- package/dist/storage/installation/installation-files.js +2 -1
- package/dist/storage/installation/installation-files.js.map +1 -1
- package/dist/storage/state-root-layout.d.ts +16 -0
- package/dist/storage/state-root-layout.d.ts.map +1 -0
- package/dist/storage/state-root-layout.js +16 -0
- package/dist/storage/state-root-layout.js.map +1 -0
- package/dist/storage/state-root.d.ts.map +1 -1
- package/dist/storage/state-root.js +5 -3
- package/dist/storage/state-root.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-files.d.ts","sourceRoot":"","sources":["../../../src/storage/daemon/release-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"release-files.d.ts","sourceRoot":"","sources":["../../../src/storage/daemon/release-files.ts"],"names":[],"mappings":"AAKA,gHAAgH;AAChH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC;AAED,4GAA4G;AAC5G,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGpF"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFile, realpath } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { readStateDirectory } from "../state-directory.js";
|
|
4
|
+
import { STATE_ROOT_LAYOUT } from "../state-root-layout.js";
|
|
4
5
|
/** npm installs each daemon release into its own prefix, so an upgrade never overwrites the running release. */
|
|
5
6
|
export function releasePrefix(version) {
|
|
6
|
-
return join(readStateDirectory(),
|
|
7
|
+
return join(readStateDirectory(), STATE_ROOT_LAYOUT.releases, version);
|
|
7
8
|
}
|
|
8
9
|
/** The canonical directory of the Mobius package npm installed into `prefix`, and its package.json text. */
|
|
9
10
|
export async function readInstalledRelease(prefix) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-files.js","sourceRoot":"","sources":["../../../src/storage/daemon/release-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"release-files.js","sourceRoot":"","sources":["../../../src/storage/daemon/release-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,gHAAgH;AAChH,MAAM,UAAU,aAAa,CAAC,OAAe;IACzC,OAAO,IAAI,CAAC,kBAAkB,EAAE,EAAE,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC3E,CAAC;AAOD,4GAA4G;AAC5G,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACrD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;AAChG,CAAC"}
|
|
@@ -4,8 +4,11 @@ export declare class DataInheritanceError extends Error {
|
|
|
4
4
|
/** The version the current data pointer names, or null when there is no pointer. */
|
|
5
5
|
export declare function readCurrentDataVersion(root: string, signal: AbortSignal): Promise<string | null>;
|
|
6
6
|
export declare function versionDataExists(root: string, version: string, signal: AbortSignal): Promise<boolean>;
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Copies one version's data into a new version's directory and returns the nested state root entries it left
|
|
9
|
+
* behind. Any other symbolic link is rejected.
|
|
10
|
+
*/
|
|
11
|
+
export declare function copyVersionData(root: string, sourceVersion: string, targetVersion: string, signal: AbortSignal): Promise<readonly string[]>;
|
|
9
12
|
/** Points the current data pointer at a version whose data directory exists. */
|
|
10
13
|
export declare function writeCurrentDataVersion(root: string, version: string, signal: AbortSignal): Promise<void>;
|
|
11
14
|
//# sourceMappingURL=version-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-data.d.ts","sourceRoot":"","sources":["../../../src/storage/daemon/version-data.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version-data.d.ts","sourceRoot":"","sources":["../../../src/storage/daemon/version-data.ts"],"names":[],"mappings":"AAWA,qBAAa,oBAAqB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,6BAA6B;CAC7C;AAED,oFAAoF;AACpF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBtG;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAU5G;AAeD;;;GAGG;AACH,wBAAsB,eAAe,CACjC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAyC5B;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/G"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { cp, lstat, mkdtemp, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
3
|
+
import { join, relative, sep } from "node:path";
|
|
4
4
|
import { runtimeUpgradeVersionSchema } from "@moxt-ai/mobius-sdk/protocol";
|
|
5
5
|
import { validateLocalPath } from "../../util/filesystem/private-path.js";
|
|
6
6
|
import { isNodeError } from "../../util/node-error.js";
|
|
7
|
+
import { STATE_ROOT_ENTRY_NAMES, STATE_ROOT_LAYOUT } from "../state-root-layout.js";
|
|
7
8
|
// Each daemon version keeps its data in `versions/<version>/` under the state root, and
|
|
8
9
|
// `current-data.txt` names the version whose data is current.
|
|
9
10
|
export class DataInheritanceError extends Error {
|
|
@@ -12,7 +13,7 @@ export class DataInheritanceError extends Error {
|
|
|
12
13
|
/** The version the current data pointer names, or null when there is no pointer. */
|
|
13
14
|
export async function readCurrentDataVersion(root, signal) {
|
|
14
15
|
// A relative, version-only pointer remains valid if the state root is moved.
|
|
15
|
-
const pointer = join(root,
|
|
16
|
+
const pointer = join(root, STATE_ROOT_LAYOUT.currentData);
|
|
16
17
|
try {
|
|
17
18
|
await validateLocalPath(pointer, false, true, signal);
|
|
18
19
|
const value = (await readFile(pointer, { encoding: "utf8", signal })).trim();
|
|
@@ -30,7 +31,7 @@ export async function readCurrentDataVersion(root, signal) {
|
|
|
30
31
|
}
|
|
31
32
|
export async function versionDataExists(root, version, signal) {
|
|
32
33
|
try {
|
|
33
|
-
await validateLocalPath(join(root,
|
|
34
|
+
await validateLocalPath(join(root, STATE_ROOT_LAYOUT.versions, version), true, true, signal);
|
|
34
35
|
return true;
|
|
35
36
|
}
|
|
36
37
|
catch (cause) {
|
|
@@ -40,9 +41,23 @@ export async function versionDataExists(root, version, signal) {
|
|
|
40
41
|
return false;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Whether a path in a version's data is a state root entry inside an installation, as `installations/<application>/
|
|
46
|
+
* <installation>/npm`. An earlier Mobius that ran with that installation as its root left it; it is not the
|
|
47
|
+
* installation's data, and its release links would otherwise block every later version from starting.
|
|
48
|
+
*/
|
|
49
|
+
function nestedRootEntry(segments) {
|
|
50
|
+
return (segments.length >= 4 &&
|
|
51
|
+
segments[0] === STATE_ROOT_LAYOUT.installations &&
|
|
52
|
+
STATE_ROOT_ENTRY_NAMES.has(segments[3] ?? ""));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Copies one version's data into a new version's directory and returns the nested state root entries it left
|
|
56
|
+
* behind. Any other symbolic link is rejected.
|
|
57
|
+
*/
|
|
44
58
|
export async function copyVersionData(root, sourceVersion, targetVersion, signal) {
|
|
45
|
-
const
|
|
59
|
+
const leftBehind = [];
|
|
60
|
+
const versions = join(root, STATE_ROOT_LAYOUT.versions);
|
|
46
61
|
const source = join(versions, sourceVersion);
|
|
47
62
|
const target = join(versions, targetVersion);
|
|
48
63
|
await validateLocalPath(root, true, true, signal);
|
|
@@ -54,6 +69,13 @@ export async function copyVersionData(root, sourceVersion, targetVersion, signal
|
|
|
54
69
|
recursive: true,
|
|
55
70
|
filter: async (path) => {
|
|
56
71
|
signal.throwIfAborted();
|
|
72
|
+
const segments = relative(source, path).split(sep);
|
|
73
|
+
if (nestedRootEntry(segments)) {
|
|
74
|
+
if (segments.length === 4) {
|
|
75
|
+
leftBehind.push(segments.join("/"));
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
57
79
|
if ((await lstat(path)).isSymbolicLink()) {
|
|
58
80
|
throw new DataInheritanceError("The inherited data contains a symbolic link");
|
|
59
81
|
}
|
|
@@ -71,6 +93,7 @@ export async function copyVersionData(root, sourceVersion, targetVersion, signal
|
|
|
71
93
|
}
|
|
72
94
|
await validateLocalPath(target, true, true, signal);
|
|
73
95
|
}
|
|
96
|
+
return leftBehind;
|
|
74
97
|
}
|
|
75
98
|
finally {
|
|
76
99
|
await rm(staging, { recursive: true, force: true });
|
|
@@ -79,12 +102,12 @@ export async function copyVersionData(root, sourceVersion, targetVersion, signal
|
|
|
79
102
|
/** Points the current data pointer at a version whose data directory exists. */
|
|
80
103
|
export async function writeCurrentDataVersion(root, version, signal) {
|
|
81
104
|
await validateLocalPath(root, true, true, signal);
|
|
82
|
-
await validateLocalPath(join(root,
|
|
105
|
+
await validateLocalPath(join(root, STATE_ROOT_LAYOUT.versions, version), true, true, signal);
|
|
83
106
|
const temporary = join(root, `.current-data-${randomUUID()}.txt`);
|
|
84
107
|
try {
|
|
85
108
|
await writeFile(temporary, `versions/${version}\n`, { mode: 0o600, flag: "wx", signal });
|
|
86
109
|
signal.throwIfAborted();
|
|
87
|
-
await rename(temporary, join(root,
|
|
110
|
+
await rename(temporary, join(root, STATE_ROOT_LAYOUT.currentData));
|
|
88
111
|
}
|
|
89
112
|
finally {
|
|
90
113
|
await rm(temporary, { force: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-data.js","sourceRoot":"","sources":["../../../src/storage/daemon/version-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"version-data.js","sourceRoot":"","sources":["../../../src/storage/daemon/version-data.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installation-files.d.ts","sourceRoot":"","sources":["../../../src/storage/installation/installation-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installation-files.d.ts","sourceRoot":"","sources":["../../../src/storage/installation/installation-files.ts"],"names":[],"mappings":"AAYA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,uBAAuB,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,oBAAoB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAElG;AAED,wBAAgB,mBAAmB,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,kBAAkB,CAAC,mBAAmB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5F;AAED,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAAC,qBAAqB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7F;AAED,MAAM,MAAM,oBAAoB,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE5C,2EAA2E;AAC3E,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgBtF;AAED,yGAAyG;AACzG,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1G;AAED,8FAA8F;AAC9F,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;AAED,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAEzF;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExE"}
|
|
@@ -2,12 +2,13 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import { mkdir, open, readdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { isNodeError } from "../../util/node-error.js";
|
|
5
|
+
import { STATE_ROOT_LAYOUT } from "../state-root-layout.js";
|
|
5
6
|
// One application's installations live in `<root>/installations/<applicationId>/`. `current.json`
|
|
6
7
|
// points at the current installation, whose directory keeps one file per saved connection in
|
|
7
8
|
// `connections/` and one index file per relay channel in `channels/`.
|
|
8
9
|
const MAXIMUM_FILE_BYTES = 16 * 1024;
|
|
9
10
|
export function applicationDirectory(root, applicationId) {
|
|
10
|
-
return join(root,
|
|
11
|
+
return join(root, STATE_ROOT_LAYOUT.installations, applicationId);
|
|
11
12
|
}
|
|
12
13
|
export function installationPointerPath(applicationDirectory) {
|
|
13
14
|
return join(applicationDirectory, "current.json");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installation-files.js","sourceRoot":"","sources":["../../../src/storage/installation/installation-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAmB,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"installation-files.js","sourceRoot":"","sources":["../../../src/storage/installation/installation-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entries a Mobius state root owns at its top level. Installation data never uses these names, so finding one
|
|
3
|
+
* inside an installation means an earlier Mobius ran with that installation as its root.
|
|
4
|
+
*/
|
|
5
|
+
export declare const STATE_ROOT_LAYOUT: Readonly<{
|
|
6
|
+
/** Names the version whose data is current. */
|
|
7
|
+
currentData: "current-data.txt";
|
|
8
|
+
/** Applications' installations: `installations/<application>/<installation>`. */
|
|
9
|
+
installations: "installations";
|
|
10
|
+
/** Managed CLI releases: `npm/<version>`. */
|
|
11
|
+
releases: "npm";
|
|
12
|
+
/** Each CLI version's data: `versions/<version>`. */
|
|
13
|
+
versions: "versions";
|
|
14
|
+
}>;
|
|
15
|
+
export declare const STATE_ROOT_ENTRY_NAMES: ReadonlySet<string>;
|
|
16
|
+
//# sourceMappingURL=state-root-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-root-layout.d.ts","sourceRoot":"","sources":["../../src/storage/state-root-layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,iBAAiB;IAC1B,+CAA+C;;IAE/C,iFAAiF;;IAEjF,6CAA6C;;IAE7C,qDAAqD;;EAEvD,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAA6C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entries a Mobius state root owns at its top level. Installation data never uses these names, so finding one
|
|
3
|
+
* inside an installation means an earlier Mobius ran with that installation as its root.
|
|
4
|
+
*/
|
|
5
|
+
export const STATE_ROOT_LAYOUT = Object.freeze({
|
|
6
|
+
/** Names the version whose data is current. */
|
|
7
|
+
currentData: "current-data.txt",
|
|
8
|
+
/** Applications' installations: `installations/<application>/<installation>`. */
|
|
9
|
+
installations: "installations",
|
|
10
|
+
/** Managed CLI releases: `npm/<version>`. */
|
|
11
|
+
releases: "npm",
|
|
12
|
+
/** Each CLI version's data: `versions/<version>`. */
|
|
13
|
+
versions: "versions",
|
|
14
|
+
});
|
|
15
|
+
export const STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
|
|
16
|
+
//# sourceMappingURL=state-root-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-root-layout.js","sourceRoot":"","sources":["../../src/storage/state-root-layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,+CAA+C;IAC/C,WAAW,EAAE,kBAAkB;IAC/B,iFAAiF;IACjF,aAAa,EAAE,eAAe;IAC9B,6CAA6C;IAC7C,QAAQ,EAAE,KAAK;IACf,qDAAqD;IACrD,QAAQ,EAAE,UAAU;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAwB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-root.d.ts","sourceRoot":"","sources":["../../src/storage/state-root.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state-root.d.ts","sourceRoot":"","sources":["../../src/storage/state-root.ts"],"names":[],"mappings":"AAMA,qHAAqH;AACrH,qBAAa,cAAe,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,qCAAqC;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,YAAY,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAOrD;CACJ;AAqCD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/F"}
|
|
@@ -2,6 +2,7 @@ import { readFile, stat } from "node:fs/promises";
|
|
|
2
2
|
import { basename, dirname, join } from "node:path";
|
|
3
3
|
import { installationPointerPath } from "./installation/installation-files.js";
|
|
4
4
|
import { readStateDirectory } from "./state-directory.js";
|
|
5
|
+
import { STATE_ROOT_LAYOUT } from "./state-root-layout.js";
|
|
5
6
|
/** The configured state directory holds another root's installation data, so Mobius must not create a root there. */
|
|
6
7
|
export class StateRootError extends Error {
|
|
7
8
|
code = "state_root_is_installation_data";
|
|
@@ -23,7 +24,7 @@ async function exists(path) {
|
|
|
23
24
|
async function owningRoot(directory) {
|
|
24
25
|
const application = dirname(directory);
|
|
25
26
|
const installations = dirname(application);
|
|
26
|
-
if (basename(installations) !==
|
|
27
|
+
if (basename(installations) !== STATE_ROOT_LAYOUT.installations) {
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
30
|
let pointer;
|
|
@@ -40,7 +41,7 @@ async function owningRoot(directory) {
|
|
|
40
41
|
return null;
|
|
41
42
|
}
|
|
42
43
|
const container = dirname(installations);
|
|
43
|
-
return basename(dirname(container)) ===
|
|
44
|
+
return basename(dirname(container)) === STATE_ROOT_LAYOUT.versions ? dirname(dirname(container)) : container;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Refuses a state directory that is another root's installation data, as an Agent launched by an earlier daemon
|
|
@@ -48,7 +49,8 @@ async function owningRoot(directory) {
|
|
|
48
49
|
*/
|
|
49
50
|
export async function validateStateRoot(environment) {
|
|
50
51
|
const directory = readStateDirectory(environment);
|
|
51
|
-
if ((await exists(join(directory,
|
|
52
|
+
if ((await exists(join(directory, STATE_ROOT_LAYOUT.currentData))) ||
|
|
53
|
+
(await exists(join(directory, STATE_ROOT_LAYOUT.versions)))) {
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
56
|
const root = await owningRoot(directory);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-root.js","sourceRoot":"","sources":["../../src/storage/state-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"state-root.js","sourceRoot":"","sources":["../../src/storage/state-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,qHAAqH;AACrH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC5B,IAAI,GAAG,iCAAiC,CAAC;IACzC,UAAU,CAAS;IAE5B,YAAY,cAAsB,EAAE,UAAkB;QAClD,KAAK,CACD,2BAA2B,cAAc,mDAAmD;YACxF,2DAA2D,UAAU,EAAE,CAC9E,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;CACJ;AAED,KAAK,UAAU,MAAM,CAAC,IAAY;IAC9B,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACxB,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACd,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,SAAiB;IACvC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,QAAQ,CAAC,aAAa,CAAC,KAAK,iBAAiB,CAAC,aAAa,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,uBAAuB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IACI,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,CAAC,CAAC,gBAAgB,IAAI,OAAO,CAAC;QAC9B,OAAO,CAAC,cAAc,KAAK,QAAQ,CAAC,SAAS,CAAC,EAChD,CAAC;QACC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAwC;IAC5E,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAClD,IACI,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9D,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC7D,CAAC;QACC,OAAO;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;AACL,CAAC"}
|