@openclaw/clickclack 2026.9.6 → 2026.9.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.
- package/assets/icon.png +0 -0
- package/dist/.setup/{channel-CT4CVd4d.mjs → channel-Bcwtohk7.mjs} +162 -134
- package/dist/.setup/resolve-BHGLohni.mjs +336 -0
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{runtime-api-A9r1b12d.mjs → runtime-api-BvP8DrPQ.mjs} +8 -5
- package/dist/.setup/{setup-claim-t5SbtvZy.mjs → setup-claim-Cx8knvXs.mjs} +1 -1
- package/dist/.setup/setup-plugin-api-BH_nw-AP.mjs +2 -0
- package/dist/.setup/{setup-plugin-api-BUwBPYpy.mjs → setup-plugin-api-C9QcBJuW.mjs} +1 -1
- package/dist/.setup/{setup-surface-BBl3rvVx.mjs → setup-surface-BW1Q06w5.mjs} +50 -503
- package/dist/.setup/setup-verify-Msgd70_M.mjs +111 -0
- package/dist/api.js +3 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +160 -3
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +4 -3
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/openclaw.plugin.json +31 -1
- package/package.json +4 -4
- package/dist/.setup/setup-plugin-api-B19mjQvl.mjs +0 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { h as resolveClickClackAccount } from "./setup-surface-BW1Q06w5.mjs";
|
|
2
|
+
import { i as createClickClackClient, n as resolveWorkspaceId } from "./resolve-BHGLohni.mjs";
|
|
3
|
+
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
4
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
|
+
import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/setup";
|
|
6
|
+
//#region extensions/clickclack/src/setup-verify.ts
|
|
7
|
+
const GATEWAY_RUNNING_MESSAGE = "OpenClaw is running — ClickClack will connect automatically.";
|
|
8
|
+
const GATEWAY_NOT_RUNNING_MESSAGE = "Start OpenClaw to connect: openclaw gateway";
|
|
9
|
+
const GATEWAY_UNKNOWN_MESSAGE = "If OpenClaw is running it connects automatically; otherwise start it with: openclaw gateway";
|
|
10
|
+
function isHttpStatus(error, status) {
|
|
11
|
+
return typeof error === "object" && error !== null && "status" in error && error.status === status;
|
|
12
|
+
}
|
|
13
|
+
function isWorkspaceNotFound(error) {
|
|
14
|
+
return error instanceof Error && error.message.startsWith("ClickClack workspace not found:");
|
|
15
|
+
}
|
|
16
|
+
function usesUnavailableImplicitEnvToken(account, tokenOverride) {
|
|
17
|
+
return account.accountId === DEFAULT_ACCOUNT_ID && Boolean(account.baseUrl && account.workspace) && !tokenOverride && !account.token && !hasConfiguredSecretInput(account.config.token) && !account.config.tokenFile?.trim();
|
|
18
|
+
}
|
|
19
|
+
async function checkClickClackSetupConnection(params) {
|
|
20
|
+
let workspaceInput = "";
|
|
21
|
+
try {
|
|
22
|
+
const account = resolveClickClackAccount({
|
|
23
|
+
cfg: params.cfg,
|
|
24
|
+
accountId: params.accountId
|
|
25
|
+
});
|
|
26
|
+
workspaceInput = account.workspace;
|
|
27
|
+
const token = params.token?.trim() || account.token;
|
|
28
|
+
if (usesUnavailableImplicitEnvToken(account, token)) return { status: "skipped-env-token" };
|
|
29
|
+
if (!account.baseUrl || !account.workspace || !token) return { status: "skipped-unconfigured" };
|
|
30
|
+
const client = createClickClackClient({
|
|
31
|
+
baseUrl: account.apiEndpoint,
|
|
32
|
+
token
|
|
33
|
+
});
|
|
34
|
+
const me = await client.me();
|
|
35
|
+
const workspaceId = await resolveWorkspaceId(client, account.workspace);
|
|
36
|
+
const workspace = (await client.workspaces()).find((candidate) => candidate.id === workspaceId);
|
|
37
|
+
if (!workspace) throw new Error(`ClickClack workspace not found: ${account.workspace}`);
|
|
38
|
+
return {
|
|
39
|
+
status: "connected",
|
|
40
|
+
handle: me.handle,
|
|
41
|
+
workspaceName: workspace.name
|
|
42
|
+
};
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (isHttpStatus(error, 401)) return { status: "invalid-token" };
|
|
45
|
+
if (isWorkspaceNotFound(error)) return {
|
|
46
|
+
status: "workspace-not-found",
|
|
47
|
+
workspace: workspaceInput
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
status: "failed",
|
|
51
|
+
error: formatErrorMessage(error)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isGatewayNotRunningError(error) {
|
|
56
|
+
if (typeof error === "object" && error !== null && "name" in error && "kind" in error && "code" in error && error.name === "GatewayTransportError" && error.kind === "closed" && error.code === 1006) return true;
|
|
57
|
+
const message = formatErrorMessage(error).toLowerCase();
|
|
58
|
+
return message.includes("econnrefused") || message.includes("connection refused");
|
|
59
|
+
}
|
|
60
|
+
async function probeClickClackGatewayStatus() {
|
|
61
|
+
try {
|
|
62
|
+
const { callGatewayFromCli } = await import("openclaw/plugin-sdk/gateway-runtime");
|
|
63
|
+
await callGatewayFromCli("health", {
|
|
64
|
+
timeout: "1000",
|
|
65
|
+
json: true
|
|
66
|
+
}, void 0, {
|
|
67
|
+
expectFinal: false,
|
|
68
|
+
progress: false
|
|
69
|
+
});
|
|
70
|
+
return "running";
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return isGatewayNotRunningError(error) ? "not-running" : "unavailable";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function formatClickClackConnectionLog(result) {
|
|
76
|
+
switch (result.status) {
|
|
77
|
+
case "connected": return `Connected as @${result.handle} — workspace ${result.workspaceName} resolved.`;
|
|
78
|
+
case "invalid-token": return "ClickClack rejected the bot token (401). Copy a current token and rerun setup.";
|
|
79
|
+
case "workspace-not-found": return `Workspace "${result.workspace}" was not found. Check the id, slug, or name, list available workspaces, and rerun setup.`;
|
|
80
|
+
case "failed": return `Connection check failed: ${result.error}. Setup was saved; fix the connection and rerun setup.`;
|
|
81
|
+
case "skipped-env-token": return "Token comes from CLICKCLACK_BOT_TOKEN; verification skipped.";
|
|
82
|
+
case "skipped-unconfigured": return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function formatClickClackGatewayLog(status) {
|
|
86
|
+
switch (status) {
|
|
87
|
+
case "running": return GATEWAY_RUNNING_MESSAGE;
|
|
88
|
+
case "not-running": return GATEWAY_NOT_RUNNING_MESSAGE;
|
|
89
|
+
case "unavailable": return GATEWAY_UNKNOWN_MESSAGE;
|
|
90
|
+
}
|
|
91
|
+
return GATEWAY_UNKNOWN_MESSAGE;
|
|
92
|
+
}
|
|
93
|
+
async function verifyClickClackAccountAfterSetup(params) {
|
|
94
|
+
try {
|
|
95
|
+
const message = formatClickClackConnectionLog(await checkClickClackSetupConnection({
|
|
96
|
+
cfg: params.cfg,
|
|
97
|
+
accountId: params.accountId
|
|
98
|
+
}));
|
|
99
|
+
if (message) params.runtime.log(message);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
params.runtime.log(`Connection check failed: ${formatErrorMessage(error)}. Setup was saved; fix the connection and rerun setup.`);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const status = await probeClickClackGatewayStatus();
|
|
105
|
+
params.runtime.log(formatClickClackGatewayLog(status));
|
|
106
|
+
} catch {
|
|
107
|
+
params.runtime.log(GATEWAY_UNKNOWN_MESSAGE);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { checkClickClackSetupConnection, verifyClickClackAccountAfterSetup };
|
package/dist/api.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./.setup/channel-
|
|
1
|
+
import { _ as resolveDefaultClickClackAccountId, d as DEFAULT_ACCOUNT_ID, h as resolveClickClackAccount, m as listEnabledClickClackAccounts, p as listClickClackAccountIds, s as clickClackConfigSchema } from "./.setup/setup-surface-BW1Q06w5.mjs";
|
|
2
|
+
import { a as setClickClackRuntime, i as getClickClackRuntime, n as buildClickClackTarget, r as parseClickClackTarget, t as clickClackPlugin } from "./.setup/channel-Bcwtohk7.mjs";
|
|
3
|
+
import { i as createClickClackClient } from "./.setup/resolve-BHGLohni.mjs";
|
|
3
4
|
export { DEFAULT_ACCOUNT_ID, buildClickClackTarget, clickClackConfigSchema, clickClackPlugin, createClickClackClient, getClickClackRuntime, listClickClackAccountIds, listEnabledClickClackAccounts, parseClickClackTarget, resolveClickClackAccount, resolveDefaultClickClackAccountId, setClickClackRuntime };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as clickClackPlugin } from "./.setup/channel-
|
|
1
|
+
import { t as clickClackPlugin } from "./.setup/channel-Bcwtohk7.mjs";
|
|
2
2
|
export { clickClackPlugin };
|
|
@@ -1,7 +1,164 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as __reExport, t as __exportAll } from "./.setup/rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
+
//#region packages/normalization-core/src/record-coerce.ts
|
|
3
|
+
/** Type guard for non-array object records at browser-safe boundaries. */
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
/** Returns a non-array record or null. */
|
|
8
|
+
function asNullableRecord(value) {
|
|
9
|
+
return isRecord(value) ? value : null;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/config/channel-config-normalization.ts
|
|
13
|
+
/** Applies one channel-specific doctor migration to every object-shaped account. */
|
|
14
|
+
function normalizeChannelAccounts(params) {
|
|
15
|
+
const rawAccounts = asNullableRecord(params.entry.accounts);
|
|
16
|
+
if (!rawAccounts) return {
|
|
17
|
+
entry: params.entry,
|
|
18
|
+
changed: false
|
|
19
|
+
};
|
|
20
|
+
let changed = false;
|
|
21
|
+
const accounts = { ...rawAccounts };
|
|
22
|
+
for (const [accountId, value] of Object.entries(rawAccounts)) {
|
|
23
|
+
const account = asNullableRecord(value);
|
|
24
|
+
if (!account) continue;
|
|
25
|
+
const normalized = params.normalizeAccount({
|
|
26
|
+
account,
|
|
27
|
+
accountId,
|
|
28
|
+
pathPrefix: `${params.pathPrefix}.accounts.${accountId}`,
|
|
29
|
+
changes: params.changes
|
|
30
|
+
});
|
|
31
|
+
if (normalized.changed) {
|
|
32
|
+
accounts[accountId] = normalized.entry;
|
|
33
|
+
changed = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return changed ? {
|
|
37
|
+
entry: {
|
|
38
|
+
...params.entry,
|
|
39
|
+
accounts
|
|
40
|
+
},
|
|
41
|
+
changed: true
|
|
42
|
+
} : {
|
|
43
|
+
entry: params.entry,
|
|
44
|
+
changed: false
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Applies the same channel-specific doctor migration at root and account scope. */
|
|
48
|
+
function normalizeChannelConfigEntries(params) {
|
|
49
|
+
const changes = params.changes ?? [];
|
|
50
|
+
const channels = params.cfg.channels;
|
|
51
|
+
const entry = asNullableRecord(channels?.[params.channelId]);
|
|
52
|
+
if (!entry) return {
|
|
53
|
+
config: params.cfg,
|
|
54
|
+
changes
|
|
55
|
+
};
|
|
56
|
+
const channelPath = `channels.${params.channelId}`;
|
|
57
|
+
const root = params.normalizeEntry({
|
|
58
|
+
entry,
|
|
59
|
+
pathPrefix: channelPath,
|
|
60
|
+
changes
|
|
61
|
+
});
|
|
62
|
+
const accounts = normalizeChannelAccounts({
|
|
63
|
+
entry: root.entry,
|
|
64
|
+
pathPrefix: channelPath,
|
|
65
|
+
changes,
|
|
66
|
+
normalizeAccount: (accountParams) => params.normalizeEntry({
|
|
67
|
+
entry: accountParams.account,
|
|
68
|
+
accountId: accountParams.accountId,
|
|
69
|
+
pathPrefix: accountParams.pathPrefix,
|
|
70
|
+
changes: accountParams.changes
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
if (!root.changed && !accounts.changed) return {
|
|
74
|
+
config: params.cfg,
|
|
75
|
+
changes
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
config: {
|
|
79
|
+
...params.cfg,
|
|
80
|
+
channels: {
|
|
81
|
+
...channels,
|
|
82
|
+
[params.channelId]: accounts.entry
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
changes
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/plugin-sdk/legacy-webhook-listener-migration.ts
|
|
90
|
+
/** Preserve explicitly configured webhook listeners while moving ingress onto Gateway routes. */
|
|
91
|
+
function createLegacyWebhookListenerDoctorContract(params) {
|
|
92
|
+
const portKey = params.portKey ?? "webhookPort";
|
|
93
|
+
const hostKey = params.hostKey === void 0 ? "webhookHost" : params.hostKey;
|
|
94
|
+
const source = (entry) => params.webhookKey ? asNullableRecord(entry[params.webhookKey]) : entry;
|
|
95
|
+
const hasLegacy = (value) => {
|
|
96
|
+
const entry = asNullableRecord(value);
|
|
97
|
+
const listener = entry && source(entry);
|
|
98
|
+
return Boolean(listener && (Object.hasOwn(listener, portKey) || hostKey && Object.hasOwn(listener, hostKey)));
|
|
99
|
+
};
|
|
100
|
+
const prefix = `channels.${params.channelKey}`;
|
|
101
|
+
return {
|
|
102
|
+
legacyConfigRules: [{
|
|
103
|
+
path: ["channels", params.channelKey],
|
|
104
|
+
message: `${prefix} webhook listeners moved to Gateway routes. Run "openclaw doctor --fix" to preserve explicitly configured listener settings as legacyWebhook.`,
|
|
105
|
+
match: (value) => {
|
|
106
|
+
const accounts = asNullableRecord(asNullableRecord(value)?.accounts);
|
|
107
|
+
return hasLegacy(value) || Object.values(accounts ?? {}).some(hasLegacy);
|
|
108
|
+
}
|
|
109
|
+
}],
|
|
110
|
+
normalizeCompatibilityConfig: ({ cfg }) => {
|
|
111
|
+
const root = asNullableRecord(asNullableRecord(cfg.channels)?.[params.channelKey]);
|
|
112
|
+
const inherited = root && source(root);
|
|
113
|
+
const canonicalRoot = asNullableRecord(root?.legacyWebhook);
|
|
114
|
+
return normalizeChannelConfigEntries({
|
|
115
|
+
cfg,
|
|
116
|
+
channelId: params.channelKey,
|
|
117
|
+
normalizeEntry: ({ entry, accountId, pathPrefix, changes }) => {
|
|
118
|
+
const listener = source(entry);
|
|
119
|
+
if (!listener || !hasLegacy(entry)) return {
|
|
120
|
+
entry,
|
|
121
|
+
changed: false
|
|
122
|
+
};
|
|
123
|
+
const next = { ...entry };
|
|
124
|
+
const port = Object.hasOwn(listener, portKey) ? listener[portKey] : (accountId ? canonicalRoot?.port ?? inherited?.[portKey] : void 0) ?? params.defaultPort;
|
|
125
|
+
const inheritedHost = accountId ? canonicalRoot ? canonicalRoot.host : (hostKey ? inherited?.[hostKey] : void 0) ?? params.defaultHost : params.defaultHost;
|
|
126
|
+
const host = hostKey ? listener[hostKey] ?? inheritedHost : inheritedHost;
|
|
127
|
+
const legacyPath = [pathPrefix, params.webhookKey].filter(Boolean).join(".");
|
|
128
|
+
if (Object.hasOwn(entry, "legacyWebhook")) changes.push(`Removed ${legacyPath} legacy listener keys; ${pathPrefix}.legacyWebhook is already configured.`);
|
|
129
|
+
else if (accountId && root?.legacyWebhook === false) changes.push(`Removed ${legacyPath} legacy listener keys; ${prefix}.legacyWebhook: false keeps this account's inherited listener disabled.`);
|
|
130
|
+
else {
|
|
131
|
+
next.legacyWebhook = {
|
|
132
|
+
port,
|
|
133
|
+
...host !== void 0 ? { host } : {}
|
|
134
|
+
};
|
|
135
|
+
changes.push(`Moved ${legacyPath} listener settings to ${pathPrefix}.legacyWebhook. Point the external callback or reverse proxy at the Gateway port and webhook path, verify delivery, then set legacyWebhook: false to disable legacy forwarding.`);
|
|
136
|
+
}
|
|
137
|
+
const updated = params.webhookKey ? { ...listener } : next;
|
|
138
|
+
delete updated[portKey];
|
|
139
|
+
if (hostKey) delete updated[hostKey];
|
|
140
|
+
if (params.webhookKey) {
|
|
141
|
+
if (Object.keys(updated).length) next[params.webhookKey] = updated;
|
|
142
|
+
else delete next[params.webhookKey];
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
entry: next,
|
|
146
|
+
changed: true
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/runtime-doctor-migrations
|
|
155
|
+
var runtime_doctor_migrations_exports = /* @__PURE__ */ __exportAll({ createLegacyWebhookListenerDoctorContract: () => createLegacyWebhookListenerDoctorContract });
|
|
156
|
+
import * as import_openclaw_plugin_sdk_runtime_doctor_migrations from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
157
|
+
__reExport(runtime_doctor_migrations_exports, import_openclaw_plugin_sdk_runtime_doctor_migrations);
|
|
158
|
+
//#endregion
|
|
2
159
|
//#region extensions/clickclack/src/doctor-contract.ts
|
|
3
160
|
function stripTimeoutSeconds(value) {
|
|
4
|
-
const record = asObjectRecord(value);
|
|
161
|
+
const record = (0, runtime_doctor_migrations_exports.asObjectRecord)(value);
|
|
5
162
|
if (!record) return {
|
|
6
163
|
value,
|
|
7
164
|
changed: false
|
|
@@ -23,7 +180,7 @@ function stripTimeoutSeconds(value) {
|
|
|
23
180
|
};
|
|
24
181
|
}
|
|
25
182
|
function normalizeCompatibilityConfig({ cfg }) {
|
|
26
|
-
const rawEntry = asObjectRecord(cfg.channels?.clickclack);
|
|
183
|
+
const rawEntry = (0, runtime_doctor_migrations_exports.asObjectRecord)(cfg.channels?.clickclack);
|
|
27
184
|
if (!rawEntry) return {
|
|
28
185
|
config: cfg,
|
|
29
186
|
changes: []
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as registerClickClackDiscussions } from "./.setup/runtime-api-
|
|
1
|
+
import { t as registerClickClackDiscussions } from "./.setup/runtime-api-BvP8DrPQ.mjs";
|
|
2
2
|
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
3
3
|
//#region extensions/clickclack/index.ts
|
|
4
4
|
/**
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as setClickClackRuntime, r as parseClickClackTarget } from "./.setup/channel-
|
|
3
|
-
import {
|
|
1
|
+
import { h as resolveClickClackAccount } from "./.setup/setup-surface-BW1Q06w5.mjs";
|
|
2
|
+
import { a as setClickClackRuntime, r as parseClickClackTarget } from "./.setup/channel-Bcwtohk7.mjs";
|
|
3
|
+
import { i as createClickClackClient } from "./.setup/resolve-BHGLohni.mjs";
|
|
4
|
+
import { t as registerClickClackDiscussions } from "./.setup/runtime-api-BvP8DrPQ.mjs";
|
|
4
5
|
export { createClickClackClient, parseClickClackTarget, registerClickClackDiscussions, resolveClickClackAccount, setClickClackRuntime };
|
package/dist/setup-entry.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
var setup_entry_default = defineBundledChannelSetupEntry({
|
|
5
5
|
importMetaUrl: import.meta.url,
|
|
6
6
|
plugin: {
|
|
7
|
-
specifier: fileURLToPath(new URL(".setup/setup-plugin-api-
|
|
7
|
+
specifier: fileURLToPath(new URL(".setup/setup-plugin-api-BH_nw-AP.mjs", import.meta.url).href),
|
|
8
8
|
exportName: "clickClackSetupPlugin"
|
|
9
9
|
},
|
|
10
10
|
secrets: {
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as clickClackSetupPlugin } from "./.setup/setup-plugin-api-
|
|
1
|
+
import { t as clickClackSetupPlugin } from "./.setup/setup-plugin-api-C9QcBJuW.mjs";
|
|
2
2
|
export { clickClackSetupPlugin };
|
package/openclaw.plugin.json
CHANGED
|
@@ -237,6 +237,9 @@
|
|
|
237
237
|
"requireMention": {
|
|
238
238
|
"type": "boolean"
|
|
239
239
|
},
|
|
240
|
+
"requireMentionInBotThreads": {
|
|
241
|
+
"type": "boolean"
|
|
242
|
+
},
|
|
240
243
|
"mentionPatterns": {
|
|
241
244
|
"type": "array",
|
|
242
245
|
"items": {
|
|
@@ -254,6 +257,9 @@
|
|
|
254
257
|
"requireMention": {
|
|
255
258
|
"type": "boolean"
|
|
256
259
|
},
|
|
260
|
+
"requireMentionInBotThreads": {
|
|
261
|
+
"type": "boolean"
|
|
262
|
+
},
|
|
257
263
|
"mentionPatterns": {
|
|
258
264
|
"type": "array",
|
|
259
265
|
"items": {
|
|
@@ -548,6 +554,9 @@
|
|
|
548
554
|
"requireMention": {
|
|
549
555
|
"type": "boolean"
|
|
550
556
|
},
|
|
557
|
+
"requireMentionInBotThreads": {
|
|
558
|
+
"type": "boolean"
|
|
559
|
+
},
|
|
551
560
|
"mentionPatterns": {
|
|
552
561
|
"type": "array",
|
|
553
562
|
"items": {
|
|
@@ -565,6 +574,9 @@
|
|
|
565
574
|
"requireMention": {
|
|
566
575
|
"type": "boolean"
|
|
567
576
|
},
|
|
577
|
+
"requireMentionInBotThreads": {
|
|
578
|
+
"type": "boolean"
|
|
579
|
+
},
|
|
568
580
|
"mentionPatterns": {
|
|
569
581
|
"type": "array",
|
|
570
582
|
"items": {
|
|
@@ -640,7 +652,25 @@
|
|
|
640
652
|
"additionalProperties": false
|
|
641
653
|
},
|
|
642
654
|
"label": "ClickClack",
|
|
643
|
-
"description": "ClickClack channel accounts and group activation policy."
|
|
655
|
+
"description": "ClickClack channel accounts and group activation policy.",
|
|
656
|
+
"uiHints": {
|
|
657
|
+
"requireMentionInBotThreads": {
|
|
658
|
+
"label": "Require Mention in Bot Threads",
|
|
659
|
+
"help": "Override mention requirements in threads rooted in this bot's messages. Unset keeps the normal mention policy."
|
|
660
|
+
},
|
|
661
|
+
"groups.*.requireMentionInBotThreads": {
|
|
662
|
+
"label": "Require Mention in Bot Threads",
|
|
663
|
+
"help": "Override the account policy for threads rooted in this bot's messages in this channel."
|
|
664
|
+
},
|
|
665
|
+
"accounts.*.requireMentionInBotThreads": {
|
|
666
|
+
"label": "Require Mention in Bot Threads",
|
|
667
|
+
"help": "Override mention requirements in threads rooted in this bot's messages. Unset inherits the channel configuration."
|
|
668
|
+
},
|
|
669
|
+
"accounts.*.groups.*.requireMentionInBotThreads": {
|
|
670
|
+
"label": "Require Mention in Bot Threads",
|
|
671
|
+
"help": "Override the account policy for threads rooted in this bot's messages in this channel."
|
|
672
|
+
}
|
|
673
|
+
}
|
|
644
674
|
}
|
|
645
675
|
},
|
|
646
676
|
"contracts": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/clickclack",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.7",
|
|
4
4
|
"description": "OpenClaw ClickClack channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"zod": "4.6.5"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.9.
|
|
16
|
+
"openclaw": ">=2026.9.7"
|
|
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.
|
|
142
|
+
"pluginApi": ">=2026.9.7"
|
|
143
143
|
},
|
|
144
144
|
"build": {
|
|
145
|
-
"openclawVersion": "2026.9.
|
|
145
|
+
"openclawVersion": "2026.9.7",
|
|
146
146
|
"bundledDist": false
|
|
147
147
|
},
|
|
148
148
|
"release": {
|