@openclaw/clickclack 2026.7.2-beta.4 → 2026.7.2-beta.7

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.
@@ -1,6 +1,5 @@
1
1
  import { createAccountListHelpers, hasConfiguredAccountValue } from "openclaw/plugin-sdk/account-helpers";
2
2
  import { DEFAULT_ACCOUNT_ID, DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
- import { resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
4
3
  import { resolveNormalizedAccountEntry } from "openclaw/plugin-sdk/account-resolution-runtime";
5
4
  import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
6
5
  import { resolveDefaultSecretProviderAlias } from "openclaw/plugin-sdk/provider-auth";
@@ -15,7 +14,7 @@ import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
15
14
  import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
16
15
  import { WebSocket } from "ws";
17
16
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
18
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, applyAccountNameToChannelSection, applySetupAccountConfigPatch, baseUrlTextInput, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, hasConfiguredSecretInput, migrateBaseNameToDefaultAccount, moveSingleAccountChannelSectionToDefaultAccount, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
17
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, applyAccountNameToChannelSection, baseUrlTextInput, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, hasConfiguredSecretInput, moveSingleAccountChannelSectionToDefaultAccount, patchScopedAccountConfig, prepareScopedSetupConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
19
18
  import { createSetupInputPresenceValidator } from "openclaw/plugin-sdk/setup-runtime";
20
19
  import net from "node:net";
21
20
  //#region \0rolldown/runtime.js
@@ -39,36 +38,48 @@ const DEFAULT_RECONNECT_MS = 1500;
39
38
  const MIN_RECONNECT_MS = 100;
40
39
  const MAX_RECONNECT_MS = 6e4;
41
40
  const DEFAULT_DISCUSSIONS_SECTION = "Sessions";
42
- const { listAccountIds: listClickClackAccountIds, resolveDefaultAccountId: resolveDefaultClickClackAccountId } = createAccountListHelpers("clickclack", {
41
+ const { listAccountIds: listClickClackAccountIds, resolveDefaultAccountId: resolveDefaultClickClackAccountId, resolveAccountConfig: resolveMergedClickClackAccountConfig } = createAccountListHelpers("clickclack", {
43
42
  normalizeAccountId,
43
+ omitKeys: ["defaultAccount"],
44
+ nestedObjectKeys: ["discussions"],
44
45
  hasImplicitDefaultAccount: (cfg) => {
45
46
  const channel = cfg.channels?.clickclack;
46
47
  return Boolean(channel?.baseUrl?.trim() && (hasConfiguredAccountValue(channel.token) || Boolean(channel.tokenFile?.trim()) || Boolean(process.env.CLICKCLACK_BOT_TOKEN?.trim())) && channel.workspace?.trim());
47
48
  }
48
49
  });
50
+ function mergeClickClackGroups(...sources) {
51
+ const merged = /* @__PURE__ */ new Map();
52
+ for (const source of sources) for (const [rawKey, value] of Object.entries(source ?? {})) {
53
+ const key = rawKey.trim();
54
+ if (!key) continue;
55
+ merged.set(key, {
56
+ ...merged.get(key),
57
+ ...value.requireMention !== void 0 ? { requireMention: value.requireMention } : {},
58
+ ...value.mentionPatterns !== void 0 ? { mentionPatterns: value.mentionPatterns } : {}
59
+ });
60
+ }
61
+ return Object.fromEntries(merged);
62
+ }
49
63
  function resolveClickClackAccountConfig(cfg, accountId) {
50
64
  const channel = cfg.channels?.clickclack;
51
- const merged = resolveMergedAccountConfig({
52
- channelConfig: cfg.channels?.clickclack,
53
- accounts: channel?.accounts,
54
- accountId,
55
- omitKeys: ["defaultAccount"],
56
- nestedObjectKeys: ["discussions"],
57
- normalizeAccountId
58
- });
65
+ const merged = resolveMergedClickClackAccountConfig(cfg, accountId);
59
66
  const account = resolveNormalizedAccountEntry(channel?.accounts, accountId, normalizeAccountId);
67
+ const mergedWithGroups = channel?.groups || account?.groups ? {
68
+ ...merged,
69
+ groups: mergeClickClackGroups(channel?.groups, account?.groups)
70
+ } : merged;
60
71
  const accountTokenFile = account?.tokenFile?.trim();
61
72
  if (accountTokenFile) return {
62
- ...merged,
73
+ ...mergedWithGroups,
63
74
  token: account?.token,
64
75
  tokenFile: accountTokenFile
65
76
  };
66
77
  if (hasConfiguredAccountValue(account?.token)) return {
67
- ...merged,
78
+ ...mergedWithGroups,
68
79
  token: account?.token,
69
80
  tokenFile: void 0
70
81
  };
71
- return merged;
82
+ return mergedWithGroups;
72
83
  }
73
84
  function resolveClickClackToken(params) {
74
85
  const tokenFile = params.tokenFile?.trim();
@@ -144,6 +155,9 @@ function resolveClickClackAccount(params) {
144
155
  ...controlUrlBase ? { controlUrlBase } : {},
145
156
  section: merged.discussions?.section?.trim() || DEFAULT_DISCUSSIONS_SECTION
146
157
  },
158
+ requireMention: merged.requireMention === true,
159
+ mentionPatterns: merged.mentionPatterns ?? [],
160
+ groups: mergeClickClackGroups(merged.groups),
147
161
  config: {
148
162
  ...merged,
149
163
  allowFrom: merged.allowFrom ?? ["*"]
@@ -206,6 +220,12 @@ const ClickClackAccountConfigSchema = z.object({
206
220
  reconnectMs: z.number().int().min(100).max(6e4).optional(),
207
221
  agentActivity: z.boolean().optional(),
208
222
  commandMenu: z.boolean().optional(),
223
+ requireMention: z.boolean().optional(),
224
+ mentionPatterns: z.array(z.string()).optional(),
225
+ groups: z.record(z.string(), z.object({
226
+ requireMention: z.boolean().optional(),
227
+ mentionPatterns: z.array(z.string()).optional()
228
+ }).strict()).optional(),
209
229
  discussions: z.object({
210
230
  enabled: z.boolean().optional(),
211
231
  workspace: z.string().optional(),
@@ -672,69 +692,31 @@ function formatClickClackSetupCodeClaimError(error) {
672
692
  }
673
693
  function applyClickClackSetupConfigPatch(params) {
674
694
  const accountId = normalizeAccountId(params.accountId);
675
- const namedConfig = applyAccountNameToChannelSection({
676
- cfg: accountId === DEFAULT_ACCOUNT_ID ? params.cfg : moveSingleAccountChannelSectionToDefaultAccount({
677
- cfg: params.cfg,
695
+ return patchScopedAccountConfig({
696
+ cfg: prepareScopedSetupConfig({
697
+ cfg: accountId === DEFAULT_ACCOUNT_ID ? params.cfg : moveSingleAccountChannelSectionToDefaultAccount({
698
+ cfg: params.cfg,
699
+ channelKey: channel$1,
700
+ setupSurface: clickClackSetupAdapter
701
+ }),
678
702
  channelKey: channel$1,
679
- setupSurface: clickClackSetupAdapter
703
+ accountId,
704
+ name: params.name,
705
+ migrateBaseName: accountId !== DEFAULT_ACCOUNT_ID
680
706
  }),
681
707
  channelKey: channel$1,
682
708
  accountId,
683
- name: params.name
684
- });
685
- return applySetupAccountConfigPatch({
686
- cfg: accountId !== DEFAULT_ACCOUNT_ID ? migrateBaseNameToDefaultAccount({
687
- cfg: namedConfig,
688
- channelKey: channel$1
689
- }) : namedConfig,
690
- channelKey: channel$1,
691
- accountId,
692
- patch: params.patch
709
+ patch: params.patch,
710
+ ...params.clearFields ? { clearFields: params.clearFields } : {}
693
711
  });
694
712
  }
695
- function clearClickClackSetupConfigFields(params) {
696
- const clickclack = params.cfg.channels?.clickclack;
697
- if (!clickclack) return params.cfg;
698
- const accountId = normalizeAccountId(params.accountId);
699
- if (accountId === DEFAULT_ACCOUNT_ID) {
700
- const nextClickClack = { ...clickclack };
701
- for (const field of params.fields) delete nextClickClack[field];
702
- return {
703
- ...params.cfg,
704
- channels: {
705
- ...params.cfg.channels,
706
- clickclack: nextClickClack
707
- }
708
- };
709
- }
710
- const currentAccount = clickclack.accounts?.[accountId];
711
- if (!currentAccount) return params.cfg;
712
- const nextAccount = { ...currentAccount };
713
- for (const field of params.fields) delete nextAccount[field];
714
- return {
715
- ...params.cfg,
716
- channels: {
717
- ...params.cfg.channels,
718
- clickclack: {
719
- ...clickclack,
720
- accounts: {
721
- ...clickclack.accounts,
722
- [accountId]: nextAccount
723
- }
724
- }
725
- }
726
- };
727
- }
728
713
  function applyClickClackCredentialConfig(params) {
729
714
  const fieldsToClear = params.useEnv ? ["token", "tokenFile"] : params.tokenFile ? ["token"] : params.token !== void 0 ? ["tokenFile"] : [];
730
- return clearClickClackSetupConfigFields({
731
- cfg: applyClickClackSetupConfigPatch({
732
- cfg: params.cfg,
733
- accountId: params.accountId,
734
- patch: params.useEnv ? {} : params.tokenFile ? { tokenFile: params.tokenFile } : params.token !== void 0 ? { token: params.token } : {}
735
- }),
715
+ return applyClickClackSetupConfigPatch({
716
+ cfg: params.cfg,
736
717
  accountId: params.accountId,
737
- fields: fieldsToClear
718
+ clearFields: fieldsToClear,
719
+ patch: params.useEnv ? {} : params.tokenFile ? { tokenFile: params.tokenFile } : params.token !== void 0 ? { token: params.token } : {}
738
720
  });
739
721
  }
740
722
  const clickClackSetupAdapter = {
@@ -751,7 +733,7 @@ const clickClackSetupAdapter = {
751
733
  const claimUrl = setup.exactClaimUrl && !privateApiBaseUrl ? setup.exactClaimUrl : buildClickClackSetupClaimUrl(privateApiBaseUrl ?? setup.baseUrl);
752
734
  let claim;
753
735
  try {
754
- const { claimClickClackSetupCode } = await import("./setup-claim-CJIUfZS7.js");
736
+ const { claimClickClackSetupCode } = await import("./setup-claim-CP-QZ5bt.js");
755
737
  claim = await claimClickClackSetupCode({
756
738
  claimUrl,
757
739
  code: setup.code,
@@ -6,16 +6,6 @@
6
6
  "channels": [
7
7
  "clickclack"
8
8
  ],
9
- "contracts": {
10
- "tools": [
11
- "discussion"
12
- ]
13
- },
14
- "configSchema": {
15
- "type": "object",
16
- "additionalProperties": false,
17
- "properties": {}
18
- },
19
9
  "channelConfigs": {
20
10
  "clickclack": {
21
11
  "schema": {
@@ -165,6 +155,36 @@
165
155
  "commandMenu": {
166
156
  "type": "boolean"
167
157
  },
158
+ "requireMention": {
159
+ "type": "boolean"
160
+ },
161
+ "mentionPatterns": {
162
+ "type": "array",
163
+ "items": {
164
+ "type": "string"
165
+ }
166
+ },
167
+ "groups": {
168
+ "type": "object",
169
+ "propertyNames": {
170
+ "type": "string"
171
+ },
172
+ "additionalProperties": {
173
+ "type": "object",
174
+ "properties": {
175
+ "requireMention": {
176
+ "type": "boolean"
177
+ },
178
+ "mentionPatterns": {
179
+ "type": "array",
180
+ "items": {
181
+ "type": "string"
182
+ }
183
+ }
184
+ },
185
+ "additionalProperties": false
186
+ }
187
+ },
168
188
  "discussions": {
169
189
  "type": "object",
170
190
  "properties": {
@@ -335,6 +355,36 @@
335
355
  "commandMenu": {
336
356
  "type": "boolean"
337
357
  },
358
+ "requireMention": {
359
+ "type": "boolean"
360
+ },
361
+ "mentionPatterns": {
362
+ "type": "array",
363
+ "items": {
364
+ "type": "string"
365
+ }
366
+ },
367
+ "groups": {
368
+ "type": "object",
369
+ "propertyNames": {
370
+ "type": "string"
371
+ },
372
+ "additionalProperties": {
373
+ "type": "object",
374
+ "properties": {
375
+ "requireMention": {
376
+ "type": "boolean"
377
+ },
378
+ "mentionPatterns": {
379
+ "type": "array",
380
+ "items": {
381
+ "type": "string"
382
+ }
383
+ }
384
+ },
385
+ "additionalProperties": false
386
+ }
387
+ },
338
388
  "discussions": {
339
389
  "type": "object",
340
390
  "properties": {
@@ -365,7 +415,17 @@
365
415
  "additionalProperties": false
366
416
  },
367
417
  "label": "ClickClack",
368
- "description": "self-hosted chat via first-class ClickClack bot tokens."
418
+ "description": "ClickClack channel accounts and group activation policy."
369
419
  }
420
+ },
421
+ "contracts": {
422
+ "tools": [
423
+ "discussion"
424
+ ]
425
+ },
426
+ "configSchema": {
427
+ "type": "object",
428
+ "additionalProperties": false,
429
+ "properties": {}
370
430
  }
371
431
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/clickclack",
3
- "version": "2026.7.2-beta.4",
3
+ "version": "2026.7.2-beta.7",
4
4
  "description": "OpenClaw ClickClack channel plugin",
5
5
  "type": "module",
6
6
  "exports": {
@@ -13,7 +13,7 @@
13
13
  "zod": "4.4.3"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.7.2-beta.4"
16
+ "openclaw": ">=2026.7.2-beta.7"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -136,10 +136,10 @@
136
136
  "allowInvalidConfigRecovery": true
137
137
  },
138
138
  "compat": {
139
- "pluginApi": ">=2026.7.2-beta.4"
139
+ "pluginApi": ">=2026.7.2-beta.7"
140
140
  },
141
141
  "build": {
142
- "openclawVersion": "2026.7.2-beta.4",
142
+ "openclawVersion": "2026.7.2-beta.7",
143
143
  "bundledDist": false
144
144
  },
145
145
  "release": {
@@ -158,7 +158,6 @@
158
158
  "files": [
159
159
  "dist/**",
160
160
  "openclaw.plugin.json",
161
- "npm-shrinkwrap.json",
162
161
  "README.md"
163
162
  ],
164
163
  "bundledDependencies": [
@@ -1,54 +0,0 @@
1
- {
2
- "name": "@openclaw/clickclack",
3
- "version": "2026.7.2-beta.4",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "": {
8
- "name": "@openclaw/clickclack",
9
- "version": "2026.7.2-beta.4",
10
- "dependencies": {
11
- "ws": "8.21.1",
12
- "zod": "4.4.3"
13
- },
14
- "peerDependencies": {
15
- "openclaw": ">=2026.7.2-beta.4"
16
- },
17
- "peerDependenciesMeta": {
18
- "openclaw": {
19
- "optional": true
20
- }
21
- }
22
- },
23
- "node_modules/ws": {
24
- "version": "8.21.1",
25
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
26
- "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
27
- "license": "MIT",
28
- "engines": {
29
- "node": ">=10.0.0"
30
- },
31
- "peerDependencies": {
32
- "bufferutil": "^4.0.1",
33
- "utf-8-validate": ">=5.0.2"
34
- },
35
- "peerDependenciesMeta": {
36
- "bufferutil": {
37
- "optional": true
38
- },
39
- "utf-8-validate": {
40
- "optional": true
41
- }
42
- }
43
- },
44
- "node_modules/zod": {
45
- "version": "4.4.3",
46
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
47
- "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
48
- "license": "MIT",
49
- "funding": {
50
- "url": "https://github.com/sponsors/colinhacks"
51
- }
52
- }
53
- }
54
- }