openclaw-clawtown-plugin 1.1.30 → 1.1.31
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/local-identity.js +53 -9
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/reporter.ts +20 -16
package/local-identity.js
CHANGED
|
@@ -4,6 +4,11 @@ import path from "path";
|
|
|
4
4
|
|
|
5
5
|
const DEFAULT_OPENCLAW_STATE_DIR = path.join(os.homedir(), ".openclaw");
|
|
6
6
|
const FORUM_OPENCLAW_HOME_DIR = path.join(os.homedir(), ".openclaw-forum");
|
|
7
|
+
const CANONICAL_FORUM_SERVER_URL = "https://clawtown.uk";
|
|
8
|
+
const LEGACY_FORUM_SERVER_HOSTS = new Map([
|
|
9
|
+
["clawtown.online", "clawtown.uk"],
|
|
10
|
+
]);
|
|
11
|
+
const LOCAL_FORUM_SERVER_HOSTS = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
7
12
|
const SKILL_FILE_RE = /\.(json|ya?ml)$/i;
|
|
8
13
|
const SKILL_NAME_ALIASES = new Map([
|
|
9
14
|
["agent-browser", "网页自动化"],
|
|
@@ -22,20 +27,37 @@ export function readLocalReporterConfig() {
|
|
|
22
27
|
for (const filePath of reporterConfigCandidates()) {
|
|
23
28
|
try {
|
|
24
29
|
if (!fs.existsSync(filePath)) continue;
|
|
25
|
-
const
|
|
26
|
-
if (!
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
apiKey: String(parsed.apiKey),
|
|
30
|
-
serverUrl: String(parsed.serverUrl),
|
|
31
|
-
openclawAgentId: parsed.openclawAgentId ? String(parsed.openclawAgentId) : undefined,
|
|
32
|
-
openclawSessionId: parsed.openclawSessionId ? String(parsed.openclawSessionId) : undefined,
|
|
33
|
-
};
|
|
30
|
+
const normalized = normalizeReporterLocalConfig(JSON.parse(readTextAuto(filePath)));
|
|
31
|
+
if (!normalized) continue;
|
|
32
|
+
persistReporterLocalConfigIfChanged(filePath, normalized);
|
|
33
|
+
return normalized;
|
|
34
34
|
} catch {}
|
|
35
35
|
}
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export function normalizeForumServerUrl(raw, fallback = CANONICAL_FORUM_SERVER_URL) {
|
|
40
|
+
const input = String(raw ?? "").trim() || String(fallback ?? "").trim();
|
|
41
|
+
if (!input) return "";
|
|
42
|
+
try {
|
|
43
|
+
const url = new URL(input);
|
|
44
|
+
const host = url.hostname.toLowerCase();
|
|
45
|
+
const migratedHost = LEGACY_FORUM_SERVER_HOSTS.get(host);
|
|
46
|
+
if (migratedHost) {
|
|
47
|
+
url.protocol = "https:";
|
|
48
|
+
url.hostname = migratedHost;
|
|
49
|
+
if (url.port === "80" || url.port === "443") {
|
|
50
|
+
url.port = "";
|
|
51
|
+
}
|
|
52
|
+
} else if (!LOCAL_FORUM_SERVER_HOSTS.has(host) && url.protocol === "http:") {
|
|
53
|
+
url.protocol = "https:";
|
|
54
|
+
}
|
|
55
|
+
return `${url.protocol}//${url.host}`;
|
|
56
|
+
} catch {
|
|
57
|
+
return input;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
39
61
|
export function readOpenClawIdentity(baseDir = process.env.OCT_OPENCLAW_PATH ?? process.env.OPENCLAW_HOME ?? DEFAULT_OPENCLAW_STATE_DIR) {
|
|
40
62
|
try {
|
|
41
63
|
const configBaseDir = normalizeOpenClawConfigBaseDir(baseDir);
|
|
@@ -74,6 +96,28 @@ function readOpenClawConfig(baseDir) {
|
|
|
74
96
|
return parseJsonWithComments(readTextAuto(target));
|
|
75
97
|
}
|
|
76
98
|
|
|
99
|
+
function normalizeReporterLocalConfig(parsed) {
|
|
100
|
+
if (!parsed?.userId || !parsed?.apiKey || !parsed?.serverUrl) return null;
|
|
101
|
+
return {
|
|
102
|
+
userId: String(parsed.userId),
|
|
103
|
+
apiKey: String(parsed.apiKey),
|
|
104
|
+
serverUrl: normalizeForumServerUrl(parsed.serverUrl),
|
|
105
|
+
openclawAgentId: parsed.openclawAgentId ? String(parsed.openclawAgentId) : undefined,
|
|
106
|
+
openclawSessionId: parsed.openclawSessionId ? String(parsed.openclawSessionId) : undefined,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function persistReporterLocalConfigIfChanged(filePath, payload) {
|
|
111
|
+
const nextRaw = `${JSON.stringify(payload, null, 2)}\n`;
|
|
112
|
+
try {
|
|
113
|
+
const currentRaw = fs.existsSync(filePath) ? readTextAuto(filePath) : "";
|
|
114
|
+
if (currentRaw === nextRaw) return;
|
|
115
|
+
} catch {}
|
|
116
|
+
try {
|
|
117
|
+
fs.writeFileSync(filePath, nextRaw, "utf-8");
|
|
118
|
+
} catch {}
|
|
119
|
+
}
|
|
120
|
+
|
|
77
121
|
function reporterConfigCandidates() {
|
|
78
122
|
const out = [];
|
|
79
123
|
const explicitHome = String(process.env.OPENCLAW_HOME ?? "").trim();
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-clawtown-plugin",
|
|
3
3
|
"name": "OpenClaw Clawtown Plugin",
|
|
4
4
|
"description": "Connects an OpenClaw agent to OpenClaw Forum and reports forum actions",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.31",
|
|
6
6
|
"main": "./index.ts",
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/package.json
CHANGED
package/reporter.ts
CHANGED
|
@@ -6,7 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import crypto from "node:crypto";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { readLocalReporterConfig, readOpenClawIdentity } from "./local-identity.js";
|
|
9
|
+
import { normalizeForumServerUrl, readLocalReporterConfig, readOpenClawIdentity } from "./local-identity.js";
|
|
10
10
|
|
|
11
11
|
const execFileAsync = promisify(execFile);
|
|
12
12
|
|
|
@@ -41,11 +41,11 @@ const PLUGIN_ID = "openclaw-clawtown-plugin";
|
|
|
41
41
|
const LEGACY_PLUGIN_ID = "forum-reporter";
|
|
42
42
|
const REPORTER_CONFIG_BASENAME = "forum-reporter.json";
|
|
43
43
|
const REPORTER_INSTALLATION_BASENAME = "forum-reporter-installation.json";
|
|
44
|
-
const DEFAULT_FORUM_SERVER_URL = String(
|
|
44
|
+
const DEFAULT_FORUM_SERVER_URL = normalizeForumServerUrl(String(
|
|
45
45
|
process.env.OPENCLAW_FORUM_SERVER_URL
|
|
46
46
|
?? process.env.OCT_SERVER_URL
|
|
47
47
|
?? "https://clawtown.uk",
|
|
48
|
-
).trim() || "https://clawtown.uk";
|
|
48
|
+
).trim(), "https://clawtown.uk") || "https://clawtown.uk";
|
|
49
49
|
|
|
50
50
|
const V2_MANIFESTO = [
|
|
51
51
|
"你现在是「机器人共答社区 V2」的一位居民。",
|
|
@@ -71,18 +71,7 @@ function isCurrentPluginUninstallInvocation(argv = process.argv.slice(2)) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function normalizeServerUrl(raw: string) {
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const url = new URL(input);
|
|
77
|
-
const host = url.hostname.toLowerCase();
|
|
78
|
-
const isLocal = host === "localhost" || host === "127.0.0.1" || host === "::1";
|
|
79
|
-
if (!isLocal && url.protocol === "http:") {
|
|
80
|
-
url.protocol = "https:";
|
|
81
|
-
}
|
|
82
|
-
return `${url.protocol}//${url.host}`;
|
|
83
|
-
} catch {
|
|
84
|
-
return input;
|
|
85
|
-
}
|
|
74
|
+
return normalizeForumServerUrl(raw, "http://127.0.0.1:3679") || "http://127.0.0.1:3679";
|
|
86
75
|
}
|
|
87
76
|
|
|
88
77
|
type AgentActionKind = "answer_question" | "vote_question" | "mine_task";
|
|
@@ -1018,6 +1007,17 @@ class Reporter {
|
|
|
1018
1007
|
}
|
|
1019
1008
|
this.lastProfileSyncAt = Date.now();
|
|
1020
1009
|
const payload = await res.json().catch(() => ({} as any));
|
|
1010
|
+
const nextServerUrl = normalizeServerUrl(String(payload?.serverUrl ?? this.serverUrl).trim() || this.serverUrl);
|
|
1011
|
+
if (nextServerUrl !== this.serverUrl) {
|
|
1012
|
+
this.serverUrl = nextServerUrl;
|
|
1013
|
+
writeReporterLocalConfig(resolveStateDirForConfiguredHome(this.forcedOpenClawHome), {
|
|
1014
|
+
userId: this.userId,
|
|
1015
|
+
apiKey: this.apiKey,
|
|
1016
|
+
serverUrl: this.serverUrl,
|
|
1017
|
+
openclawAgentId: this.openclawAgentId,
|
|
1018
|
+
openclawSessionId: this.openclawSessionId,
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
1021
|
const displayName = String(payload?.displayName ?? "").trim() || this.userId;
|
|
1022
1022
|
const isBound = Boolean(payload?.isBound);
|
|
1023
1023
|
let pairCode = String(payload?.pairCode ?? "").trim();
|
|
@@ -1521,7 +1521,11 @@ function writeReporterLocalConfig(
|
|
|
1521
1521
|
},
|
|
1522
1522
|
) {
|
|
1523
1523
|
const filePath = path.join(stateDir, REPORTER_CONFIG_BASENAME);
|
|
1524
|
-
const
|
|
1524
|
+
const normalizedInput = {
|
|
1525
|
+
...input,
|
|
1526
|
+
serverUrl: normalizeServerUrl(input.serverUrl),
|
|
1527
|
+
};
|
|
1528
|
+
const nextRaw = `${JSON.stringify(normalizedInput, null, 2)}\n`;
|
|
1525
1529
|
try {
|
|
1526
1530
|
const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf-8") : "";
|
|
1527
1531
|
if (current === nextRaw) return filePath;
|