@openclaw/nextcloud-talk 2026.7.2-beta.1 → 2026.7.2-beta.2

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,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./channel-CYse6FwT.js";
1
+ import { t as nextcloudTalkPlugin } from "./channel-BSnehBf6.js";
2
2
  export { nextcloudTalkPlugin };
@@ -17,22 +17,20 @@ import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openc
17
17
  import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
18
18
  import { createAccountStatusSink, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
19
19
  import { ssrfPolicyFromPrivateNetworkOptIn, ssrfPolicyFromPrivateNetworkOptIn as ssrfPolicyFromPrivateNetworkOptIn$1 } from "openclaw/plugin-sdk/ssrf-runtime";
20
- import { readFileSync } from "node:fs";
21
20
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
22
21
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
23
22
  import { createHmac, randomBytes } from "node:crypto";
24
- import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
23
+ import { fileExists, safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
25
24
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/channel-plugin-common";
26
25
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2 } from "openclaw/plugin-sdk/account-id";
27
- import { DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ReplyRuntimeConfigSchemaShape, ToolPolicySchema, buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
26
+ import { DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ReplyRuntimeConfigSchemaShape, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
28
27
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
29
28
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
30
29
  import { requireChannelOpenAllowFrom, resolveLoggerBackedRuntime, runStoppablePassiveMonitor, safeParseJsonWithSchema } from "openclaw/plugin-sdk/extension-shared";
31
30
  import { z } from "zod";
32
- import fs from "node:fs/promises";
33
31
  import os from "node:os";
34
32
  import path from "node:path";
35
- import { createClaimableDedupe, migratePersistentDedupeLegacyJsonFile } from "openclaw/plugin-sdk/persistent-dedupe";
33
+ import { createChannelReplayGuard, migratePersistentDedupeLegacyJsonFile } from "openclaw/plugin-sdk/persistent-dedupe";
36
34
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
37
35
  import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
38
36
  import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
@@ -43,7 +41,7 @@ import { createServer } from "node:http";
43
41
  import { WEBHOOK_RATE_LIMIT_DEFAULTS, createAuthRateLimiter, isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-ingress";
44
42
  import { jsonResult, readStringParam, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
45
43
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, buildOutboundBaseSessionKey, normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
46
- import { applyAccountNameToChannelSection, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
44
+ import { applyAccountNameToChannelSection, baseUrlTextInput, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
47
45
  import { createSetupInputPresenceValidator, createSetupTranslator as createSetupTranslator$1, mergeAllowFromEntries, promptParsedAllowFromForAccount, resolveSetupAccountId } from "openclaw/plugin-sdk/setup-runtime";
48
46
  import { formatDocsLink as formatDocsLink$1 } from "openclaw/plugin-sdk/setup-tools";
49
47
  //#region extensions/nextcloud-talk/src/accounts.ts
@@ -166,10 +164,10 @@ function resolveNextcloudTalkApiCredentials(params) {
166
164
  };
167
165
  if (!params.apiPasswordFile) return;
168
166
  try {
169
- const filePassword = readFileSync(params.apiPasswordFile, "utf-8").trim();
170
- return filePassword ? {
167
+ const fileValue = tryReadSecretFileSync(params.apiPasswordFile, "Nextcloud Talk API password", { rejectHardlinks: false });
168
+ return fileValue ? {
171
169
  apiUser,
172
- apiPassword: filePassword
170
+ apiPassword: fileValue
173
171
  } : void 0;
174
172
  } catch {
175
173
  return;
@@ -362,18 +360,11 @@ const nextcloudTalkPairingTextAdapter = {
362
360
  };
363
361
  //#endregion
364
362
  //#region extensions/nextcloud-talk/src/config-schema.ts
365
- const NextcloudTalkRoomSchema = z.object({
366
- requireMention: z.boolean().optional(),
367
- tools: ToolPolicySchema,
368
- skills: z.array(z.string()).optional(),
369
- enabled: z.boolean().optional(),
370
- allowFrom: z.array(z.string()).optional(),
371
- systemPrompt: z.string().optional()
372
- }).strict();
363
+ const NextcloudTalkRoomSchema = buildGroupEntrySchema({ allowFrom: z.array(z.string()).optional() }).omit({ toolsBySender: true });
373
364
  const NextcloudTalkNetworkSchema = z.object({
374
365
  /** Dangerous opt-in for self-hosted Nextcloud Talk on trusted private/internal hosts. */
375
366
  dangerouslyAllowPrivateNetwork: z.boolean().optional() }).strict().optional();
376
- const NextcloudTalkAccountSchemaBase = z.object({
367
+ const NextcloudTalkConfigSchema = buildMultiAccountChannelSchema(z.object({
377
368
  name: z.string().optional(),
378
369
  enabled: z.boolean().optional(),
379
370
  markdown: MarkdownConfigSchema,
@@ -395,27 +386,17 @@ const NextcloudTalkAccountSchemaBase = z.object({
395
386
  /** Network policy overrides for self-hosted Nextcloud Talk on trusted private/internal hosts. */
396
387
  network: NextcloudTalkNetworkSchema,
397
388
  ...ReplyRuntimeConfigSchemaShape
398
- }).strict();
399
- const NextcloudTalkAccountSchema = NextcloudTalkAccountSchemaBase.superRefine((value, ctx) => {
400
- requireChannelOpenAllowFrom({
401
- channel: "nextcloud-talk",
402
- policy: value.dmPolicy,
403
- allowFrom: value.allowFrom,
404
- ctx,
405
- requireOpenAllowFrom
406
- });
407
- });
408
- const NextcloudTalkConfigSchema = NextcloudTalkAccountSchemaBase.extend({
409
- accounts: z.record(z.string(), NextcloudTalkAccountSchema.optional()).optional(),
410
- defaultAccount: z.string().optional()
411
- }).superRefine((value, ctx) => {
412
- requireChannelOpenAllowFrom({
413
- channel: "nextcloud-talk",
414
- policy: value.dmPolicy,
415
- allowFrom: value.allowFrom,
416
- ctx,
417
- requireOpenAllowFrom
418
- });
389
+ }).strict(), {
390
+ optionalAccount: true,
391
+ refine: (value, ctx) => {
392
+ requireChannelOpenAllowFrom({
393
+ channel: "nextcloud-talk",
394
+ policy: value.dmPolicy,
395
+ allowFrom: value.allowFrom,
396
+ ctx,
397
+ requireOpenAllowFrom
398
+ });
399
+ }
419
400
  });
420
401
  //#endregion
421
402
  //#region extensions/nextcloud-talk/src/replay-guard.ts
@@ -424,7 +405,7 @@ const NEXTCLOUD_TALK_REPLAY_DEDUPE_NAMESPACE_PREFIX = "replay-dedupe";
424
405
  const DEFAULT_REPLAY_TTL_MS = 1440 * 60 * 1e3;
425
406
  const DEFAULT_MEMORY_MAX_SIZE = 1e3;
426
407
  const DEFAULT_STATE_MAX_ENTRIES = 1e4;
427
- function buildReplayKey(params) {
408
+ function buildNextcloudTalkReplayKey(params) {
428
409
  const roomToken = params.roomToken.trim();
429
410
  const messageId = params.messageId.trim();
430
411
  if (!roomToken || !messageId) return null;
@@ -436,55 +417,21 @@ function createNextcloudTalkReplayGuard(options) {
436
417
  ttlMs: options.ttlMs ?? DEFAULT_REPLAY_TTL_MS,
437
418
  memoryMaxSize: options.memoryMaxSize ?? DEFAULT_MEMORY_MAX_SIZE
438
419
  };
439
- const dedupe = createClaimableDedupe(stateDir ? {
440
- ...baseOptions,
441
- pluginId: NEXTCLOUD_TALK_PLUGIN_ID,
442
- namespacePrefix: NEXTCLOUD_TALK_REPLAY_DEDUPE_NAMESPACE_PREFIX,
443
- stateMaxEntries: options.stateMaxEntries ?? options.fileMaxEntries ?? DEFAULT_STATE_MAX_ENTRIES,
444
- env: {
445
- ...process.env,
446
- OPENCLAW_STATE_DIR: stateDir
447
- },
448
- onDiskError: options.onDiskError
449
- } : baseOptions);
450
- return {
451
- claimMessage: async ({ accountId, roomToken, messageId }) => {
452
- const replayKey = buildReplayKey({
453
- roomToken,
454
- messageId
455
- });
456
- if (!replayKey) return "invalid";
457
- return (await dedupe.claim(replayKey, { namespace: accountId })).kind;
458
- },
459
- commitMessage: async ({ accountId, roomToken, messageId }) => {
460
- const replayKey = buildReplayKey({
461
- roomToken,
462
- messageId
463
- });
464
- if (!replayKey) return true;
465
- return await dedupe.commit(replayKey, { namespace: accountId });
466
- },
467
- releaseMessage: ({ accountId, roomToken, messageId, error }) => {
468
- const replayKey = buildReplayKey({
469
- roomToken,
470
- messageId
471
- });
472
- if (!replayKey) return;
473
- dedupe.release(replayKey, {
474
- namespace: accountId,
475
- error
476
- });
477
- },
478
- shouldProcessMessage: async ({ accountId, roomToken, messageId }) => {
479
- const replayKey = buildReplayKey({
480
- roomToken,
481
- messageId
482
- });
483
- if (!replayKey) return true;
484
- if ((await dedupe.claim(replayKey, { namespace: accountId })).kind !== "claimed") return false;
485
- return await dedupe.commit(replayKey, { namespace: accountId });
486
- }
487
- };
420
+ return createChannelReplayGuard({
421
+ dedupe: stateDir ? {
422
+ ...baseOptions,
423
+ pluginId: NEXTCLOUD_TALK_PLUGIN_ID,
424
+ namespacePrefix: NEXTCLOUD_TALK_REPLAY_DEDUPE_NAMESPACE_PREFIX,
425
+ stateMaxEntries: options.stateMaxEntries ?? options.fileMaxEntries ?? DEFAULT_STATE_MAX_ENTRIES,
426
+ env: {
427
+ ...process.env,
428
+ OPENCLAW_STATE_DIR: stateDir
429
+ },
430
+ onDiskError: options.onDiskError
431
+ } : baseOptions,
432
+ buildReplayKey: buildNextcloudTalkReplayKey,
433
+ namespace: (event) => event.accountId
434
+ });
488
435
  }
489
436
  //#endregion
490
437
  //#region extensions/nextcloud-talk/src/doctor.ts
@@ -495,14 +442,6 @@ function sanitizeLegacyReplaySegment(value) {
495
442
  if (!trimmed) return "default";
496
443
  return trimmed.replace(/[^a-zA-Z0-9_-]/g, "_");
497
444
  }
498
- async function fileExists(filePath) {
499
- try {
500
- await fs.access(filePath);
501
- return true;
502
- } catch {
503
- return false;
504
- }
505
- }
506
445
  async function collectNextcloudTalkBotResponseWarnings(params) {
507
446
  const warnings = [];
508
447
  for (const accountId of listNextcloudTalkAccountIds(params.cfg)) {
@@ -527,7 +466,7 @@ async function repairNextcloudTalkReplayDedupeState(params) {
527
466
  const replayDir = path.join(stateDir, "nextcloud-talk", "replay-dedupe");
528
467
  for (const accountId of listNextcloudTalkAccountIds(params.cfg)) {
529
468
  const legacyPath = path.join(replayDir, `${sanitizeLegacyReplaySegment(accountId)}.json`);
530
- if (!await fileExists(legacyPath)) continue;
469
+ if (!fileExists(legacyPath)) continue;
531
470
  try {
532
471
  const result = await migratePersistentDedupeLegacyJsonFile({
533
472
  filePath: legacyPath,
@@ -1263,40 +1202,12 @@ const WEBHOOK_ERRORS = {
1263
1202
  payloadTooLarge: "Payload too large",
1264
1203
  internalServerError: "Internal server error"
1265
1204
  };
1266
- var NextcloudTalkRetryableWebhookError = class extends Error {
1267
- constructor(message, options) {
1268
- super(message, options);
1269
- this.name = "NextcloudTalkRetryableWebhookError";
1270
- }
1271
- };
1272
1205
  async function processNextcloudTalkReplayGuardedMessage(params) {
1273
- if (await params.replayGuard.claimMessage({
1206
+ return (await params.replayGuard.processGuarded({
1274
1207
  accountId: params.accountId,
1275
1208
  roomToken: params.message.roomToken,
1276
1209
  messageId: params.message.messageId
1277
- }) !== "claimed") return "duplicate";
1278
- try {
1279
- await params.handleMessage();
1280
- await params.replayGuard.commitMessage({
1281
- accountId: params.accountId,
1282
- roomToken: params.message.roomToken,
1283
- messageId: params.message.messageId
1284
- });
1285
- return "processed";
1286
- } catch (error) {
1287
- if (error instanceof NextcloudTalkRetryableWebhookError) params.replayGuard.releaseMessage({
1288
- accountId: params.accountId,
1289
- roomToken: params.message.roomToken,
1290
- messageId: params.message.messageId,
1291
- error
1292
- });
1293
- else await params.replayGuard.commitMessage({
1294
- accountId: params.accountId,
1295
- roomToken: params.message.roomToken,
1296
- messageId: params.message.messageId
1297
- });
1298
- throw error;
1299
- }
1210
+ }, params.handleMessage, { onError: "commit" })).kind === "processed" ? "processed" : "duplicate";
1300
1211
  }
1301
1212
  function formatError(err) {
1302
1213
  if (err instanceof Error) return err.message;
@@ -1959,8 +1870,10 @@ const nextcloudTalkSetupWizard = {
1959
1870
  [CONFIGURE_API_FLAG]: "1"
1960
1871
  } };
1961
1872
  },
1962
- credentials: [{
1873
+ credentials: [defineTokenCredential({
1963
1874
  inputKey: "token",
1875
+ configKey: "botSecret",
1876
+ configuredFields: ["botSecret", "botSecretFile"],
1964
1877
  providerHint: channel,
1965
1878
  credentialLabel: t("wizard.nextcloudTalk.botSecret"),
1966
1879
  preferredEnvVar: "NEXTCLOUD_TALK_BOT_SECRET",
@@ -1968,61 +1881,56 @@ const nextcloudTalkSetupWizard = {
1968
1881
  keepPrompt: t("wizard.nextcloudTalk.botSecretKeep"),
1969
1882
  inputPrompt: t("wizard.nextcloudTalk.botSecretInput"),
1970
1883
  allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID$1,
1971
- inspect: ({ cfg, accountId }) => {
1972
- const resolvedAccount = resolveNextcloudTalkAccount({
1973
- cfg,
1974
- accountId
1975
- });
1976
- return {
1977
- accountConfigured: Boolean(resolvedAccount.secret && resolvedAccount.baseUrl),
1978
- hasConfiguredValue: Boolean(hasConfiguredSecretInput(resolvedAccount.config.botSecret) || resolvedAccount.config.botSecretFile),
1979
- resolvedValue: resolvedAccount.secret || void 0,
1980
- envValue: accountId === DEFAULT_ACCOUNT_ID$1 ? normalizeOptionalString(process.env.NEXTCLOUD_TALK_BOT_SECRET) : void 0
1981
- };
1884
+ resolveAccount: ({ cfg, accountId }) => resolveNextcloudTalkAccount({
1885
+ cfg,
1886
+ accountId
1887
+ }),
1888
+ accountConfigured: (account) => Boolean(account.secret && account.baseUrl),
1889
+ hasConfiguredValue: (account) => Boolean(hasConfiguredSecretInput(account.config.botSecret) || account.config.botSecretFile),
1890
+ resolvedValue: (account) => account.secret || void 0,
1891
+ envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID$1 ? normalizeOptionalString(process.env.NEXTCLOUD_TALK_BOT_SECRET) : void 0,
1892
+ patchAccount: ({ cfg, accountId, patch, clearFields }) => {
1893
+ return setNextcloudTalkAccountConfig(clearNextcloudTalkAccountFields(cfg, accountId, clearFields), accountId, patch);
1982
1894
  },
1983
- applyUseEnv: async (params) => {
1984
- const resolvedAccount = resolveNextcloudTalkAccount({
1985
- cfg: params.cfg,
1986
- accountId: params.accountId
1987
- });
1988
- return setNextcloudTalkAccountConfig(clearNextcloudTalkAccountFields(params.cfg, params.accountId, ["botSecret", "botSecretFile"]), params.accountId, { baseUrl: resolvedAccount.baseUrl });
1895
+ useEnv: {
1896
+ clearFields: ["botSecret", "botSecretFile"],
1897
+ patch: (account) => ({ baseUrl: account.baseUrl })
1989
1898
  },
1990
- applySet: async (params) => setNextcloudTalkAccountConfig(clearNextcloudTalkAccountFields(params.cfg, params.accountId, ["botSecret", "botSecretFile"]), params.accountId, { botSecret: params.value })
1991
- }, {
1899
+ set: { clearFields: ["botSecret", "botSecretFile"] }
1900
+ }), defineTokenCredential({
1992
1901
  inputKey: "password",
1902
+ configKey: "apiPassword",
1903
+ configuredFields: ["apiPassword", "apiPasswordFile"],
1993
1904
  providerHint: "nextcloud-talk-api",
1994
1905
  credentialLabel: t("wizard.nextcloudTalk.apiPassword"),
1995
1906
  preferredEnvVar: "NEXTCLOUD_TALK_API_PASSWORD",
1996
1907
  envPrompt: "",
1997
1908
  keepPrompt: t("wizard.nextcloudTalk.apiPasswordKeep"),
1998
1909
  inputPrompt: t("wizard.nextcloudTalk.apiPasswordInput"),
1999
- inspect: ({ cfg, accountId }) => {
2000
- const resolvedAccount = resolveNextcloudTalkAccount({
2001
- cfg,
2002
- accountId
2003
- });
2004
- const apiUser = resolvedAccount.config.apiUser?.trim();
2005
- const apiPasswordConfigured = Boolean(hasConfiguredSecretInput(resolvedAccount.config.apiPassword) || resolvedAccount.config.apiPasswordFile);
2006
- return {
2007
- accountConfigured: Boolean(apiUser && apiPasswordConfigured),
2008
- hasConfiguredValue: apiPasswordConfigured
2009
- };
2010
- },
1910
+ resolveAccount: ({ cfg, accountId }) => resolveNextcloudTalkAccount({
1911
+ cfg,
1912
+ accountId
1913
+ }),
1914
+ accountConfigured: (account) => Boolean(account.config.apiUser?.trim() && (hasConfiguredSecretInput(account.config.apiPassword) || account.config.apiPasswordFile)),
1915
+ hasConfiguredValue: (account) => Boolean(hasConfiguredSecretInput(account.config.apiPassword) || account.config.apiPasswordFile),
2011
1916
  shouldPrompt: ({ credentialValues }) => credentialValues[CONFIGURE_API_FLAG] === "1",
2012
- applySet: async (params) => setNextcloudTalkAccountConfig(clearNextcloudTalkAccountFields(params.cfg, params.accountId, ["apiPassword", "apiPasswordFile"]), params.accountId, { apiPassword: params.value })
2013
- }],
2014
- textInputs: [{
1917
+ patchAccount: ({ cfg, accountId, patch, clearFields }) => setNextcloudTalkAccountConfig(clearNextcloudTalkAccountFields(cfg, accountId, clearFields), accountId, patch),
1918
+ set: { clearFields: ["apiPassword", "apiPasswordFile"] }
1919
+ })],
1920
+ textInputs: [baseUrlTextInput({
2015
1921
  inputKey: "httpUrl",
1922
+ configKey: "baseUrl",
2016
1923
  message: t("wizard.nextcloudTalk.instanceUrlPrompt"),
2017
- currentValue: ({ cfg, accountId }) => resolveNextcloudTalkAccount({
1924
+ resolveAccount: ({ cfg, accountId }) => resolveNextcloudTalkAccount({
2018
1925
  cfg,
2019
1926
  accountId
2020
- }).baseUrl || void 0,
1927
+ }),
1928
+ currentValue: (account) => account.baseUrl || void 0,
2021
1929
  shouldPrompt: ({ currentValue }) => !currentValue,
2022
- validate: ({ value }) => validateNextcloudTalkBaseUrl(value),
2023
- normalizeValue: ({ value }) => normalizeNextcloudTalkBaseUrl(value),
2024
- applySet: async (params) => setNextcloudTalkAccountConfig(params.cfg, params.accountId, { baseUrl: params.value })
2025
- }, {
1930
+ validate: validateNextcloudTalkBaseUrl,
1931
+ normalize: normalizeNextcloudTalkBaseUrl,
1932
+ patchAccount: ({ cfg, accountId, patch }) => setNextcloudTalkAccountConfig(cfg, accountId, patch)
1933
+ }), {
2026
1934
  inputKey: "userId",
2027
1935
  message: t("wizard.nextcloudTalk.apiUserPrompt"),
2028
1936
  currentValue: ({ cfg, accountId }) => resolveNextcloudTalkAccount({
@@ -1,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./channel-CYse6FwT.js";
1
+ import { t as nextcloudTalkPlugin } from "./channel-BSnehBf6.js";
2
2
  export { nextcloudTalkPlugin };
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@openclaw/nextcloud-talk",
3
- "version": "2026.7.2-beta.1",
3
+ "version": "2026.7.2-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/nextcloud-talk",
9
- "version": "2026.7.2-beta.1",
9
+ "version": "2026.7.2-beta.2",
10
10
  "dependencies": {
11
11
  "zod": "4.4.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "openclaw": ">=2026.7.2-beta.1"
14
+ "openclaw": ">=2026.7.2-beta.2"
15
15
  },
16
16
  "peerDependenciesMeta": {
17
17
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/nextcloud-talk",
3
- "version": "2026.7.2-beta.1",
3
+ "version": "2026.7.2-beta.2",
4
4
  "description": "OpenClaw Nextcloud Talk channel plugin for conversations.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "peerDependencies": {
11
- "openclaw": ">=2026.7.2-beta.1"
11
+ "openclaw": ">=2026.7.2-beta.2"
12
12
  },
13
13
  "peerDependenciesMeta": {
14
14
  "openclaw": {
@@ -40,10 +40,10 @@
40
40
  "minHostVersion": ">=2026.4.10"
41
41
  },
42
42
  "compat": {
43
- "pluginApi": ">=2026.7.2-beta.1"
43
+ "pluginApi": ">=2026.7.2-beta.2"
44
44
  },
45
45
  "build": {
46
- "openclawVersion": "2026.7.2-beta.1"
46
+ "openclawVersion": "2026.7.2-beta.2"
47
47
  },
48
48
  "release": {
49
49
  "publishToClawHub": true,