@openclaw/clickclack 2026.7.2-beta.3 → 2026.7.2-beta.5
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 +125 -0
- package/dist/api.js +2 -2
- package/dist/{channel-CEYthZ9N.js → channel-DfcFlLjC.js} +397 -13
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +48 -0
- package/dist/index.js +3 -1
- package/dist/runtime-api-D1H9vheM.js +1029 -0
- package/dist/runtime-api.js +4 -4
- package/dist/{setup-claim-BUWvZjtu.js → setup-claim-BFU16zoo.js} +33 -11
- package/dist/setup-plugin-api.js +2 -1
- package/dist/{setup-surface-CNjp76Xx.js → setup-surface-CD6MUC1g.js} +286 -89
- package/node_modules/ws/lib/receiver.js +15 -32
- package/node_modules/ws/lib/websocket-server.js +4 -4
- package/node_modules/ws/lib/websocket.js +4 -4
- package/node_modules/ws/package.json +5 -1
- package/openclaw.plugin.json +49 -13
- package/package.json +91 -16
- package/npm-shrinkwrap.json +0 -54
package/dist/runtime-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import "./api.js";
|
|
4
|
-
export { createClickClackClient, parseClickClackTarget, resolveClickClackAccount, setClickClackRuntime };
|
|
1
|
+
import { d as createClickClackClient, x as resolveClickClackAccount } from "./setup-surface-CD6MUC1g.js";
|
|
2
|
+
import { D as setClickClackRuntime, r as parseClickClackTarget } from "./channel-DfcFlLjC.js";
|
|
3
|
+
import { t as registerClickClackDiscussions } from "./runtime-api-D1H9vheM.js";
|
|
4
|
+
export { createClickClackClient, parseClickClackTarget, registerClickClackDiscussions, resolveClickClackAccount, setClickClackRuntime };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { a as buildClickClackSetupClaimUrl, o as isClickClackSetupLoopbackHost, s as requireClickClackSetupApiBaseUrl } from "./setup-surface-CD6MUC1g.js";
|
|
1
2
|
import { createProviderOperationDeadline, readProviderJsonResponse, readResponseTextLimited, resolveProviderOperationTimeoutMs } from "openclaw/plugin-sdk/provider-http";
|
|
2
|
-
import { fetchWithSsrFGuard,
|
|
3
|
+
import { fetchWithSsrFGuard, resolvePinnedHostnameWithPolicy, ssrfPolicyFromHttpBaseUrlAllowedHostname } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
3
4
|
import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
5
|
//#region extensions/clickclack/src/setup-claim.ts
|
|
5
6
|
const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
|
|
@@ -20,7 +21,7 @@ function requireString(record, key, label) {
|
|
|
20
21
|
if (typeof value !== "string" || !value.trim()) throw new Error(`ClickClack setup code claim returned invalid ${label}.${key}`);
|
|
21
22
|
return value;
|
|
22
23
|
}
|
|
23
|
-
function parseClickClackSetupCodeClaim(value) {
|
|
24
|
+
function parseClickClackSetupCodeClaim(value, expectedClaimUrl) {
|
|
24
25
|
const claim = requireRecord(value, "response");
|
|
25
26
|
const bot = requireRecord(claim.bot, "bot");
|
|
26
27
|
const workspace = requireRecord(claim.workspace, "workspace");
|
|
@@ -31,7 +32,23 @@ function parseClickClackSetupCodeClaim(value) {
|
|
|
31
32
|
if (defaultTo !== void 0 && typeof defaultTo !== "string") throw new Error("ClickClack setup code claim returned invalid defaults.defaultTo");
|
|
32
33
|
if (allowFrom !== void 0 && (!Array.isArray(allowFrom) || !allowFrom.every((entry) => typeof entry === "string"))) throw new Error("ClickClack setup code claim returned invalid defaults.allowFrom");
|
|
33
34
|
if (agentActivity !== void 0 && typeof agentActivity !== "boolean") throw new Error("ClickClack setup code claim returned invalid defaults.agentActivity");
|
|
35
|
+
const contractVersion = claim.contract_version;
|
|
36
|
+
const apiBaseUrlValue = claim.api_base_url;
|
|
37
|
+
const hasContractMetadata = contractVersion !== void 0 || apiBaseUrlValue !== void 0;
|
|
38
|
+
if (expectedClaimUrl && !hasContractMetadata) throw new Error("ClickClack setup code claim returned a legacy response for an exact endpoint");
|
|
39
|
+
let contract = {};
|
|
40
|
+
if (hasContractMetadata) {
|
|
41
|
+
if (contractVersion !== 1 || typeof apiBaseUrlValue !== "string") throw new Error("ClickClack setup code claim returned invalid v1 contract metadata");
|
|
42
|
+
const apiBaseUrl = requireClickClackSetupApiBaseUrl(apiBaseUrlValue, "setup code claim response.api_base_url");
|
|
43
|
+
const canonicalClaimUrl = buildClickClackSetupClaimUrl(apiBaseUrl);
|
|
44
|
+
if (expectedClaimUrl && expectedClaimUrl !== canonicalClaimUrl) throw new Error("ClickClack setup code claim returned an API base that does not match the claim URL");
|
|
45
|
+
contract = {
|
|
46
|
+
contract_version: 1,
|
|
47
|
+
api_base_url: apiBaseUrl
|
|
48
|
+
};
|
|
49
|
+
}
|
|
34
50
|
return {
|
|
51
|
+
...contract,
|
|
35
52
|
token: requireString(claim, "token", "response"),
|
|
36
53
|
bot: {
|
|
37
54
|
id: requireString(bot, "id", "bot"),
|
|
@@ -53,30 +70,35 @@ function parseClickClackSetupCodeClaim(value) {
|
|
|
53
70
|
}
|
|
54
71
|
/** Claims a one-time setup code without sending any existing bot credential. */
|
|
55
72
|
async function claimClickClackSetupCode(params) {
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
let parsedClaimUrl;
|
|
74
|
+
try {
|
|
75
|
+
parsedClaimUrl = new URL(params.claimUrl);
|
|
76
|
+
} catch {
|
|
77
|
+
throw new Error("ClickClack setup code claim URL must be a valid HTTP(S) endpoint.");
|
|
78
|
+
}
|
|
79
|
+
if (parsedClaimUrl.protocol !== "http:" && parsedClaimUrl.protocol !== "https:" || parsedClaimUrl.username || parsedClaimUrl.password || parsedClaimUrl.search || parsedClaimUrl.hash || !parsedClaimUrl.pathname.endsWith("/api/bot-setup-codes/claim")) throw new Error("ClickClack setup code claim URL must be a valid HTTP(S) endpoint.");
|
|
58
80
|
const deadline = createProviderOperationDeadline({
|
|
59
81
|
label: "ClickClack setup code claim",
|
|
60
82
|
timeoutMs: CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS
|
|
61
83
|
});
|
|
62
84
|
let pinnedHttpTarget;
|
|
63
|
-
if (
|
|
85
|
+
if (parsedClaimUrl.protocol === "http:") {
|
|
64
86
|
const resolveTimeoutMs = resolveProviderOperationTimeoutMs({
|
|
65
87
|
deadline,
|
|
66
88
|
defaultTimeoutMs: CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS
|
|
67
89
|
});
|
|
68
|
-
const pinned = await withTimeout(resolvePinnedHostnameWithPolicy(
|
|
90
|
+
const pinned = await withTimeout(resolvePinnedHostnameWithPolicy(parsedClaimUrl.hostname, {
|
|
69
91
|
lookupFn: params.lookupFn,
|
|
70
92
|
policy: { dangerouslyAllowPrivateNetwork: true }
|
|
71
93
|
}), resolveTimeoutMs, { message: `ClickClack setup code claim timed out after ${CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS}ms` });
|
|
72
|
-
if (!pinned.addresses.every((address) =>
|
|
94
|
+
if (!pinned.addresses.every((address) => isClickClackSetupLoopbackHost(address))) throw new Error("ClickClack setup codes require HTTPS unless the server is on loopback.");
|
|
73
95
|
pinnedHttpTarget = {
|
|
74
96
|
hostname: pinned.hostname,
|
|
75
97
|
addresses: pinned.addresses
|
|
76
98
|
};
|
|
77
99
|
}
|
|
78
100
|
const { response, release } = await fetchWithSsrFGuard({
|
|
79
|
-
url:
|
|
101
|
+
url: params.claimUrl,
|
|
80
102
|
fetchImpl: params.fetch,
|
|
81
103
|
init: {
|
|
82
104
|
method: "POST",
|
|
@@ -91,8 +113,8 @@ async function claimClickClackSetupCode(params) {
|
|
|
91
113
|
deadline,
|
|
92
114
|
defaultTimeoutMs: CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS
|
|
93
115
|
}),
|
|
94
|
-
requireHttps:
|
|
95
|
-
policy: ssrfPolicyFromHttpBaseUrlAllowedHostname(
|
|
116
|
+
requireHttps: parsedClaimUrl.protocol === "https:",
|
|
117
|
+
policy: ssrfPolicyFromHttpBaseUrlAllowedHostname(params.claimUrl),
|
|
96
118
|
lookupFn: params.lookupFn,
|
|
97
119
|
...pinnedHttpTarget ? { dispatcherPolicy: {
|
|
98
120
|
mode: "direct",
|
|
@@ -105,7 +127,7 @@ async function claimClickClackSetupCode(params) {
|
|
|
105
127
|
const detail = await readResponseTextLimited(response, CLICKCLACK_ERROR_BODY_LIMIT_BYTES);
|
|
106
128
|
throw new ClickClackSetupCodeClaimError(response.status, detail);
|
|
107
129
|
}
|
|
108
|
-
return parseClickClackSetupCodeClaim(await readProviderJsonResponse(response, "ClickClack setup code claim", { maxBytes: CLICKCLACK_SETUP_CODE_CLAIM_JSON_LIMIT_BYTES }));
|
|
130
|
+
return parseClickClackSetupCodeClaim(await readProviderJsonResponse(response, "ClickClack setup code claim", { maxBytes: CLICKCLACK_SETUP_CODE_CLAIM_JSON_LIMIT_BYTES }), params.expectedClaimUrl);
|
|
109
131
|
} finally {
|
|
110
132
|
await release();
|
|
111
133
|
}
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as clickClackMeta, g as clickClackConfigAdapter, m as clickClackConfigSchema, n as clickClackSetupAdapter, r as clickClackSetupContract, t as clickClackSetupWizard } from "./setup-surface-CD6MUC1g.js";
|
|
2
2
|
//#region extensions/clickclack/src/channel.setup.ts
|
|
3
3
|
const clickClackSetupPlugin = {
|
|
4
4
|
id: "clickclack",
|
|
@@ -12,6 +12,7 @@ const clickClackSetupPlugin = {
|
|
|
12
12
|
configSchema: clickClackConfigSchema,
|
|
13
13
|
config: clickClackConfigAdapter,
|
|
14
14
|
setup: clickClackSetupAdapter,
|
|
15
|
+
setupContract: clickClackSetupContract,
|
|
15
16
|
setupWizard: clickClackSetupWizard
|
|
16
17
|
};
|
|
17
18
|
//#endregion
|