openclaw-extension-typex 1.0.15 → 1.0.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/dist/client/monitor.js +61 -34
- package/package.json +5 -4
package/dist/client/monitor.js
CHANGED
|
@@ -35,9 +35,67 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.monitorTypeXProvider = monitorTypeXProvider;
|
|
37
37
|
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const client_js_1 = require("./client.js");
|
|
40
41
|
const message_js_1 = require("./message.js");
|
|
42
|
+
const OPENCLAW_CONFIG_PATH = process.env.OPENCLAW_CONFIG_PATH ||
|
|
43
|
+
path.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
44
|
+
/** Read pos from openclaw.json: channels.openclaw-extension-typex.accounts.<accountId>.pos */
|
|
45
|
+
async function readPos(accountId) {
|
|
46
|
+
try {
|
|
47
|
+
const raw = await fs.readFile(OPENCLAW_CONFIG_PATH, "utf-8");
|
|
48
|
+
const cfg = JSON.parse(raw);
|
|
49
|
+
const pos = cfg?.channels?.["openclaw-extension-typex"]?.accounts?.[accountId]?.pos;
|
|
50
|
+
if (typeof pos === "number")
|
|
51
|
+
return pos;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// ignore — will fall through to migration
|
|
55
|
+
}
|
|
56
|
+
// Migrate from legacy state file locations (pre-openclaw.json storage).
|
|
57
|
+
// Priority (highest first):
|
|
58
|
+
// v1 (oldest): /tmp/typex/.typex_pos_<safeId>.json — flat-file format
|
|
59
|
+
// v2: /tmp/typex/<accountId>/.typex_pos.json — accountId-subdir format
|
|
60
|
+
// If v1 exists it takes precedence; v2 is only used when v1 is absent.
|
|
61
|
+
const safeId = (accountId || "default").replace(/[^a-z0-9]/gi, "_");
|
|
62
|
+
const legacyCandidates = [
|
|
63
|
+
path.join("/tmp", "typex", `.typex_pos_${safeId}.json`), // v1 (oldest)
|
|
64
|
+
path.join("/tmp", "typex", accountId, ".typex_pos.json"), // v2
|
|
65
|
+
];
|
|
66
|
+
for (const candidate of legacyCandidates) {
|
|
67
|
+
try {
|
|
68
|
+
const data = await fs.readFile(candidate, "utf-8");
|
|
69
|
+
const json = JSON.parse(data);
|
|
70
|
+
if (typeof json.pos === "number") {
|
|
71
|
+
// Persist to openclaw.json and remove legacy file.
|
|
72
|
+
await savePos(accountId, json.pos);
|
|
73
|
+
await fs.unlink(candidate).catch(() => { });
|
|
74
|
+
return json.pos;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
/* try next */
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
/** Write pos back into openclaw.json under the account config. */
|
|
84
|
+
async function savePos(accountId, pos) {
|
|
85
|
+
try {
|
|
86
|
+
const raw = await fs.readFile(OPENCLAW_CONFIG_PATH, "utf-8");
|
|
87
|
+
const cfg = JSON.parse(raw);
|
|
88
|
+
cfg.channels ??= {};
|
|
89
|
+
cfg.channels["openclaw-extension-typex"] ??= {};
|
|
90
|
+
cfg.channels["openclaw-extension-typex"].accounts ??= {};
|
|
91
|
+
cfg.channels["openclaw-extension-typex"].accounts[accountId] ??= {};
|
|
92
|
+
cfg.channels["openclaw-extension-typex"].accounts[accountId].pos = pos;
|
|
93
|
+
await fs.writeFile(OPENCLAW_CONFIG_PATH, JSON.stringify(cfg, null, 4));
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Non-fatal: losing pos means re-processing a few messages at worst.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
41
99
|
async function monitorTypeXProvider(opts) {
|
|
42
100
|
try {
|
|
43
101
|
const { account, runtime, abortSignal, log, typexCfg, cfg } = opts;
|
|
@@ -52,42 +110,12 @@ async function monitorTypeXProvider(opts) {
|
|
|
52
110
|
// Initialize Client
|
|
53
111
|
const client = (0, client_js_1.getTypeXClient)(undefined, { token, skipConfigCheck: true });
|
|
54
112
|
logger?.info(`[${accountObj.accountId}] Starting TypeX monitor for ${accountObj.accountId}...`);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
await fs.mkdir(accountDir, { recursive: true });
|
|
58
|
-
const stateFile = path.join(accountDir, ".typex_pos.json");
|
|
59
|
-
let currentPos = 0;
|
|
60
|
-
try {
|
|
61
|
-
const data = await fs.readFile(stateFile, "utf-8");
|
|
62
|
-
const json = JSON.parse(data);
|
|
63
|
-
if (typeof json.pos === "number") {
|
|
64
|
-
currentPos = json.pos;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// New-path file not found — try migrating from legacy path (pre-accountId-subdir layout).
|
|
69
|
-
try {
|
|
70
|
-
const safeId = (accountObj.accountId || "default").replace(/[^a-z0-9]/gi, "_");
|
|
71
|
-
const legacyFile = path.join(baseDir, `.typex_pos_${safeId}.json`);
|
|
72
|
-
const legacyData = await fs.readFile(legacyFile, "utf-8");
|
|
73
|
-
const legacyJson = JSON.parse(legacyData);
|
|
74
|
-
if (typeof legacyJson.pos === "number") {
|
|
75
|
-
currentPos = legacyJson.pos;
|
|
76
|
-
// Persist to new location so future starts use the correct pos.
|
|
77
|
-
await fs.writeFile(stateFile, JSON.stringify({ pos: currentPos }));
|
|
78
|
-
await fs.unlink(legacyFile).catch(() => { });
|
|
79
|
-
logger?.info(`[${accountObj.accountId}] Migrated pos (${currentPos}) from legacy state file.`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
/* No legacy file either — start from 0. */
|
|
84
|
-
}
|
|
85
|
-
}
|
|
113
|
+
let currentPos = await readPos(accountObj.accountId);
|
|
114
|
+
logger?.info(`[${accountObj.accountId}] Loaded pos: ${currentPos}`);
|
|
86
115
|
// --- Polling Loop ---
|
|
87
116
|
while (!abortSignal.aborted) {
|
|
88
117
|
try {
|
|
89
118
|
const messages = await client.fetchMessages(currentPos);
|
|
90
|
-
logger?.info(`[${accountObj.accountId}] Received ${messages?.length || 0} messages.`);
|
|
91
119
|
if (messages && messages.length > 0) {
|
|
92
120
|
for (const msg of messages) {
|
|
93
121
|
// Dispatch to OpenClaw via processTypeXMessage
|
|
@@ -101,10 +129,9 @@ async function monitorTypeXProvider(opts) {
|
|
|
101
129
|
});
|
|
102
130
|
if (typeof msg.position === "number") {
|
|
103
131
|
currentPos = msg.position;
|
|
132
|
+
await savePos(accountObj.accountId, currentPos);
|
|
104
133
|
}
|
|
105
134
|
}
|
|
106
|
-
// Save message position
|
|
107
|
-
await fs.writeFile(stateFile, JSON.stringify({ pos: currentPos }));
|
|
108
135
|
}
|
|
109
136
|
}
|
|
110
137
|
catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-extension-typex",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "TypeX channel integration for OpenClaw",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"README.md",
|
|
11
11
|
"openclaw.plugin.json"
|
|
12
12
|
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
13
17
|
"keywords": [
|
|
14
18
|
"openclaw",
|
|
15
19
|
"openclaw-extension",
|
|
@@ -35,8 +39,5 @@
|
|
|
35
39
|
"extensions": [
|
|
36
40
|
"./dist/index.js"
|
|
37
41
|
]
|
|
38
|
-
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"build": "tsc"
|
|
41
42
|
}
|
|
42
43
|
}
|