@remnic/plugin-openclaw 1.0.53 → 1.0.54
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/{causal-consolidation-V533DIGW.js → causal-consolidation-IAIX53NV.js} +2 -2
- package/dist/{chunk-MWLY7VQX.js → chunk-AJECKGY2.js} +1 -1
- package/dist/{chunk-QVTGUY3H.js → chunk-FDK3VJVE.js} +2 -2
- package/dist/{chunk-YXDXRE6N.js → chunk-USSDZQKJ.js} +39 -6
- package/dist/{chunk-PSAPZGDX.js → chunk-VUZEEGP5.js} +1 -1
- package/dist/{engine-7VG3IXKN.js → engine-O46ZX4EZ.js} +2 -2
- package/dist/index.js +44 -9
- package/dist/{memory-governance-TK4B4ZZ2.js → memory-governance-6BCH6SZ5.js} +2 -2
- package/dist/{storage-HUNVVHZ7.js → storage-VEGU76NN.js} +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
buildExtensionsBlockForConsolidation,
|
|
7
7
|
runPostConsolidationMaterialize
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AJECKGY2.js";
|
|
9
9
|
import "./chunk-TH5FF5SC.js";
|
|
10
10
|
import {
|
|
11
11
|
resolveCausalTrajectoryStoreDir
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
FallbackLlmClient
|
|
22
22
|
} from "./chunk-SWOYEQN2.js";
|
|
23
23
|
import "./chunk-3A5ELHTT.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-USSDZQKJ.js";
|
|
25
25
|
import "./chunk-QMUQV5NP.js";
|
|
26
26
|
import "./chunk-BQZ7JACP.js";
|
|
27
27
|
import {
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
StorageManager,
|
|
6
6
|
parseContinuityImprovementLoops,
|
|
7
7
|
sanitizeMemoryContent
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-USSDZQKJ.js";
|
|
9
9
|
import {
|
|
10
10
|
log
|
|
11
11
|
} from "./chunk-UFU5GGGA.js";
|
|
@@ -293,7 +293,7 @@ var CompoundingEngine = class {
|
|
|
293
293
|
let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
|
|
294
294
|
if (this.config.cmcConsolidationEnabled) {
|
|
295
295
|
try {
|
|
296
|
-
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-
|
|
296
|
+
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-IAIX53NV.js");
|
|
297
297
|
const causalCandidates = await deriveCausalPromotionCandidates({
|
|
298
298
|
memoryDir: this.config.memoryDir,
|
|
299
299
|
causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
createVersion
|
|
3
3
|
} from "./chunk-QMUQV5NP.js";
|
|
4
4
|
import {
|
|
5
|
+
MAGIC_HEADER_SIZE,
|
|
5
6
|
SecureStoreLockedError,
|
|
6
7
|
isEncryptedFile,
|
|
7
8
|
readMaybeEncryptedFile,
|
|
@@ -23,7 +24,8 @@ const writeFile2 = fsReadModule0.writeFile;
|
|
|
23
24
|
const mkdir2 = fsReadModule0.mkdir;
|
|
24
25
|
const unlink = fsReadModule0.unlink;
|
|
25
26
|
const appendFile = fsReadModule0.appendFile;
|
|
26
|
-
|
|
27
|
+
const open = fsReadModule0.open;
|
|
28
|
+
import { appendFileSync, createReadStream, mkdirSync, statSync } from "fs";
|
|
27
29
|
import { createHash } from "crypto";
|
|
28
30
|
import path4 from "path";
|
|
29
31
|
|
|
@@ -1474,15 +1476,15 @@ function citationTemplateLiteralParts(template) {
|
|
|
1474
1476
|
const parts = [];
|
|
1475
1477
|
let cursor = 0;
|
|
1476
1478
|
while (cursor < template.length) {
|
|
1477
|
-
const
|
|
1478
|
-
if (
|
|
1479
|
+
const open2 = template.indexOf("{", cursor);
|
|
1480
|
+
if (open2 === -1) {
|
|
1479
1481
|
parts.push(template.slice(cursor));
|
|
1480
1482
|
break;
|
|
1481
1483
|
}
|
|
1482
|
-
parts.push(template.slice(cursor,
|
|
1483
|
-
const close = template.indexOf("}",
|
|
1484
|
+
parts.push(template.slice(cursor, open2));
|
|
1485
|
+
const close = template.indexOf("}", open2 + 1);
|
|
1484
1486
|
if (close === -1) {
|
|
1485
|
-
cursor =
|
|
1487
|
+
cursor = open2 + 1;
|
|
1486
1488
|
} else {
|
|
1487
1489
|
cursor = close + 1;
|
|
1488
1490
|
}
|
|
@@ -3250,6 +3252,37 @@ var StorageManager = class _StorageManager {
|
|
|
3250
3252
|
const target = this.assertManagedStoragePath(filePath, "storage.readOfflineSyncFile");
|
|
3251
3253
|
return readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);
|
|
3252
3254
|
}
|
|
3255
|
+
async digestOfflineSyncFile(filePath) {
|
|
3256
|
+
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
3257
|
+
if (await this.offlineSyncFileIsEncrypted(target)) {
|
|
3258
|
+
const content = await readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);
|
|
3259
|
+
return {
|
|
3260
|
+
sha256: createHash("sha256").update(content).digest("hex"),
|
|
3261
|
+
bytes: content.byteLength
|
|
3262
|
+
};
|
|
3263
|
+
}
|
|
3264
|
+
const hash = createHash("sha256");
|
|
3265
|
+
let bytes = 0;
|
|
3266
|
+
for await (const rawChunk of createReadStream(target)) {
|
|
3267
|
+
const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
|
|
3268
|
+
hash.update(chunk);
|
|
3269
|
+
bytes += chunk.length;
|
|
3270
|
+
}
|
|
3271
|
+
return {
|
|
3272
|
+
sha256: hash.digest("hex"),
|
|
3273
|
+
bytes
|
|
3274
|
+
};
|
|
3275
|
+
}
|
|
3276
|
+
async offlineSyncFileIsEncrypted(filePath) {
|
|
3277
|
+
const handle = await open(filePath, "r");
|
|
3278
|
+
try {
|
|
3279
|
+
const header = Buffer.alloc(MAGIC_HEADER_SIZE);
|
|
3280
|
+
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
3281
|
+
return bytesRead >= MAGIC_HEADER_SIZE && isEncryptedFile(header);
|
|
3282
|
+
} finally {
|
|
3283
|
+
await handle.close();
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3253
3286
|
async writeOfflineSyncFile(filePath, content) {
|
|
3254
3287
|
const target = this.assertManagedStoragePath(filePath, "storage.writeOfflineSyncFile");
|
|
3255
3288
|
await writeMaybeEncryptedFile(target, content, this.resolveWriteKey(), {}, this.baseDir);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompoundingEngine,
|
|
3
3
|
defaultTierMigrationCycleBudget
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FDK3VJVE.js";
|
|
5
5
|
import "./chunk-4XDQ3KEC.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-USSDZQKJ.js";
|
|
7
7
|
import "./chunk-QMUQV5NP.js";
|
|
8
8
|
import "./chunk-BQZ7JACP.js";
|
|
9
9
|
import "./chunk-UFU5GGGA.js";
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,9 @@ import "./chunk-CEL5ZLKP.js";
|
|
|
3
3
|
import {
|
|
4
4
|
isValidCapsuleSince
|
|
5
5
|
} from "./chunk-TXOEHSVP.js";
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
validateArchiveRelativePath
|
|
8
|
+
} from "./chunk-YKV4EFUI.js";
|
|
7
9
|
import {
|
|
8
10
|
CAPSULE_ID_PATTERN
|
|
9
11
|
} from "./chunk-QCCP4RU5.js";
|
|
@@ -11,19 +13,19 @@ import "./chunk-ZS6VABML.js";
|
|
|
11
13
|
import "./chunk-QQXJODFL.js";
|
|
12
14
|
import "./chunk-BU5KJVWF.js";
|
|
13
15
|
import "./chunk-LZCGPRHS.js";
|
|
14
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-VUZEEGP5.js";
|
|
15
17
|
import "./chunk-BZ4EYURA.js";
|
|
16
18
|
import "./chunk-W6EEFUCJ.js";
|
|
17
19
|
import "./chunk-7JOLBJJ5.js";
|
|
18
20
|
import "./chunk-JC3FCKYL.js";
|
|
19
21
|
import "./chunk-YJYZMLD5.js";
|
|
20
22
|
import "./chunk-IO5WWY6A.js";
|
|
21
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-AJECKGY2.js";
|
|
22
24
|
import "./chunk-TH5FF5SC.js";
|
|
23
25
|
import "./chunk-3IKMUNW5.js";
|
|
24
26
|
import "./chunk-3G7FAF6S.js";
|
|
25
27
|
import "./chunk-25J4PXDH.js";
|
|
26
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-FDK3VJVE.js";
|
|
27
29
|
import {
|
|
28
30
|
external_exports
|
|
29
31
|
} from "./chunk-4XDQ3KEC.js";
|
|
@@ -34,7 +36,7 @@ import "./chunk-6IWEAUN6.js";
|
|
|
34
36
|
import "./chunk-SWOYEQN2.js";
|
|
35
37
|
import "./chunk-3A5ELHTT.js";
|
|
36
38
|
import "./chunk-5ZW5XJQ6.js";
|
|
37
|
-
import "./chunk-
|
|
39
|
+
import "./chunk-USSDZQKJ.js";
|
|
38
40
|
import "./chunk-QMUQV5NP.js";
|
|
39
41
|
import "./chunk-BQZ7JACP.js";
|
|
40
42
|
import "./chunk-UFU5GGGA.js";
|
|
@@ -6641,6 +6643,7 @@ import crypto2 from "crypto";
|
|
|
6641
6643
|
|
|
6642
6644
|
// ../remnic-core/src/offline-sync.ts
|
|
6643
6645
|
import { createHash as createHash13, randomUUID as randomUUID5 } from "crypto";
|
|
6646
|
+
import { createReadStream } from "fs";
|
|
6644
6647
|
import * as fsReadModule27 from "fs/promises";
|
|
6645
6648
|
const lstat6 = fsReadModule27.lstat;
|
|
6646
6649
|
const mkdir33 = fsReadModule27.mkdir;
|
|
@@ -6651,11 +6654,14 @@ const rename5 = fsReadModule27.rename;
|
|
|
6651
6654
|
const rm8 = fsReadModule27.rm;
|
|
6652
6655
|
const stat14 = fsReadModule27.stat;
|
|
6653
6656
|
const unlink9 = fsReadModule27.unlink;
|
|
6657
|
+
const utimes3 = fsReadModule27.utimes;
|
|
6654
6658
|
const writeFile31 = fsReadModule27.writeFile;
|
|
6655
6659
|
import path48 from "path";
|
|
6656
6660
|
var OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES = 64 * 1024 * 1024;
|
|
6657
6661
|
var OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
6658
6662
|
var OFFLINE_SYNC_APPLY_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
6663
|
+
var OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES = 64 * 1024 * 1024;
|
|
6664
|
+
var OFFLINE_SYNC_MAX_MTIME_MS = 864e13;
|
|
6659
6665
|
var OFFLINE_SYNC_UPLOAD_STAGING_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
6660
6666
|
|
|
6661
6667
|
// ../remnic-core/src/action-confidence.ts
|
|
@@ -6917,9 +6923,38 @@ var capsuleImportRequestSchema = external_exports.object({
|
|
|
6917
6923
|
var capsuleListRequestSchema = external_exports.object({
|
|
6918
6924
|
namespace: namespaceSchema
|
|
6919
6925
|
});
|
|
6926
|
+
function isValidOfflineSyncPath(value) {
|
|
6927
|
+
try {
|
|
6928
|
+
validateArchiveRelativePath(value, "path");
|
|
6929
|
+
return true;
|
|
6930
|
+
} catch {
|
|
6931
|
+
return false;
|
|
6932
|
+
}
|
|
6933
|
+
}
|
|
6934
|
+
var offlineSyncPathSchema = external_exports.string().trim().min(1, "path must be non-empty").max(4096).refine(
|
|
6935
|
+
isValidOfflineSyncPath,
|
|
6936
|
+
"path must be a POSIX relative path without unsafe segments"
|
|
6937
|
+
);
|
|
6938
|
+
var offlineSyncFileStateSchema = external_exports.object({
|
|
6939
|
+
path: offlineSyncPathSchema,
|
|
6940
|
+
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/i, "sha256 must be a 64-character hex digest"),
|
|
6941
|
+
bytes: external_exports.number().int().min(0),
|
|
6942
|
+
mtimeMs: external_exports.number().finite().min(0).max(OFFLINE_SYNC_MAX_MTIME_MS)
|
|
6943
|
+
});
|
|
6944
|
+
var offlineSyncBaseCapturedAtSchema = external_exports.string().trim().min(1, "baseCapturedAt must be non-empty when provided").max(64).refine((value) => Number.isFinite(Date.parse(value)), {
|
|
6945
|
+
message: "baseCapturedAt must be a valid ISO 8601 timestamp"
|
|
6946
|
+
});
|
|
6947
|
+
var offlineSyncSnapshotRequestSchema = external_exports.object({
|
|
6948
|
+
namespace: namespaceSchema,
|
|
6949
|
+
includeTranscripts: external_exports.boolean().optional(),
|
|
6950
|
+
includeContent: external_exports.boolean().optional(),
|
|
6951
|
+
baseCapturedAt: offlineSyncBaseCapturedAtSchema.optional(),
|
|
6952
|
+
baseFiles: external_exports.array(offlineSyncFileStateSchema).max(3e5, "baseFiles must contain 300000 or fewer entries").optional()
|
|
6953
|
+
});
|
|
6920
6954
|
var offlineSyncApplyRequestSchema = external_exports.object({
|
|
6921
6955
|
namespace: namespaceSchema,
|
|
6922
|
-
changeset: external_exports.unknown()
|
|
6956
|
+
changeset: external_exports.unknown(),
|
|
6957
|
+
returnCurrentFiles: external_exports.boolean().optional()
|
|
6923
6958
|
}).refine((value) => value.changeset !== void 0 && value.changeset !== null, {
|
|
6924
6959
|
message: "changeset is required",
|
|
6925
6960
|
path: ["changeset"]
|
|
@@ -6927,12 +6962,12 @@ var offlineSyncApplyRequestSchema = external_exports.object({
|
|
|
6927
6962
|
var offlineSyncFilesRequestSchema = external_exports.object({
|
|
6928
6963
|
namespace: namespaceSchema,
|
|
6929
6964
|
includeTranscripts: external_exports.boolean().optional(),
|
|
6930
|
-
paths: external_exports.array(
|
|
6965
|
+
paths: external_exports.array(offlineSyncPathSchema).max(5e3, "paths must contain 5000 or fewer entries")
|
|
6931
6966
|
});
|
|
6932
6967
|
var offlineSyncFileContentRequestSchema = external_exports.object({
|
|
6933
6968
|
namespace: namespaceSchema,
|
|
6934
6969
|
includeTranscripts: external_exports.boolean().optional(),
|
|
6935
|
-
path:
|
|
6970
|
+
path: offlineSyncPathSchema,
|
|
6936
6971
|
offset: external_exports.number().int().min(0).optional(),
|
|
6937
6972
|
length: external_exports.number().int().min(1).max(OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES).optional()
|
|
6938
6973
|
});
|
|
@@ -7465,7 +7500,7 @@ const stat19 = fsReadModule40.stat;
|
|
|
7465
7500
|
import { stat as stat21 } from "fs/promises";
|
|
7466
7501
|
|
|
7467
7502
|
// ../remnic-core/src/network/webdav.ts
|
|
7468
|
-
import { createReadStream } from "fs";
|
|
7503
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
7469
7504
|
import { mkdir as mkdir47, readdir as readdir28, realpath as realpath5, stat as stat22 } from "fs/promises";
|
|
7470
7505
|
import { createServer as createServer2 } from "http";
|
|
7471
7506
|
import { timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
readMemoryGovernanceRunArtifact,
|
|
7
7
|
restoreMemoryGovernanceRun,
|
|
8
8
|
runMemoryGovernance
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VUZEEGP5.js";
|
|
10
10
|
import "./chunk-BZ4EYURA.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-USSDZQKJ.js";
|
|
12
12
|
import "./chunk-QMUQV5NP.js";
|
|
13
13
|
import "./chunk-BQZ7JACP.js";
|
|
14
14
|
import "./chunk-UFU5GGGA.js";
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-remnic",
|
|
3
3
|
"name": "Remnic OpenClaw Plugin",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.54",
|
|
5
5
|
"kind": "memory",
|
|
6
6
|
"description": "Local semantic memory for OpenClaw with bundled Remnic core runtime. Requires plugins.slots.memory set to this plugin id for hooks to fire.",
|
|
7
7
|
"setup": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/plugin-openclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.54",
|
|
4
4
|
"description": "OpenClaw adapter for Remnic memory with bundled @remnic/core runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"openai": "^6.0.0",
|
|
74
|
-
"@remnic/core": "^1.1.
|
|
74
|
+
"@remnic/core": "^1.1.30"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"openclaw": ">=2026.4.1 || 2026.4.7-1 || 2026.4.9-beta.1 || 2026.4.11-beta.1 || 2026.4.12-beta.1 || 2026.4.14-beta.1 || 2026.4.15-beta.1 || 2026.4.15-beta.2 || 2026.4.19-beta.1 || 2026.4.19-beta.2 || 2026.4.20-beta.1 || 2026.4.20-beta.2 || 2026.4.22-beta.1 || 2026.4.23-beta.1 || 2026.4.23-beta.2 || 2026.4.23-beta.3 || 2026.4.23-beta.4 || 2026.4.23-beta.5 || 2026.4.23-beta.6 || 2026.4.24-beta.1 || 2026.4.24-beta.2 || 2026.4.24-beta.3 || 2026.4.24-beta.4 || 2026.4.24-beta.5 || 2026.4.24-beta.6 || 2026.4.25-beta.1 || 2026.4.25-beta.2 || 2026.4.25-beta.3 || 2026.4.25-beta.4 || 2026.4.25-beta.5 || 2026.4.25-beta.6 || 2026.4.25-beta.7 || 2026.4.25-beta.8 || 2026.4.25-beta.9 || 2026.4.25-beta.10 || 2026.4.25-beta.11 || 2026.4.26-beta.1 || 2026.4.27-beta.1 || 2026.4.29-beta.1 || 2026.4.29-beta.2 || 2026.4.29-beta.3 || 2026.4.29-beta.4 || 2026.4.30-beta.1 || 2026.5.2-beta.1 || 2026.5.2-beta.2 || 2026.5.2-beta.3 || 2026.5.3-1 || 2026.5.3-beta.1 || 2026.5.3-beta.2 || 2026.5.3-beta.3 || 2026.5.3-beta.4 || 2026.5.4-beta.1 || 2026.5.4-beta.2 || 2026.5.4-beta.3 || 2026.5.5-beta.1 || 2026.5.5-beta.2 || 2026.5.6-beta.1 || 2026.5.7-beta.1 || 2026.5.9-beta.1 || 2026.5.10-beta.1 || 2026.5.10-beta.2 || 2026.5.10-beta.3 || 2026.5.10-beta.4 || 2026.5.10-beta.5 || 2026.5.10-beta.6 || 2026.5.12-beta.1 || 2026.5.12-beta.2 || 2026.5.12-beta.3 || 2026.5.12-beta.4 || 2026.5.12-beta.5 || 2026.5.12-beta.6 || 2026.5.12-beta.7 || 2026.5.12-beta.8 || 2026.5.14-beta.1 || 2026.5.14-beta.2 || 2026.5.16-beta.1 || 2026.5.16-beta.2 || 2026.5.16-beta.3 || 2026.5.16-beta.4 || 2026.5.16-beta.5 || 2026.5.16-beta.6 || 2026.5.16-beta.7 || 2026.5.18-beta.1 || 2026.5.19-alpha.1 || 2026.5.19-beta.1 || 2026.5.19-beta.2 || 2026.5.20-beta.1 || 2026.5.20-beta.2 || 2026.5.21-alpha.1 || 2026.5.21-beta.1 || 2026.5.22-beta.1 || 2026.5.23-alpha.1 || 2026.5.24-alpha.1 || 2026.5.24-beta.1 || 2026.5.24-beta.2 || 2026.5.25-alpha.1 || 2026.5.25-alpha.2 || 2026.5.25-beta.1 || 2026.5.26-beta.1 || 2026.5.26-beta.2 || 2026.5.27-alpha.1 || 2026.5.27-beta.1 || 2026.5.28-alpha.1 || 2026.5.28-beta.1 || 2026.5.28-beta.2 || 2026.5.28-beta.3 || 2026.5.28-beta.4 || 2026.5.29-alpha.1 || 2026.5.30-beta.1 || 2026.5.30-beta.2 || 2026.5.31-alpha.1 || 2026.5.31-beta.1 || 2026.5.31-beta.2 || 2026.5.31-beta.3"
|