@clawling/clawchat-plugin-openclaw 2026.6.16-1 → 2026.6.16-3

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.
@@ -185,6 +185,27 @@ function readOptionalString(value) {
185
185
  function readEnvString(env, key) {
186
186
  return readOptionalString(env[key]);
187
187
  }
188
+ /**
189
+ * Decode a string claim from a JWT access token's payload (no signature
190
+ * verification — this is for self-identifying claims the backend already signed,
191
+ * e.g. `oid` owner id). Returns "" on any malformed input.
192
+ */
193
+ function decodeJwtStringClaim(token, claim) {
194
+ if (typeof token !== "string")
195
+ return "";
196
+ const segments = token.split(".");
197
+ if (segments.length < 2 || !segments[1])
198
+ return "";
199
+ try {
200
+ const json = Buffer.from(segments[1], "base64url").toString("utf8");
201
+ const parsed = JSON.parse(json);
202
+ const value = parsed?.[claim];
203
+ return typeof value === "string" ? value.trim() : "";
204
+ }
205
+ catch {
206
+ return "";
207
+ }
208
+ }
188
209
  function readGroupMode(value) {
189
210
  return value === "mention" ? "mention" : "all";
190
211
  }
@@ -291,7 +312,13 @@ export function resolveOpenclawClawlingAccount(cfg, env = process.env) {
291
312
  const token = readOptionalString(channel.token) || readEnvString(env, CLAWCHAT_TOKEN_ENV);
292
313
  const agentId = readOptionalString(channel.agentId) || readEnvString(env, CLAWCHAT_AGENT_ID_ENV);
293
314
  const userId = readOptionalString(channel.userId) || readEnvString(env, CLAWCHAT_USER_ID_ENV);
294
- const ownerUserId = readOptionalString(channel.ownerUserId) || readEnvString(env, CLAWCHAT_OWNER_USER_ID_ENV);
315
+ const ownerUserId = readOptionalString(channel.ownerUserId) ||
316
+ readEnvString(env, CLAWCHAT_OWNER_USER_ID_ENV) ||
317
+ // Fall back to the access token's `oid` (owner) claim. A provisioner may
318
+ // inject token + userId but omit ownerUserId; without it the connect gate
319
+ // (hasOpenclawClawlingConnectCredentials) never passes and the plugin sits
320
+ // in the wait-for-activation loop. The owner is always carried in the token.
321
+ decodeJwtStringClaim(token, "oid");
295
322
  const enabled = typeof channel.enabled === "boolean" ? channel.enabled : true;
296
323
  const outputVisibility = readOutputVisibility(channel.outputVisibility);
297
324
  const chats = readChats(channel.chats);
@@ -1,11 +1,38 @@
1
1
  import { createRequire } from "node:module";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { createOpenclawClawlingApiClient } from "./api-client.js";
3
- /** Best-effort read of this plugin's package version; "unknown" on failure. */
5
+ const PACKAGE_NAME = "@clawling/clawchat-plugin-openclaw";
6
+ /**
7
+ * Best-effort read of this plugin's package version; "unknown" on failure.
8
+ *
9
+ * Walks up from this module's directory to the nearest package.json whose
10
+ * name matches this plugin, instead of assuming a fixed relative depth. The
11
+ * compiled module lives at dist/src/plugin-report.js (rootDir "." + outDir
12
+ * "dist"), so a hard-coded "../package.json" resolves to the non-existent
13
+ * dist/package.json at runtime and always falls back to "unknown" — even
14
+ * though it happens to work when tests run straight from src/.
15
+ */
4
16
  export function resolvePluginVersion() {
5
17
  try {
6
18
  const require = createRequire(import.meta.url);
7
- const pkg = require("../package.json");
8
- return pkg.version ?? "unknown";
19
+ let dir = dirname(fileURLToPath(import.meta.url));
20
+ // Bounded climb (handles dist/src, src, and any reasonable nesting).
21
+ for (let i = 0; i < 8; i += 1) {
22
+ try {
23
+ const pkg = require(join(dir, "package.json"));
24
+ if (pkg.name === PACKAGE_NAME && pkg.version)
25
+ return pkg.version;
26
+ }
27
+ catch {
28
+ // no package.json at this level — keep climbing
29
+ }
30
+ const parent = dirname(dir);
31
+ if (parent === dir)
32
+ break;
33
+ dir = parent;
34
+ }
35
+ return "unknown";
9
36
  }
10
37
  catch {
11
38
  return "unknown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawling/clawchat-plugin-openclaw",
3
- "version": "2026.6.16-1",
3
+ "version": "2026.6.16-3",
4
4
  "description": "OpenClaw ClawChat channel plugin",
5
5
  "license": "MIT",
6
6
  "files": [
package/src/config.ts CHANGED
@@ -309,6 +309,25 @@ function readEnvString(env: Record<string, string | undefined>, key: string): st
309
309
  return readOptionalString(env[key]);
310
310
  }
311
311
 
312
+ /**
313
+ * Decode a string claim from a JWT access token's payload (no signature
314
+ * verification — this is for self-identifying claims the backend already signed,
315
+ * e.g. `oid` owner id). Returns "" on any malformed input.
316
+ */
317
+ function decodeJwtStringClaim(token: string, claim: string): string {
318
+ if (typeof token !== "string") return "";
319
+ const segments = token.split(".");
320
+ if (segments.length < 2 || !segments[1]) return "";
321
+ try {
322
+ const json = Buffer.from(segments[1], "base64url").toString("utf8");
323
+ const parsed = JSON.parse(json) as Record<string, unknown>;
324
+ const value = parsed?.[claim];
325
+ return typeof value === "string" ? value.trim() : "";
326
+ } catch {
327
+ return "";
328
+ }
329
+ }
330
+
312
331
  function readGroupMode(value: unknown): GroupMode {
313
332
  return value === "mention" ? "mention" : "all";
314
333
  }
@@ -444,7 +463,13 @@ export function resolveOpenclawClawlingAccount(
444
463
  const agentId = readOptionalString(channel.agentId) || readEnvString(env, CLAWCHAT_AGENT_ID_ENV);
445
464
  const userId = readOptionalString(channel.userId) || readEnvString(env, CLAWCHAT_USER_ID_ENV);
446
465
  const ownerUserId =
447
- readOptionalString(channel.ownerUserId) || readEnvString(env, CLAWCHAT_OWNER_USER_ID_ENV);
466
+ readOptionalString(channel.ownerUserId) ||
467
+ readEnvString(env, CLAWCHAT_OWNER_USER_ID_ENV) ||
468
+ // Fall back to the access token's `oid` (owner) claim. A provisioner may
469
+ // inject token + userId but omit ownerUserId; without it the connect gate
470
+ // (hasOpenclawClawlingConnectCredentials) never passes and the plugin sits
471
+ // in the wait-for-activation loop. The owner is always carried in the token.
472
+ decodeJwtStringClaim(token, "oid");
448
473
  const enabled = typeof channel.enabled === "boolean" ? channel.enabled : true;
449
474
  const outputVisibility = readOutputVisibility(channel.outputVisibility);
450
475
  const chats = readChats(channel.chats);
@@ -1,12 +1,40 @@
1
1
  import { createRequire } from "node:module";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { createOpenclawClawlingApiClient } from "./api-client.ts";
3
5
 
4
- /** Best-effort read of this plugin's package version; "unknown" on failure. */
6
+ const PACKAGE_NAME = "@clawling/clawchat-plugin-openclaw";
7
+
8
+ /**
9
+ * Best-effort read of this plugin's package version; "unknown" on failure.
10
+ *
11
+ * Walks up from this module's directory to the nearest package.json whose
12
+ * name matches this plugin, instead of assuming a fixed relative depth. The
13
+ * compiled module lives at dist/src/plugin-report.js (rootDir "." + outDir
14
+ * "dist"), so a hard-coded "../package.json" resolves to the non-existent
15
+ * dist/package.json at runtime and always falls back to "unknown" — even
16
+ * though it happens to work when tests run straight from src/.
17
+ */
5
18
  export function resolvePluginVersion(): string {
6
19
  try {
7
20
  const require = createRequire(import.meta.url);
8
- const pkg = require("../package.json") as { version?: string };
9
- return pkg.version ?? "unknown";
21
+ let dir = dirname(fileURLToPath(import.meta.url));
22
+ // Bounded climb (handles dist/src, src, and any reasonable nesting).
23
+ for (let i = 0; i < 8; i += 1) {
24
+ try {
25
+ const pkg = require(join(dir, "package.json")) as {
26
+ name?: string;
27
+ version?: string;
28
+ };
29
+ if (pkg.name === PACKAGE_NAME && pkg.version) return pkg.version;
30
+ } catch {
31
+ // no package.json at this level — keep climbing
32
+ }
33
+ const parent = dirname(dir);
34
+ if (parent === dir) break;
35
+ dir = parent;
36
+ }
37
+ return "unknown";
10
38
  } catch {
11
39
  return "unknown";
12
40
  }