@openclaw/clickclack 2026.8.1-beta.2 → 2026.8.1-beta.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.
package/dist/api.js CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as DEFAULT_ACCOUNT_ID, b as resolveClickClackAccount, p as clickClackConfigSchema, u as createClickClackClient, v as listClickClackAccountIds, x as resolveDefaultClickClackAccountId, y as listEnabledClickClackAccounts } from "./setup-surface-DjT-gmMe.js";
2
- import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./channel-DaHgaTy1.js";
1
+ import { _ as DEFAULT_ACCOUNT_ID, b as resolveClickClackAccount, p as clickClackConfigSchema, u as createClickClackClient, v as listClickClackAccountIds, x as resolveDefaultClickClackAccountId, y as listEnabledClickClackAccounts } from "./setup-surface-BQ1Zyohu.js";
2
+ import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./channel-ChO3E9i2.js";
3
3
  export { DEFAULT_ACCOUNT_ID, buildClickClackTarget, clickClackConfigSchema, clickClackPlugin, createClickClackClient, getClickClackRuntime, listClickClackAccountIds, listEnabledClickClackAccounts, parseClickClackTarget, resolveClickClackAccount, resolveDefaultClickClackAccountId, setClickClackRuntime };
@@ -1,4 +1,4 @@
1
- import { _ as DEFAULT_ACCOUNT_ID, b as resolveClickClackAccount, c as resolveWorkspaceId, f as normalizeClickClackCorrelationId, g as clickClackMeta, h as clickClackConfigAdapter, l as ClickClackHttpError, m as CLICKCLACK_CHANNEL_ID, n as clickClackSetupContract, p as clickClackConfigSchema, s as resolveChannelId, t as clickClackSetupWizard, u as createClickClackClient, y as listEnabledClickClackAccounts } from "./setup-surface-DjT-gmMe.js";
1
+ import { _ as DEFAULT_ACCOUNT_ID, b as resolveClickClackAccount, c as resolveWorkspaceId, f as normalizeClickClackCorrelationId, g as clickClackMeta, h as clickClackConfigAdapter, l as ClickClackHttpError, m as CLICKCLACK_CHANNEL_ID, n as clickClackSetupContract, p as clickClackConfigSchema, s as resolveChannelId, t as clickClackSetupWizard, u as createClickClackClient, y as listEnabledClickClackAccounts } from "./setup-surface-BQ1Zyohu.js";
2
2
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-BKkzzjBA.js";
3
3
  import { parseDateStringTimestampMs } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
@@ -866,15 +866,16 @@ async function syncClickClackCommandMenu(params) {
866
866
  await params.client.setBotCommands(commands);
867
867
  } catch (error) {
868
868
  const status = errorStatus(error);
869
+ const messagePrefix = `[${params.accountId}] ClickClack command menu sync`;
869
870
  if (status === 403) {
870
- params.log?.warn?.("ClickClack command menu sync skipped: bot token lacks commands:write");
871
+ params.log?.warn?.(`${messagePrefix} skipped: ${formatErrorMessage(error)}; verify token/workspace command permissions or set commandMenu: false if menus are not needed`);
871
872
  return;
872
873
  }
873
874
  if (status === 404) {
874
- params.log?.debug?.("ClickClack command menu sync skipped: server does not support /api/bots/self/commands");
875
+ params.log?.debug?.(`${messagePrefix} skipped: server does not support /api/bots/self/commands`);
875
876
  return;
876
877
  }
877
- params.log?.warn?.(`ClickClack command menu sync failed: ${formatErrorMessage(error)}`);
878
+ params.log?.warn?.(`${messagePrefix} failed: ${formatErrorMessage(error)}`);
878
879
  }
879
880
  }
880
881
  //#endregion
