@openclaw/clickclack 2026.9.1-beta.1 → 2026.9.1

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/README.md CHANGED
@@ -119,8 +119,8 @@ not have an account selector.
119
119
  Messages in the managed channel run in a stable side session under the same
120
120
  agent id as the attached main session. The plugin installs a scoped host grant
121
121
  for `sessions_history`, `session_status`, and `sessions_send` between that side
122
- session and its attached main session, so `tools.sessions.visibility` can stay
123
- at its safer default `tree`. A second host-side policy blocks session discovery
122
+ session and its attached main session, so `tools.sessions.visibility` can be set
123
+ explicitly to `tree` for narrower access than the agent-wide default. A second host-side policy blocks session discovery
124
124
  and alternate targets; the side-agent prompt is not the authorization boundary.
125
125
  The agent still needs those three tools in its effective tool allowlist.
126
126
 
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-u7Mgy8Wp.js";
2
- import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./channel-DbE7fnUL.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-ktvDJmH4.js";
2
+ import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./channel-DR3HQ51j.js";
3
3
  export { DEFAULT_ACCOUNT_ID, buildClickClackTarget, clickClackConfigSchema, clickClackPlugin, createClickClackClient, getClickClackRuntime, listClickClackAccountIds, listEnabledClickClackAccounts, parseClickClackTarget, resolveClickClackAccount, resolveDefaultClickClackAccountId, setClickClackRuntime };
@@ -1,5 +1,6 @@
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-u7Mgy8Wp.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-ktvDJmH4.js";
2
2
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-BKkzzjBA.js";
3
+ import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
3
4
  import { parseDateStringTimestampMs } from "openclaw/plugin-sdk/number-runtime";
