@matelink/cli 2026.4.14 → 2026.4.16
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/bin/matecli.mjs +139 -7
- package/package.json +1 -1
package/bin/matecli.mjs
CHANGED
|
@@ -20,6 +20,7 @@ const NUMERIC_CODE_LENGTH = 4;
|
|
|
20
20
|
const GROUP_SIZE = 4;
|
|
21
21
|
const DEFAULT_RELAY_WORKER_WAIT_SECONDS = 600;
|
|
22
22
|
const DEFAULT_NETWORK_TIMEOUT_MS = 600000;
|
|
23
|
+
const BRIDGE_RETRY_DELAY_MS = 2000;
|
|
23
24
|
const DEFAULT_RELAY_URL = "http://43.134.64.199:8090";
|
|
24
25
|
const DEFAULT_GATEWAY_HOST = "127.0.0.1";
|
|
25
26
|
const DEFAULT_WEBHOOK_PATH = "/testnextim/webhook";
|
|
@@ -662,11 +663,104 @@ function listWorkspaceFiles(workspaceRoot) {
|
|
|
662
663
|
return files;
|
|
663
664
|
}
|
|
664
665
|
|
|
666
|
+
const FIXED_MEMORY_FILES = new Set([
|
|
667
|
+
"AGENTS.md",
|
|
668
|
+
"HEARTBEAT.md",
|
|
669
|
+
"IDENTITY.md",
|
|
670
|
+
"MEMORY.md",
|
|
671
|
+
"SOUL.md",
|
|
672
|
+
"TOOLS.md",
|
|
673
|
+
"USER.md",
|
|
674
|
+
]);
|
|
675
|
+
|
|
676
|
+
function normalizeFixedMemoryFileName(rawName) {
|
|
677
|
+
const normalized = String(rawName ?? "").trim().toUpperCase();
|
|
678
|
+
for (const fileName of FIXED_MEMORY_FILES) {
|
|
679
|
+
if (fileName.toUpperCase() === normalized) {
|
|
680
|
+
return fileName;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
throw new Error(`unsupported memory file: ${String(rawName ?? "").trim()}`);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function listFixedMemoryFiles(workspaceRoot) {
|
|
687
|
+
return Array.from(FIXED_MEMORY_FILES)
|
|
688
|
+
.sort((a, b) => a.localeCompare(b))
|
|
689
|
+
.map((name) => {
|
|
690
|
+
const { relativePath, absolutePath } = resolveWorkspaceFilePath(workspaceRoot, name);
|
|
691
|
+
if (!fs.existsSync(absolutePath)) {
|
|
692
|
+
return buildWorkspaceFileMeta({
|
|
693
|
+
workspaceRoot,
|
|
694
|
+
relativePath,
|
|
695
|
+
absolutePath,
|
|
696
|
+
missing: true,
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
return buildWorkspaceFileMeta({
|
|
700
|
+
workspaceRoot,
|
|
701
|
+
relativePath,
|
|
702
|
+
absolutePath,
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
|
|
665
707
|
async function callWorkspaceRpcLocal({
|
|
666
708
|
method,
|
|
667
709
|
params,
|
|
668
710
|
}) {
|
|
669
711
|
const workspaceRoot = resolveConfiguredWorkspaceRoot();
|
|
712
|
+
if (method === "memory.files.list") {
|
|
713
|
+
return {
|
|
714
|
+
ok: true,
|
|
715
|
+
workspace: workspaceRoot,
|
|
716
|
+
files: listFixedMemoryFiles(workspaceRoot),
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
if (method === "memory.files.get") {
|
|
721
|
+
const fixedName = normalizeFixedMemoryFileName(params?.name);
|
|
722
|
+
const { relativePath, absolutePath } = resolveWorkspaceFilePath(workspaceRoot, fixedName);
|
|
723
|
+
if (!fs.existsSync(absolutePath)) {
|
|
724
|
+
return {
|
|
725
|
+
ok: true,
|
|
726
|
+
workspace: workspaceRoot,
|
|
727
|
+
file: buildWorkspaceFileMeta({
|
|
728
|
+
workspaceRoot,
|
|
729
|
+
relativePath,
|
|
730
|
+
absolutePath,
|
|
731
|
+
missing: true,
|
|
732
|
+
}),
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
return {
|
|
736
|
+
ok: true,
|
|
737
|
+
workspace: workspaceRoot,
|
|
738
|
+
file: buildWorkspaceFileMeta({
|
|
739
|
+
workspaceRoot,
|
|
740
|
+
relativePath,
|
|
741
|
+
absolutePath,
|
|
742
|
+
includeContent: true,
|
|
743
|
+
}),
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (method === "memory.files.set") {
|
|
748
|
+
const fixedName = normalizeFixedMemoryFileName(params?.name);
|
|
749
|
+
const { relativePath, absolutePath } = resolveWorkspaceFilePath(workspaceRoot, fixedName);
|
|
750
|
+
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
|
|
751
|
+
fs.writeFileSync(absolutePath, String(params?.content ?? ""), "utf8");
|
|
752
|
+
return {
|
|
753
|
+
ok: true,
|
|
754
|
+
workspace: workspaceRoot,
|
|
755
|
+
file: buildWorkspaceFileMeta({
|
|
756
|
+
workspaceRoot,
|
|
757
|
+
relativePath,
|
|
758
|
+
absolutePath,
|
|
759
|
+
includeContent: true,
|
|
760
|
+
}),
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
|
|
670
764
|
if (method === "agents.files.list") {
|
|
671
765
|
return {
|
|
672
766
|
ok: true,
|
|
@@ -1210,6 +1304,27 @@ async function fetchWithTimeout(url, options = {}, timeoutMs = DEFAULT_NETWORK_T
|
|
|
1210
1304
|
}
|
|
1211
1305
|
}
|
|
1212
1306
|
|
|
1307
|
+
function isTransientNetworkError(error) {
|
|
1308
|
+
const message = String(error instanceof Error ? error.message : error).toLowerCase();
|
|
1309
|
+
return (
|
|
1310
|
+
message.includes("timeout") ||
|
|
1311
|
+
message.includes("fetch failed") ||
|
|
1312
|
+
message.includes("terminated") ||
|
|
1313
|
+
message.includes("socket") ||
|
|
1314
|
+
message.includes("econnreset") ||
|
|
1315
|
+
message.includes("econnrefused") ||
|
|
1316
|
+
message.includes("ehostunreach") ||
|
|
1317
|
+
message.includes("enotfound") ||
|
|
1318
|
+
message.includes("etimedout") ||
|
|
1319
|
+
message.includes("epipe") ||
|
|
1320
|
+
message.includes("network")
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
function sleep(ms) {
|
|
1325
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1213
1328
|
function normalizeGatewayIdRaw(value) {
|
|
1214
1329
|
return String(value ?? "")
|
|
1215
1330
|
.trim()
|
|
@@ -2922,13 +3037,16 @@ async function callGatewayRpcLocal({
|
|
|
2922
3037
|
return {
|
|
2923
3038
|
ok: true,
|
|
2924
3039
|
methods: ["sessions.list", "sessions.abort", "sessions.delete", "sessions.usage", "sessions.patch",
|
|
2925
|
-
"usage.cost", "agents.files.list", "agents.files.get", "agents.files.set",
|
|
3040
|
+
"usage.cost", "memory.files.list", "memory.files.get", "memory.files.set", "agents.files.list", "agents.files.get", "agents.files.set",
|
|
2926
3041
|
"skills.status", "models.list", "chat.history", "chat.abort",
|
|
2927
3042
|
"config.get", "config.patch"],
|
|
2928
3043
|
};
|
|
2929
3044
|
}
|
|
2930
3045
|
|
|
2931
3046
|
if (
|
|
3047
|
+
method === "memory.files.list" ||
|
|
3048
|
+
method === "memory.files.get" ||
|
|
3049
|
+
method === "memory.files.set" ||
|
|
2932
3050
|
method === "agents.files.list" ||
|
|
2933
3051
|
method === "agents.files.get" ||
|
|
2934
3052
|
method === "agents.files.set"
|
|
@@ -3331,12 +3449,26 @@ async function runRelayBridge({
|
|
|
3331
3449
|
const activeRequests = new Set();
|
|
3332
3450
|
|
|
3333
3451
|
while (true) {
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3452
|
+
let request;
|
|
3453
|
+
try {
|
|
3454
|
+
request = await readRelayNextGatewayRequest({
|
|
3455
|
+
relayUrl,
|
|
3456
|
+
gatewayId,
|
|
3457
|
+
gatewayToken,
|
|
3458
|
+
waitSeconds: DEFAULT_RELAY_WORKER_WAIT_SECONDS,
|
|
3459
|
+
});
|
|
3460
|
+
} catch (error) {
|
|
3461
|
+
if (!isTransientNetworkError(error)) {
|
|
3462
|
+
throw error;
|
|
3463
|
+
}
|
|
3464
|
+
if (!json) {
|
|
3465
|
+
console.warn(
|
|
3466
|
+
`[matecli] relay poll failed: ${String(error instanceof Error ? error.message : error)}; retrying in ${Math.round(BRIDGE_RETRY_DELAY_MS / 1000)}s`,
|
|
3467
|
+
);
|
|
3468
|
+
}
|
|
3469
|
+
await sleep(BRIDGE_RETRY_DELAY_MS);
|
|
3470
|
+
continue;
|
|
3471
|
+
}
|
|
3340
3472
|
if (!request) {
|
|
3341
3473
|
continue;
|
|
3342
3474
|
}
|