@@ -1948,7 +1949,8 @@ async function startClickClackGatewayAccount(ctx) {
1948
1949
  if (account.commandMenu) await syncClickClackCommandMenu({
1949
1950
  cfg: ctx.cfg,
1950
1951
  client,
1951
- log: ctx.log
1952
+ log: ctx.log,
1953
+ accountId: account.accountId
1952
1954
  });
1953
1955
  ctx.setStatus({
1954
1956
  accountId: account.accountId,
@@ -2156,6 +2158,7 @@ const clickClackPlugin = createChatChannelPlugin({
2156
2158
  capabilities: {
2157
2159
  chatTypes: ["direct", "group"],
2158
2160
  threads: true,
2161
+ media: true,
2159
2162
  blockStreaming: true
2160
2163
  },
2161
2164
  reload: { configPrefixes: ["channels.clickclack"] },
@@ -2222,7 +2225,11 @@ const clickClackPlugin = createChatChannelPlugin({
2222
2225
  name: account.name,
2223
2226
  enabled: account.enabled,
2224
2227
  configured: account.configured,
2225
- baseUrl: account.baseUrl
2228
+ extra: {
2229
+ baseUrl: account.baseUrl,
2230
+ tokenSource: account.tokenSource,
2231
+ tokenStatus: account.tokenStatus
2232
+ }
2226
2233
  })
2227
2234
  }),
2228
2235
  gateway: { startAccount: startClickClackGatewayAccount },
@@ -1,2 +1,2 @@
1
- import { t as clickClackPlugin } from "./channel-DaHgaTy1.js";
1
+ import { t as clickClackPlugin } from "./channel-ChO3E9i2.js";
2
2
  export { clickClackPlugin };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as registerClickClackDiscussions } from "./runtime-api-CPL3m5AD.js";
1
+ import { t as registerClickClackDiscussions } from "./runtime-api-B0ChZLhm.js";
2
2
  import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
3
3
  //#region extensions/clickclack/index.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { b as resolveClickClackAccount, d as isClickClackChannelNameConflict, l as ClickClackHttpError, u as createClickClackClient, v as listClickClackAccountIds } from "./setup-surface-DjT-gmMe.js";
2
- import { C as slugifyDiscussionLabel, D as listPendingDiscussionOpens, E as clearPendingDiscussionOpen, O as recordPendingDiscussionOpen, S as resolveDiscussionLabel, T as clearDiscussionBindingGeneration, _ as getClickClackDiscussionBindingStore, b as fallbackDiscussionLabel, c as markClickClackDiscussionChannelIdentityRevoked, d as discussionInfoForBinding, f as normalizedServerBaseUrl, g as bindingMatchesActiveSessionIncarnation, h as attachBindingToCurrentActiveSession, k as reserveDiscussionBindingGeneration, l as markClickClackDiscussionChannelRevoked, o as clearClickClackDiscussionChannelRevoked, p as resolveDiscussionBindingAccount, s as isClickClackDiscussionChannelRevoked, u as discussionAccounts, v as discussionCredentialFingerprint, w as truncateDiscussionDisplayTitle, x as isDiscussionSessionKey, y as discussionExternalRef } from "./channel-DaHgaTy1.js";
1
+ import { b as resolveClickClackAccount, d as isClickClackChannelNameConflict, l as ClickClackHttpError, u as createClickClackClient, v as listClickClackAccountIds } from "./setup-surface-BQ1Zyohu.js";
2
+ import { C as slugifyDiscussionLabel, D as listPendingDiscussionOpens, E as clearPendingDiscussionOpen, O as recordPendingDiscussionOpen, S as resolveDiscussionLabel, T as clearDiscussionBindingGeneration, _ as getClickClackDiscussionBindingStore, b as fallbackDiscussionLabel, c as markClickClackDiscussionChannelIdentityRevoked, d as discussionInfoForBinding, f as normalizedServerBaseUrl, g as bindingMatchesActiveSessionIncarnation, h as attachBindingToCurrentActiveSession, k as reserveDiscussionBindingGeneration, l as markClickClackDiscussionChannelRevoked, o as clearClickClackDiscussionChannelRevoked, p as resolveDiscussionBindingAccount, s as isClickClackDiscussionChannelRevoked, u as discussionAccounts, v as discussionCredentialFingerprint, w as truncateDiscussionDisplayTitle, x as isDiscussionSessionKey, y as discussionExternalRef } from "./channel-ChO3E9i2.js";
3
3
  import "./api.js";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { buildControlUiSessionPath, registerSessionDiscussionProvider } from "openclaw/plugin-sdk/session-discussion";
@@ -1,4 +1,4 @@
1
- import { b as resolveClickClackAccount, u as createClickClackClient } from "./setup-surface-DjT-gmMe.js";
2
- import { a as setClickClackRuntime, r as parseClickClackTarget } from "./channel-DaHgaTy1.js";
3
- import { t as registerClickClackDiscussions } from "./runtime-api-CPL3m5AD.js";
1
+ import { b as resolveClickClackAccount, u as createClickClackClient } from "./setup-surface-BQ1Zyohu.js";
2
+ import { a as setClickClackRuntime, r as parseClickClackTarget } from "./channel-ChO3E9i2.js";
3
+ import { t as registerClickClackDiscussions } from "./runtime-api-B0ChZLhm.js";
4
4
  export { createClickClackClient, parseClickClackTarget, registerClickClackDiscussions, resolveClickClackAccount, setClickClackRuntime };
@@ -1,4 +1,4 @@
1
- import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-DjT-gmMe.js";
1
+ import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-BQ1Zyohu.js";
2
2
  import { createProviderOperationDeadline, readProviderJsonResponse, readResponseTextLimited, resolveProviderOperationTimeoutMs } from "openclaw/plugin-sdk/provider-http";
3
3
  import { fetchWithSsrFGuard, resolvePinnedHostnameWithPolicy, ssrfPolicyFromHttpBaseUrlAllowedHostname } from "openclaw/plugin-sdk/ssrf-runtime";
4
4
  import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -1,4 +1,4 @@
1
- import { g as clickClackMeta, h as clickClackConfigAdapter, n as clickClackSetupContract, p as clickClackConfigSchema, t as clickClackSetupWizard } from "./setup-surface-DjT-gmMe.js";
1
+ import { g as clickClackMeta, h as clickClackConfigAdapter, n as clickClackSetupContract, p as clickClackConfigSchema, t as clickClackSetupWizard } from "./setup-surface-BQ1Zyohu.js";
2
2
  //#region extensions/clickclack/src/channel.setup.ts
3
3
  const clickClackSetupPlugin = {
4
4
  id: "clickclack",
@@ -5,7 +5,7 @@ import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
6
6
  import { resolveDefaultSecretProviderAlias } from "openclaw/plugin-sdk/provider-auth";
7
7
  import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
8
- import { buildSecretInputSchema, normalizeResolvedSecretInputString, normalizeSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
8
+ import { buildSecretInputSchema, normalizeSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
9
9
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
10
  import { getChatChannelMeta } from "openclaw/plugin-sdk/channel-plugin-common";
11
11
  import { ChannelBotLoopProtectionSchema, buildChannelAllowBotsSchema, buildChannelConfigSchema, buildMultiAccountChannelSchema } from "openclaw/plugin-sdk/channel-config-schema";
@@ -87,7 +87,20 @@ function resolveClickClackAccountConfig(cfg, accountId) {
87
87
  }
88
88
  function resolveClickClackToken(params) {
89
89
  const tokenFile = params.tokenFile?.trim();
90
- if (tokenFile) return tryReadSecretFileSync(tokenFile, params.accountId === DEFAULT_ACCOUNT_ID$2 ? "channels.clickclack.tokenFile" : `channels.clickclack.accounts.${params.accountId}.tokenFile`, { rejectSymlink: true }) ?? "";
90
+ if (tokenFile) {
91
+ const accountTokenFile = resolveNormalizedAccountEntry(params.cfg.channels?.clickclack?.accounts, params.accountId, normalizeAccountId)?.tokenFile?.trim();
92
+ const result = tryReadSecretFileSync(tokenFile, "ClickClack bot token", { rejectSymlink: true }, { configPath: accountTokenFile ? `channels.clickclack.accounts.${params.accountId}.tokenFile` : "channels.clickclack.tokenFile" });
93
+ return result.status === "available" ? {
94
+ token: result.value,
95
+ tokenSource: "tokenFile",
96
+ tokenStatus: "available"
97
+ } : {
98
+ token: "",
99
+ tokenSource: "tokenFile",
100
+ tokenStatus: "configured_unavailable",
101
+ credentialDiagnostics: [result.diagnostic]
102
+ };
103
+ }
91
104
  const resolved = resolveSecretInputString({
92
105
  value: params.value,
93
106
  path: params.accountId === DEFAULT_ACCOUNT_ID$2 ? "channels.clickclack.token" : `channels.clickclack.accounts.${params.accountId}.token`,
@@ -95,21 +108,42 @@ function resolveClickClackToken(params) {
95
108
  mode: "inspect"
96
109
  });
97
110
  if (resolved.status !== "available") {
98
- if (resolved.status === "missing" && params.accountId === DEFAULT_ACCOUNT_ID$2) return normalizeSecretInputString((params.env ?? process.env).CLICKCLACK_BOT_TOKEN) ?? "";
111
+ if (resolved.status === "missing" && params.accountId === DEFAULT_ACCOUNT_ID$2) {
112
+ const token = normalizeSecretInputString((params.env ?? process.env).CLICKCLACK_BOT_TOKEN);
113
+ return token ? {
114
+ token,
115
+ tokenSource: "env",
116
+ tokenStatus: "available"
117
+ } : {
118
+ token: "",
119
+ tokenSource: "none",
120
+ tokenStatus: "missing"
121
+ };
122
+ }
99
123
  if (resolved.status === "configured_unavailable" && resolved.ref.source === "env") {
100
124
  const providerConfig = params.cfg.secrets?.providers?.[resolved.ref.provider];
101
125
  if (providerConfig) {
102
126
  if (providerConfig.source !== "env") throw new Error(`Secret provider "${resolved.ref.provider}" has source "${providerConfig.source}" but ref requests "env".`);
103
127
  if (providerConfig.allowlist && !providerConfig.allowlist.includes(resolved.ref.id)) throw new Error(`Environment variable "${resolved.ref.id}" is not allowlisted in secrets.providers.${resolved.ref.provider}.allowlist.`);
104
128
  } else if (resolved.ref.provider !== resolveDefaultSecretProviderAlias({ secrets: params.cfg.secrets }, "env")) throw new Error(`Secret provider "${resolved.ref.provider}" is not configured (ref: env:${resolved.ref.provider}:${resolved.ref.id}).`);
105
- return normalizeSecretInputString((params.env ?? process.env)[resolved.ref.id]) ?? "";
129
+ const token = normalizeSecretInputString((params.env ?? process.env)[resolved.ref.id]);
130
+ return {
131
+ token: token ?? "",
132
+ tokenSource: "config",
133
+ tokenStatus: token ? "available" : "configured_unavailable"
134
+ };
106
135
  }
107
- return "";
136
+ return {
137
+ token: "",
138
+ tokenSource: resolved.status === "missing" ? "none" : "config",
139
+ tokenStatus: resolved.status
140
+ };
108
141
  }
109
- return normalizeResolvedSecretInputString({
110
- value: resolved.value,
111
- path: "channels.clickclack.token"
112
- }) ?? "";
142
+ return {
143
+ token: resolved.value,
144
+ tokenSource: "config",
145
+ tokenStatus: "available"
146
+ };
113
147
  }
114
148
  /**
115
149
  * Builds the normalized account snapshot used by gateway, outbound delivery,
@@ -134,10 +168,10 @@ function resolveClickClackAccount(params) {
134
168
  return {
135
169
  accountId,
136
170
  enabled,
137
- configured: Boolean(baseUrl && token && workspace),
171
+ configured: Boolean(baseUrl && token.tokenStatus !== "missing" && workspace),
138
172
  name: normalizeOptionalString(merged.name),
139
173
  baseUrl,
140
- token,
174
+ ...token,
141
175
  workspace,
142
176
  botUserId: normalizeOptionalString(merged.botUserId),
143
177
  agentId: normalizeOptionalString(merged.agentId),
@@ -482,7 +516,7 @@ function createClickClackClient(options) {
482
516
  },
483
517
  createUpload: async (params) => {
484
518
  const form = new FormData();
485
- const bytes = new Uint8Array(params.buffer);
519
+ const bytes = params.buffer.buffer instanceof ArrayBuffer ? new Uint8Array(params.buffer.buffer, params.buffer.byteOffset, params.buffer.byteLength) : Uint8Array.from(params.buffer);
486
520
  form.append("file", new Blob([bytes], { type: params.contentType }), params.filename);
487
521
  const query = new URLSearchParams({ workspace_id: params.workspaceId });
488
522
  if (params.nonce) query.set("nonce", params.nonce);
@@ -779,7 +813,7 @@ const clickClackSetupAdapter = {
779
813
  const claimUrl = setup.exactClaimUrl && !privateApiBaseUrl ? setup.exactClaimUrl : buildClickClackSetupClaimUrl(privateApiBaseUrl ?? setup.baseUrl);
780
814
  let claim;
781
815
  try {
782
- const { claimClickClackSetupCode } = await import("./setup-claim-CQjgPGxU.js");
816
+ const { claimClickClackSetupCode } = await import("./setup-claim--cdFCz2P.js");
783
817
  claim = await claimClickClackSetupCode({
784
818
  claimUrl,
785
819
  code: setup.code,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/clickclack",
3
- "version": "2026.8.1-beta.2",
3
+ "version": "2026.8.1-beta.3",
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.8.1-beta.2"
16
+ "openclaw": ">=2026.8.1-beta.3"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -139,10 +139,10 @@
139
139
  "allowInvalidConfigRecovery": true
140
140
  },
141
141
  "compat": {
142
- "pluginApi": ">=2026.8.1-beta.2"
142
+ "pluginApi": ">=2026.8.1-beta.3"
143
143
  },
144
144
  "build": {
145
- "openclawVersion": "2026.8.1-beta.2",
145
+ "openclawVersion": "2026.8.1-beta.3",
146
146
  "bundledDist": false
147
147
  },
148
148
  "release": {