4
5
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
5
6
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -500,7 +501,7 @@ const CLICKCLACK_MENTION_PATTERN = /(?:^|[^a-z0-9_@-])@([a-z0-9][a-z0-9_-]{1,31}
500
501
  function buildLocalMentionRegexes(params) {
501
502
  if (params.mentionPatterns.length === 0) return [];
502
503
  const cfg = params.cfg;
503
- return buildMentionRegexes({
504
+ const syntheticCfg = {
504
505
  ...cfg,
505
506
  messages: {
506
507
  ...cfg?.messages,
@@ -509,7 +510,8 @@ function buildLocalMentionRegexes(params) {
509
510
  mentionPatterns: params.mentionPatterns
510
511
  }
511
512
  }
512
- }, void 0, {
513
+ };
514
+ return buildMentionRegexes(syntheticCfg, void 0, {
513
515
  provider: "clickclack",
514
516
  conversationId: params.channelId
515
517
  });
@@ -1081,11 +1083,11 @@ function createClickClackActivityPublisher(params) {
1081
1083
  * Outbound ClickClack delivery helpers for channel messages, thread replies,
1082
1084
  * and direct messages.
1083
1085
  */
1084
- const CLICKCLACK_MAX_UPLOAD_BYTES = 64 * 1024 * 1024;
1086
+ const CLICKCLACK_MAX_UPLOAD_BYTES = 67108864;
1085
1087
  const CLICKCLACK_FORMAT_PROFILE = FormatCapabilityProfile.define({
1086
1088
  mechanism: "markdown",
1087
1089
  chunk: {
1088
- limit: 1024 * 1024,
1090
+ limit: 1048576,
1089
1091
  unit: "bytes"
1090
1092
  }
1091
1093
  });
@@ -1211,13 +1213,18 @@ async function sendClickClackMedia(params) {
1211
1213
  deliveryQueueId: params.deliveryQueueId,
1212
1214
  deliveryPartIndex: params.deliveryPartIndex
1213
1215
  });
1216
+ const { account, client } = createOutboundContext(params);
1217
+ const maxBytes = Math.min(resolveChannelMediaMaxBytes({
1218
+ cfg: params.cfg,
1219
+ accountId: account.accountId,
1220
+ resolveChannelLimitMb: () => account.config.mediaMaxMb
1221
+ }) ?? CLICKCLACK_MAX_UPLOAD_BYTES, CLICKCLACK_MAX_UPLOAD_BYTES);
1214
1222
  const preloadedMedia = nonces.upload ? void 0 : await loadOutboundMediaFromUrl(params.mediaUrl, {
1215
- maxBytes: CLICKCLACK_MAX_UPLOAD_BYTES,
1223
+ maxBytes,
1216
1224
  mediaAccess: params.mediaAccess,
1217
1225
  mediaLocalRoots: params.mediaLocalRoots,
1218
1226
  mediaReadFile: params.mediaReadFile
1219
1227
  });
1220
- const { account, client } = createOutboundContext(params);
1221
1228
  const workspaceId = await resolveWorkspaceId(client, account.workspace);
1222
1229
  const persistedUpload = nonces.upload ? await client.findUploadByNonce({
1223
1230
  workspaceId,
@@ -1228,7 +1235,7 @@ async function sendClickClackMedia(params) {
1228
1235
  let mediaFilename = preloadedMedia?.fileName?.trim();
1229
1236
  if (!upload) {
1230
1237
  const media = preloadedMedia ?? await loadOutboundMediaFromUrl(params.mediaUrl, {
1231
- maxBytes: CLICKCLACK_MAX_UPLOAD_BYTES,
1238
+ maxBytes,
1232
1239
  mediaAccess: params.mediaAccess,
1233
1240
  mediaLocalRoots: params.mediaLocalRoots,
1234
1241
  mediaReadFile: params.mediaReadFile
@@ -2197,21 +2204,22 @@ const clickClackPlugin = createChatChannelPlugin({
2197
2204
  },
2198
2205
  resolveOutboundSessionRoute: ({ cfg, agentId, accountId, target, replyToId, threadId, currentSessionKey }) => {
2199
2206
  const parsed = parseClickClackTarget(target);
2207
+ const baseRoute = buildChannelOutboundSessionRoute({
2208
+ cfg,
2209
+ agentId,
2210
+ channel: CHANNEL_ID,
2211
+ accountId,
2212
+ recipientSessionExact: parsed.kind === "dm",
2213
+ peer: {
2214
+ kind: parsed.chatType === "direct" ? "direct" : "channel",
2215
+ id: buildClickClackTarget(parsed)
2216
+ },
2217
+ chatType: parsed.chatType,
2218
+ from: `clickclack:${accountId ?? DEFAULT_ACCOUNT_ID}`,
2219
+ to: buildClickClackTarget(parsed)
2220
+ });
2200
2221
  return buildThreadAwareOutboundSessionRoute({
2201
- route: buildChannelOutboundSessionRoute({
2202
- cfg,
2203
- agentId,
2204
- channel: CHANNEL_ID,
2205
- accountId,
2206
- recipientSessionExact: parsed.kind === "dm",
2207
- peer: {
2208
- kind: parsed.chatType === "direct" ? "direct" : "channel",
2209
- id: buildClickClackTarget(parsed)
2210
- },
2211
- chatType: parsed.chatType,
2212
- from: `clickclack:${accountId ?? DEFAULT_ACCOUNT_ID}`,
2213
- to: buildClickClackTarget(parsed)
2214
- }),
2222
+ route: baseRoute,
2215
2223
  replyToId,
2216
2224
  threadId: threadId ?? (parsed.kind === "thread" ? parsed.id : void 0),
2217
2225
  currentSessionKey,
@@ -1,2 +1,2 @@
1
- import { t as clickClackPlugin } from "./channel-DbE7fnUL.js";
1
+ import { t as clickClackPlugin } from "./channel-DR3HQ51j.js";
2
2
  export { clickClackPlugin };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as registerClickClackDiscussions } from "./runtime-api-Pul_CTEN.js";
1
+ import { t as registerClickClackDiscussions } from "./runtime-api-CrR-O-0P.js";
2
2
  import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
3
3
  //#region extensions/clickclack/index.ts
4
4
  /**
@@ -1,10 +1,10 @@
1
- import { b as resolveClickClackAccount, d as isClickClackChannelNameConflict, l as ClickClackHttpError, u as createClickClackClient, v as listClickClackAccountIds } from "./setup-surface-u7Mgy8Wp.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-DbE7fnUL.js";
1
+ import { b as resolveClickClackAccount, d as isClickClackChannelNameConflict, l as ClickClackHttpError, u as createClickClackClient, v as listClickClackAccountIds } from "./setup-surface-ktvDJmH4.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-DR3HQ51j.js";
3
3
  import "./api.js";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { buildControlUiSessionPath, registerSessionDiscussionProvider } from "openclaw/plugin-sdk/session-discussion";
6
6
  import { createSessionVisibilityChecker } from "openclaw/plugin-sdk/session-visibility";
7
- import { resolveSessionAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
7
+ import { resolveSessionAgentIdStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
8
8
  import { textResult } from "openclaw/plugin-sdk/tool-results";
9
9
  //#region extensions/clickclack/src/discussions/binding-retention.ts
10
10
  var DetachedDiscussionBindingRetention = class {
@@ -257,7 +257,7 @@ async function openClickClackDiscussionBinding(params) {
257
257
  if (listPendingDiscussionOpens(runtime).some((pending) => pending.sessionKey === sessionKey)) throw new Error("A previous ClickClack discussion open is still unresolved; restore its credential and retry");
258
258
  }
259
259
  const config = runtime.config.current();
260
- const agentId = resolveSessionAgentId({
260
+ const agentId = resolveSessionAgentIdStrict({
261
261
  config,
262
262
  sessionKey
263
263
  });
@@ -338,7 +338,7 @@ async function openClickClackDiscussionBinding(params) {
338
338
  }
339
339
  break;
340
340
  } catch (error) {
341
- if (isClickClackChannelNameConflict(error) && attempt < CHANNEL_NAME_MUTATION_ATTEMPTS$1 - 1) {
341
+ if (isClickClackChannelNameConflict(error) && attempt < 3) {
342
342
  channels = await client.channels(workspace.id);
343
343
  assertManagedChannelListContract(channels);
344
344
  continue;
@@ -442,7 +442,7 @@ async function openClickClackDiscussionBinding(params) {
442
442
  assertChannelPatch(currentChannel, latestManagedFields);
443
443
  break;
444
444
  } catch (error) {
445
- if (!isClickClackChannelNameConflict(error) || attempt === CHANNEL_NAME_MUTATION_ATTEMPTS$1 - 1) throw error;
445
+ if (!isClickClackChannelNameConflict(error) || attempt === 3) throw error;
446
446
  }
447
447
  }
448
448
  } catch (error) {
@@ -736,7 +736,7 @@ var ClickClackDiscussionService = class {
736
736
  assertChannelPatch(renamed, patch);
737
737
  return renamed;
738
738
  } catch (error) {
739
- if (!isClickClackChannelNameConflict(error) || attempt === CHANNEL_NAME_MUTATION_ATTEMPTS - 1) throw error;
739
+ if (!isClickClackChannelNameConflict(error) || attempt === 3) throw error;
740
740
  }
741
741
  }
742
742
  throw new Error("ClickClack discussion channel name retries were exhausted");
@@ -1,4 +1,4 @@
1
- import { b as resolveClickClackAccount, u as createClickClackClient } from "./setup-surface-u7Mgy8Wp.js";
2
- import { a as setClickClackRuntime, r as parseClickClackTarget } from "./channel-DbE7fnUL.js";
3
- import { t as registerClickClackDiscussions } from "./runtime-api-Pul_CTEN.js";
1
+ import { b as resolveClickClackAccount, u as createClickClackClient } from "./setup-surface-ktvDJmH4.js";
2
+ import { a as setClickClackRuntime, r as parseClickClackTarget } from "./channel-DR3HQ51j.js";
3
+ import { t as registerClickClackDiscussions } from "./runtime-api-CrR-O-0P.js";
4
4
  export { createClickClackClient, parseClickClackTarget, registerClickClackDiscussions, resolveClickClackAccount, setClickClackRuntime };
@@ -1,10 +1,10 @@
1
- import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-u7Mgy8Wp.js";
1
+ import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-ktvDJmH4.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";
5
5
  //#region extensions/clickclack/src/setup-claim.ts
6
- const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
7
- const CLICKCLACK_SETUP_CODE_CLAIM_JSON_LIMIT_BYTES = 64 * 1024;
6
+ const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8192;
7
+ const CLICKCLACK_SETUP_CODE_CLAIM_JSON_LIMIT_BYTES = 65536;
8
8
  const CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS = 3e4;
9
9
  var ClickClackSetupCodeClaimError = class extends Error {
10
10
  constructor(status, detail) {
@@ -1,4 +1,4 @@
1
- import { g as clickClackMeta, h as clickClackConfigAdapter, n as clickClackSetupContract, p as clickClackConfigSchema, t as clickClackSetupWizard } from "./setup-surface-u7Mgy8Wp.js";
1
+ import { g as clickClackMeta, h as clickClackConfigAdapter, n as clickClackSetupContract, p as clickClackConfigSchema, t as clickClackSetupWizard } from "./setup-surface-ktvDJmH4.js";
2
2
  //#region extensions/clickclack/src/channel.setup.ts
3
3
  const clickClackSetupPlugin = {
4
4
  id: "clickclack",
@@ -3,14 +3,15 @@ import { DEFAULT_ACCOUNT_ID, DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normali
3
3
  import { resolveNormalizedAccountEntry } from "openclaw/plugin-sdk/account-resolution-runtime";
4
4
  import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
6
- import { resolveDefaultSecretProviderAlias } from "openclaw/plugin-sdk/provider-auth";
7
6
  import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
8
7
  import { buildSecretInputSchema, normalizeSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
8
+ import { canResolveEnvSecretRefInReadOnlyPath } from "openclaw/plugin-sdk/secret-ref-readonly";
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";
12
12
  import { z } from "zod";
13
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
14
+ import { bufferToBlobPart } from "openclaw/plugin-sdk/blob-runtime";
14
15
  import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
15
16
  import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
16
17
  import { WebSocket } from "ws";
@@ -121,11 +122,15 @@ function resolveClickClackToken(params) {
121
122
  };
122
123
  }
123
124
  if (resolved.status === "configured_unavailable" && resolved.ref.source === "env") {
124
- const providerConfig = params.cfg.secrets?.providers?.[resolved.ref.provider];
125
- if (providerConfig) {
125
+ if (!canResolveEnvSecretRefInReadOnlyPath({
126
+ cfg: params.cfg,
127
+ ...resolved.ref
128
+ })) {
129
+ const providerConfig = params.cfg.secrets?.providers?.[resolved.ref.provider];
130
+ if (!providerConfig) throw new Error(`Secret provider "${resolved.ref.provider}" is not configured (ref: env:${resolved.ref.provider}:${resolved.ref.id}).`);
126
131
  if (providerConfig.source !== "env") throw new Error(`Secret provider "${resolved.ref.provider}" has source "${providerConfig.source}" but ref requests "env".`);
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.`);
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}).`);
132
+ throw new Error(`Environment variable "${resolved.ref.id}" is not allowlisted in secrets.providers.${resolved.ref.provider}.allowlist.`);
133
+ }
129
134
  const token = normalizeSecretInputString((params.env ?? process.env)[resolved.ref.id]);
130
135
  return {
131
136
  token: token ?? "",
@@ -246,6 +251,7 @@ const ClickClackAccountConfigSchema = z.object({
246
251
  name: z.string().optional(),
247
252
  enabled: z.boolean().optional(),
248
253
  configWrites: z.boolean().optional(),
254
+ mediaMaxMb: z.number().positive().optional(),
249
255
  responsePrefix: z.string().optional(),
250
256
  baseUrl: z.string().url().optional(),
251
257
  apiBaseUrl: z.string().url().optional(),
@@ -281,11 +287,12 @@ const ClickClackAccountConfigSchema = z.object({
281
287
  section: z.string().optional()
282
288
  }).strict().optional()
283
289
  }).strict();
290
+ const ClickClackConfigSchema = buildMultiAccountChannelSchema(ClickClackAccountConfigSchema.extend({ historyLimit: z.number().int().min(0).optional() }), { accountSchema: ClickClackAccountConfigSchema.partial() });
284
291
  /**
285
292
  * Config schema exported to core so `openclaw doctor` and config validation
286
293
  * understand both default and named ClickClack accounts.
287
294
  */
288
- const clickClackConfigSchema = buildChannelConfigSchema(buildMultiAccountChannelSchema(ClickClackAccountConfigSchema.extend({ historyLimit: z.number().int().min(0).optional() }), { accountSchema: ClickClackAccountConfigSchema.partial() }));
295
+ const clickClackConfigSchema = buildChannelConfigSchema(ClickClackConfigSchema);
289
296
  //#endregion
290
297
  //#region extensions/clickclack/src/http-client.ts
291
298
  /**
@@ -304,11 +311,11 @@ function provenanceFields(provenance) {
304
311
  if (provenance?.runtime?.trim()) fields.author_runtime = provenance.runtime.trim();
305
312
  return fields;
306
313
  }
307
- const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
314
+ const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8192;
308
315
  const CLICKCLACK_CORRELATION_ID_MAX_LENGTH = 128;
309
316
  const CLICKCLACK_CORRELATION_ID_PATTERN = /^[A-Za-z0-9._:-]+$/u;
310
317
  const CLICKCLACK_CORRELATION_ID_HEADER = "X-Correlation-ID";
311
- const CLICKCLACK_INBOUND_JSON_LIMIT_BYTES = 16 * 1024 * 1024;
318
+ const CLICKCLACK_INBOUND_JSON_LIMIT_BYTES = 16777216;
312
319
  const CLICKCLACK_WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 3e4;
313
320
  const CLICKCLACK_EPHEMERAL_REQUEST_TIMEOUT_MS = 15e3;
314
321
  const CLICKCLACK_MESSAGE_PAGE_LIMIT = 200;
@@ -517,7 +524,7 @@ function createClickClackClient(options) {
517
524
  },
518
525
  createUpload: async (params) => {
519
526
  const form = new FormData();
520
- const bytes = params.buffer.buffer instanceof ArrayBuffer ? new Uint8Array(params.buffer.buffer, params.buffer.byteOffset, params.buffer.byteLength) : Uint8Array.from(params.buffer);
527
+ const bytes = bufferToBlobPart(params.buffer);
521
528
  form.append("file", new Blob([bytes], { type: params.contentType }), params.filename);
522
529
  const query = new URLSearchParams({ workspace_id: params.workspaceId });
523
530
  if (params.nonce) query.set("nonce", params.nonce);
@@ -773,13 +780,14 @@ function formatClickClackSetupCodeClaimError(error) {
773
780
  }
774
781
  function applyClickClackSetupConfigPatch(params) {
775
782
  const accountId = normalizeAccountId(params.accountId);
783
+ const scopedConfig = accountId === DEFAULT_ACCOUNT_ID ? params.cfg : moveSingleAccountChannelSectionToDefaultAccount({
784
+ cfg: params.cfg,
785
+ channelKey: channel$1,
786
+ setupSurface: clickClackSetupAdapter
787
+ });
776
788
  return patchScopedAccountConfig({
777
789
  cfg: prepareScopedSetupConfig({
778
- cfg: accountId === DEFAULT_ACCOUNT_ID ? params.cfg : moveSingleAccountChannelSectionToDefaultAccount({
779
- cfg: params.cfg,
780
- channelKey: channel$1,
781
- setupSurface: clickClackSetupAdapter
782
- }),
790
+ cfg: scopedConfig,
783
791
  channelKey: channel$1,
784
792
  accountId,
785
793
  name: params.name,
@@ -814,7 +822,7 @@ const clickClackSetupAdapter = {
814
822
  const claimUrl = setup.exactClaimUrl && !privateApiBaseUrl ? setup.exactClaimUrl : buildClickClackSetupClaimUrl(privateApiBaseUrl ?? setup.baseUrl);
815
823
  let claim;
816
824
  try {
817
- const { claimClickClackSetupCode } = await import("./setup-claim-Dd4LkDU2.js");
825
+ const { claimClickClackSetupCode } = await import("./setup-claim-Cp-qIa1w.js");
818
826
  claim = await claimClickClackSetupCode({
819
827
  claimUrl,
820
828
  code: setup.code,
@@ -24,6 +24,10 @@
24
24
  "configWrites": {
25
25
  "type": "boolean"
26
26
  },
27
+ "mediaMaxMb": {
28
+ "type": "number",
29
+ "exclusiveMinimum": 0
30
+ },
27
31
  "responsePrefix": {
28
32
  "type": "string"
29
33
  },
@@ -331,6 +335,10 @@
331
335
  "configWrites": {
332
336
  "type": "boolean"
333
337
  },
338
+ "mediaMaxMb": {
339
+ "type": "number",
340
+ "exclusiveMinimum": 0
341
+ },
334
342
  "responsePrefix": {
335
343
  "type": "string"
336
344
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/clickclack",
3
- "version": "2026.9.1-beta.1",
3
+ "version": "2026.9.1",
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.9.1-beta.1"
16
+ "openclaw": ">=2026.9.1"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -139,10 +139,10 @@
139
139
  "allowInvalidConfigRecovery": true
140
140
  },
141
141
  "compat": {
142
- "pluginApi": ">=2026.9.1-beta.1"
142
+ "pluginApi": ">=2026.9.1"
143
143
  },
144
144
  "build": {
145
- "openclawVersion": "2026.9.1-beta.1",
145
+ "openclawVersion": "2026.9.1",
146
146
  "bundledDist": false
147
147
  },
148
148
  "release": {