openclaw-clawtown-plugin 1.1.33 → 1.1.35
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/reporter.ts +66 -8
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.35",
|
|
6
6
|
"main": "./index.ts",
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/package.json
CHANGED
package/reporter.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { normalizeForumServerUrl, readLocalReporterConfig, readOpenClawIdentity
|
|
|
11
11
|
const execFileAsync = promisify(execFile);
|
|
12
12
|
|
|
13
13
|
const DISABLE_BRIDGE_ENV = "OPENCLAW_FORUM_DISABLE_BRIDGE";
|
|
14
|
+
const PLUGIN_MANAGEMENT_PAIRING_PROBE_ENV = "OPENCLAW_FORUM_PAIRING_PROBE_ON_PLUGIN_COMMAND";
|
|
14
15
|
const BRIDGE_DISABLED = process.env[DISABLE_BRIDGE_ENV] === "1";
|
|
15
16
|
|
|
16
17
|
const PROFILE_SYNC_MIN_INTERVAL_MS = 5 * 60_000;
|
|
@@ -75,6 +76,28 @@ function isCurrentPluginLifecycleSuppressedInvocation(argv = process.argv.slice(
|
|
|
75
76
|
|| action === "disable";
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
function shouldProbePairingStatusInPluginManagementInvocation(argv = process.argv.slice(2), env = process.env) {
|
|
80
|
+
if (String(env[PLUGIN_MANAGEMENT_PAIRING_PROBE_ENV] ?? "").trim() !== "1") return false;
|
|
81
|
+
const tokens = Array.isArray(argv)
|
|
82
|
+
? argv.map((token) => String(token ?? "").trim()).filter(Boolean)
|
|
83
|
+
: [];
|
|
84
|
+
if (tokens.length < 2) return false;
|
|
85
|
+
if (tokens[0] !== "plugins") return false;
|
|
86
|
+
const action = tokens[1];
|
|
87
|
+
return action === "install" || action === "update";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function shouldProbePairingStatusInCliInvocation(argv = process.argv.slice(2), env = process.env) {
|
|
91
|
+
if (String(env.OPENCLAW_SERVICE_MARKER ?? "").trim()) return false;
|
|
92
|
+
const tokens = Array.isArray(argv)
|
|
93
|
+
? argv.map((token) => String(token ?? "").trim()).filter(Boolean)
|
|
94
|
+
: [];
|
|
95
|
+
if (tokens.length < 2) return false;
|
|
96
|
+
if (tokens[0] !== "gateway") return false;
|
|
97
|
+
const action = tokens[1];
|
|
98
|
+
return action === "restart" || action === "start" || action === "status";
|
|
99
|
+
}
|
|
100
|
+
|
|
78
101
|
function normalizeServerUrl(raw: string) {
|
|
79
102
|
return normalizeForumServerUrl(raw, "http://127.0.0.1:3679") || "http://127.0.0.1:3679";
|
|
80
103
|
}
|
|
@@ -253,11 +276,15 @@ class Reporter {
|
|
|
253
276
|
private suppressLifecycleForCliCommand = false;
|
|
254
277
|
|
|
255
278
|
constructor() {
|
|
279
|
+
const shouldProbePairingStatusInCurrentInvocation = shouldProbePairingStatusInCliInvocation()
|
|
280
|
+
|| shouldProbePairingStatusInPluginManagementInvocation();
|
|
256
281
|
if (isCurrentPluginLifecycleSuppressedInvocation()) {
|
|
257
282
|
this.bridgeDisabled = true;
|
|
258
283
|
this.suppressLifecycleForCliCommand = true;
|
|
259
284
|
console.log("[forum-reporter-v2] lifecycle suppressed during plugin management command");
|
|
260
|
-
|
|
285
|
+
if (!shouldProbePairingStatusInCurrentInvocation) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
261
288
|
}
|
|
262
289
|
const legacyRuntime = handleLegacyRuntimeConflict(this.reporterRuntime);
|
|
263
290
|
if (legacyRuntime.summary) {
|
|
@@ -284,7 +311,9 @@ class Reporter {
|
|
|
284
311
|
}
|
|
285
312
|
if (this.bridgeDisabled) {
|
|
286
313
|
console.log("[forum-reporter-v2] bridge disabled by env flag");
|
|
287
|
-
|
|
314
|
+
if (!shouldProbePairingStatusInCurrentInvocation) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
288
317
|
}
|
|
289
318
|
const homeDecision = resolvePreferredOpenClawHome();
|
|
290
319
|
this.forcedOpenClawHome = homeDecision.home;
|
|
@@ -314,6 +343,14 @@ class Reporter {
|
|
|
314
343
|
console.log("[forum-reporter-v2] 未检测到论坛身份,准备自动为这台机器分配 userId/apiKey");
|
|
315
344
|
}
|
|
316
345
|
|
|
346
|
+
if (shouldProbePairingStatusInCurrentInvocation) {
|
|
347
|
+
this.pairingStatusProbeOnly = true;
|
|
348
|
+
queueMicrotask(() => {
|
|
349
|
+
void this.runCliPairingStatusProbe();
|
|
350
|
+
});
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
317
354
|
if (this.userId && this.apiKey) {
|
|
318
355
|
this.instanceLockPath = this.resolveInstanceLockPath(this.userId);
|
|
319
356
|
const lockOk = this.acquireInstanceLock();
|
|
@@ -364,15 +401,16 @@ class Reporter {
|
|
|
364
401
|
|
|
365
402
|
async onHeartbeat(_agentId: string) {
|
|
366
403
|
if (this.suppressLifecycleForCliCommand) return;
|
|
404
|
+
if (this.pairingStatusProbeOnly) return;
|
|
367
405
|
if (this.bridgeDisabled) return;
|
|
368
406
|
this.start();
|
|
369
407
|
await this.syncProfile();
|
|
370
408
|
}
|
|
371
409
|
|
|
372
|
-
private async ensureAutoProvisioned() {
|
|
410
|
+
private async ensureAutoProvisioned(options?: { probeOnly?: boolean }) {
|
|
373
411
|
if (this.userId && this.apiKey) return true;
|
|
374
412
|
if (this.autoProvisionPromise) return this.autoProvisionPromise;
|
|
375
|
-
this.autoProvisionPromise = this.autoProvisionIdentity()
|
|
413
|
+
this.autoProvisionPromise = this.autoProvisionIdentity(options)
|
|
376
414
|
.catch((error) => {
|
|
377
415
|
console.warn(`[forum-reporter-v2] auto provision failed: ${String((error as any)?.message ?? error ?? "unknown")}`);
|
|
378
416
|
return false;
|
|
@@ -383,7 +421,7 @@ class Reporter {
|
|
|
383
421
|
return this.autoProvisionPromise;
|
|
384
422
|
}
|
|
385
423
|
|
|
386
|
-
private async autoProvisionIdentity() {
|
|
424
|
+
private async autoProvisionIdentity(options?: { probeOnly?: boolean }) {
|
|
387
425
|
if (this.userId && this.apiKey) return true;
|
|
388
426
|
const stateDir = resolveStateDirForConfiguredHome(this.forcedOpenClawHome);
|
|
389
427
|
const installationKey = ensureReporterInstallationKey(stateDir);
|
|
@@ -411,7 +449,7 @@ class Reporter {
|
|
|
411
449
|
openclawAgentId: this.openclawAgentId,
|
|
412
450
|
openclawSessionId: this.openclawSessionId,
|
|
413
451
|
});
|
|
414
|
-
if (!this.instanceLockPath) {
|
|
452
|
+
if (!options?.probeOnly && !this.instanceLockPath) {
|
|
415
453
|
this.instanceLockPath = this.resolveInstanceLockPath(this.userId);
|
|
416
454
|
this.acquireInstanceLock();
|
|
417
455
|
}
|
|
@@ -420,12 +458,32 @@ class Reporter {
|
|
|
420
458
|
const finalDisplayName = String(payload?.displayName ?? displayName).trim() || displayName;
|
|
421
459
|
this.logPairingStatus({ pairCode, isBound, displayName: finalDisplayName }, { autoProvisioned: true });
|
|
422
460
|
console.log(`[forum-reporter-v2] local reporter config saved: ${persistedPath}`);
|
|
423
|
-
|
|
424
|
-
|
|
461
|
+
if (!options?.probeOnly) {
|
|
462
|
+
this.ensureConnectionSelfHeal();
|
|
463
|
+
this.connectWebSocket();
|
|
464
|
+
}
|
|
425
465
|
await this.syncProfile(true);
|
|
426
466
|
return true;
|
|
427
467
|
}
|
|
428
468
|
|
|
469
|
+
private async runCliPairingStatusProbe() {
|
|
470
|
+
if (!this.userId || !this.apiKey) {
|
|
471
|
+
const provisioned = await this.ensureAutoProvisioned({ probeOnly: true });
|
|
472
|
+
if (!provisioned || !this.userId || !this.apiKey) {
|
|
473
|
+
if (!this.lastPairingStatusShown) {
|
|
474
|
+
console.warn("[forum-reporter-v2] pairing status probe did not finish forum identity provisioning");
|
|
475
|
+
}
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const result = await this.syncProfile(true);
|
|
481
|
+
if (!result.ok && !this.lastPairingStatusShown) {
|
|
482
|
+
const reason = String((result.error as any)?.message ?? result.error ?? "unknown").trim() || "unknown";
|
|
483
|
+
console.warn(`[forum-reporter-v2] pairing status probe failed: ${reason}`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
429
487
|
private async registerForumIdentityWithRetry(payload: Record<string, unknown>) {
|
|
430
488
|
const maxAttempts = 1 + AUTO_PROVISION_RETRY_COUNT;
|
|
431
489
|
let lastError: unknown = null;
|