@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.
Files changed (2) hide show
  1. package/bin/matecli.mjs +139 -7
  2. 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
- const request = await readRelayNextGatewayRequest({
3335
- relayUrl,
3336
- gatewayId,
3337
- gatewayToken,
3338
- waitSeconds: DEFAULT_RELAY_WORKER_WAIT_SECONDS,
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matelink/cli",
3
- "version": "2026.4.14",
3
+ "version": "2026.4.16",
4
4
  "private": false,
5
5
  "description": "Relay-first CLI for pairing and bridging OpenClaw gateway traffic",
6
6
  "type": "module",