@inline-openclaw/inline 0.0.62 → 0.0.64

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAcA,wBAsBE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAuBA,wBAsBE"}
package/dist/index.js CHANGED
@@ -32,12 +32,288 @@ import {
32
32
  defineBundledChannelEntry,
33
33
  loadBundledEntryExportSync
34
34
  } from "openclaw/plugin-sdk/channel-entry-contract";
35
+
36
+ // src/telemetry.ts
37
+ import { randomUUID } from "node:crypto";
38
+ import { readFile } from "node:fs/promises";
39
+ var TELEMETRY_TIMEOUT_MS = 2000;
40
+ var TELEMETRY_DEDUP_MS = 5 * 60000;
41
+ var MAX_ERROR_MESSAGE_LENGTH = 8000;
42
+ var MAX_STACK_FRAMES = 80;
43
+ var SENSITIVE_ENV_NAME = /(?:token|secret|password|api[_-]?key|authorization)/i;
44
+ var lastReports = new Map;
45
+ var releasePromise;
46
+ function telemetryDisabled(env = process.env) {
47
+ const disabled = (value) => value != null && ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
48
+ const optedOut = (value) => value != null && ["0", "false", "off"].includes(value.trim().toLowerCase());
49
+ return disabled(env.DO_NOT_TRACK) || optedOut(env.INLINE_PLUGIN_TELEMETRY);
50
+ }
51
+ function resolveDsn(env = process.env) {
52
+ if (telemetryDisabled(env))
53
+ return "";
54
+ return env.INLINE_OPENCLAW_SENTRY_DSN?.trim() ?? "";
55
+ }
56
+ function sensitiveValues(env = process.env) {
57
+ return Object.entries(env).filter(([name, value]) => SENSITIVE_ENV_NAME.test(name) && (value?.length ?? 0) >= 8).map(([, value]) => value);
58
+ }
59
+ function redactOpenClawTelemetryText(value, env = process.env) {
60
+ let text = String(value ?? "").replace(/\b(Authorization\s*[:=]\s*)(?:Basic|Bearer)\s+\S+/gi, "$1[REDACTED]").replace(/\b((?:Basic|Bearer)\s+)\S+/gi, "$1[REDACTED]").replace(/(https?:\/\/)[^/\s:@]+:[^@\s/]+@/gi, "$1[REDACTED]@").replace(/([?&](?:access_token|auth|authorization|key|password|secret|token)[^=\s&]*)=([^&\s]+)/gi, "$1=[REDACTED]").replace(/\b([A-Za-z0-9_-]*(?:token|secret|password|api[_-]?key|authorization)[A-Za-z0-9_-]*)\s*([=:])\s*\S+/gi, "$1$2[REDACTED]");
61
+ for (const secret of sensitiveValues(env)) {
62
+ text = text.replaceAll(secret, "[REDACTED]");
63
+ }
64
+ return text.slice(0, MAX_ERROR_MESSAGE_LENGTH);
65
+ }
66
+ function safeTag(value) {
67
+ const normalized = value.trim().toLowerCase();
68
+ return normalized.length > 0 && normalized.length <= 80 && /^[a-z0-9._-]+$/.test(normalized) ? normalized : "unknown";
69
+ }
70
+ function parseStack(error, env) {
71
+ const stack = error.stack ?? "";
72
+ const frames = [];
73
+ for (const rawLine of stack.split(`
74
+ `).slice(1)) {
75
+ const line = redactOpenClawTelemetryText(rawLine.trim(), env);
76
+ const match = /^at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(line);
77
+ if (!match)
78
+ continue;
79
+ const filename = match[2];
80
+ const frame = {
81
+ filename,
82
+ abs_path: filename,
83
+ function: match[1] || "<anonymous>",
84
+ lineno: Number(match[3]),
85
+ colno: Number(match[4]),
86
+ in_app: filename.includes("@inline-openclaw/inline") || filename.includes("/openclaw/") || /\/(?:channel-plugin-api|runtime-register-api|index)\.js$/.test(filename)
87
+ };
88
+ frames.push(frame);
89
+ if (frames.length >= MAX_STACK_FRAMES)
90
+ break;
91
+ }
92
+ return frames.reverse();
93
+ }
94
+ function buildOpenClawTelemetryEvent(operation, error, options = {}) {
95
+ const env = options.env ?? process.env;
96
+ const exception = error instanceof Error ? error : new Error(String(error ?? "Unknown error"));
97
+ const frames = parseStack(exception, env);
98
+ return {
99
+ event_id: randomUUID().replaceAll("-", ""),
100
+ timestamp: new Date().toISOString(),
101
+ platform: "javascript",
102
+ level: "error",
103
+ logger: "inline.openclaw.plugin",
104
+ exception: {
105
+ values: [{
106
+ type: redactOpenClawTelemetryText(exception.name || "Error", env),
107
+ value: redactOpenClawTelemetryText(exception.message || String(error), env),
108
+ mechanism: {
109
+ type: "inline_plugin_boundary",
110
+ handled: options.handled ?? true
111
+ },
112
+ ...frames.length > 0 ? { stacktrace: { frames } } : {}
113
+ }]
114
+ },
115
+ tags: {
116
+ operation: safeTag(operation),
117
+ runtime: "node",
118
+ os: process.platform,
119
+ arch: process.arch
120
+ },
121
+ sdk: { name: "inline.plugin.telemetry", version: "1" }
122
+ };
123
+ }
124
+ async function resolveRelease() {
125
+ releasePromise ??= (async () => {
126
+ try {
127
+ const parsed = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
128
+ if (typeof parsed.version === "string" && parsed.version.trim()) {
129
+ return `inline-openclaw-plugin@${parsed.version.trim()}`;
130
+ }
131
+ } catch {}
132
+ return;
133
+ })();
134
+ return releasePromise;
135
+ }
136
+ function parseSentryDsn(dsn) {
137
+ try {
138
+ const parsed = new URL(dsn);
139
+ if (!/^https?:$/.test(parsed.protocol) || !parsed.username)
140
+ return null;
141
+ const parts = parsed.pathname.split("/").filter(Boolean);
142
+ const projectId = parts.pop();
143
+ if (!projectId || !/^\d+$/.test(projectId))
144
+ return null;
145
+ const prefix = parts.length > 0 ? `/${parts.join("/")}` : "";
146
+ return {
147
+ endpoint: `${parsed.origin}${prefix}/api/${projectId}/envelope/`,
148
+ publicKey: parsed.username
149
+ };
150
+ } catch {
151
+ return null;
152
+ }
153
+ }
154
+ async function sendOpenClawPluginError(operation, error, options = {}) {
155
+ const env = options.env ?? process.env;
156
+ const dsn = resolveDsn(env);
157
+ const target = parseSentryDsn(dsn);
158
+ if (!target)
159
+ return false;
160
+ const event = buildOpenClawTelemetryEvent(operation, error, options);
161
+ const release = await resolveRelease();
162
+ if (release)
163
+ event.release = release;
164
+ const envelope = [
165
+ JSON.stringify({ event_id: event.event_id, dsn, sent_at: event.timestamp }),
166
+ JSON.stringify({ type: "event", content_type: "application/json" }),
167
+ JSON.stringify(event)
168
+ ].join(`
169
+ `);
170
+ const controller = new AbortController;
171
+ const timeout = setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS);
172
+ timeout.unref?.();
173
+ try {
174
+ const response = await fetch(target.endpoint, {
175
+ method: "POST",
176
+ headers: {
177
+ "content-type": "application/x-sentry-envelope",
178
+ "x-sentry-auth": `Sentry sentry_version=7, sentry_key=${target.publicKey}, sentry_client=inline.plugin.telemetry/1`
179
+ },
180
+ body: envelope,
181
+ signal: controller.signal
182
+ });
183
+ return response.ok;
184
+ } catch {
185
+ return false;
186
+ } finally {
187
+ clearTimeout(timeout);
188
+ }
189
+ }
190
+ function reportOpenClawPluginError(operation, error, options = {}) {
191
+ try {
192
+ const exception = error instanceof Error ? error : new Error(String(error ?? "Unknown error"));
193
+ const key = `${safeTag(operation)}\x00${exception.name}\x00${redactOpenClawTelemetryText(exception.message)}`;
194
+ const now = Date.now();
195
+ if (now - (lastReports.get(key) ?? 0) < TELEMETRY_DEDUP_MS)
196
+ return;
197
+ lastReports.set(key, now);
198
+ sendOpenClawPluginError(operation, exception, options).catch(() => {});
199
+ } catch {}
200
+ }
201
+ function wrapCallback(operation, callback) {
202
+ return function(...args) {
203
+ try {
204
+ const result = Reflect.apply(callback, this, args);
205
+ if (result && typeof result.then === "function") {
206
+ return Promise.resolve(result).catch((error) => {
207
+ reportOpenClawPluginError(operation, error);
208
+ throw error;
209
+ });
210
+ }
211
+ return result;
212
+ } catch (error) {
213
+ reportOpenClawPluginError(operation, error);
214
+ throw error;
215
+ }
216
+ };
217
+ }
218
+ function wrapSurface(prefix, surface) {
219
+ const wrapped = { ...surface };
220
+ for (const [name, member] of Object.entries(wrapped)) {
221
+ if (typeof member === "function") {
222
+ wrapped[name] = wrapCallback(`${prefix}.${name}`, member);
223
+ }
224
+ }
225
+ return wrapped;
226
+ }
227
+ function instrumentToolValue(value) {
228
+ if (Array.isArray(value))
229
+ return value.map(instrumentToolValue);
230
+ if (!value || typeof value !== "object")
231
+ return value;
232
+ const tool = value;
233
+ const execute = tool.execute;
234
+ if (typeof execute !== "function")
235
+ return value;
236
+ const name = typeof tool.name === "string" ? safeTag(tool.name) : "unknown";
237
+ return new Proxy(tool, {
238
+ get(target, property, receiver) {
239
+ if (property === "execute") {
240
+ return wrapCallback(`tool.${name}`, execute);
241
+ }
242
+ return Reflect.get(target, property, receiver);
243
+ }
244
+ });
245
+ }
246
+ function instrumentOpenClawPluginApi(value) {
247
+ const api = value;
248
+ return new Proxy(api, {
249
+ get(target, property, receiver) {
250
+ const member = Reflect.get(target, property, receiver);
251
+ if (property === "registerTool" && typeof member === "function") {
252
+ return (toolOrFactory, options) => {
253
+ const wrapped = typeof toolOrFactory === "function" ? wrapCallback("tool.factory", (...args) => instrumentToolValue(Reflect.apply(toolOrFactory, undefined, args))) : instrumentToolValue(toolOrFactory);
254
+ return Reflect.apply(member, target, [wrapped, options]);
255
+ };
256
+ }
257
+ if (property === "registerCommand" && typeof member === "function") {
258
+ return (command) => {
259
+ const handler = command.handler;
260
+ const name = typeof command.name === "string" ? safeTag(command.name) : "unknown";
261
+ const wrapped = typeof handler === "function" ? { ...command, handler: wrapCallback(`command.${name}`, handler) } : command;
262
+ return Reflect.apply(member, target, [wrapped]);
263
+ };
264
+ }
265
+ if (property === "on" && typeof member === "function") {
266
+ return (event, handler) => Reflect.apply(member, target, [event, wrapCallback(`hook.${safeTag(event)}`, handler)]);
267
+ }
268
+ return member;
269
+ }
270
+ });
271
+ }
272
+ function instrumentOpenClawChannelPlugin(value) {
273
+ const plugin = { ...value };
274
+ for (const name of [
275
+ "lifecycle",
276
+ "pairing",
277
+ "outbound",
278
+ "heartbeat",
279
+ "directory",
280
+ "resolver",
281
+ "allowlist",
282
+ "status",
283
+ "gateway"
284
+ ]) {
285
+ const surface = plugin[name];
286
+ if (surface && typeof surface === "object") {
287
+ plugin[name] = wrapSurface(name, surface);
288
+ }
289
+ }
290
+ const message = plugin.message;
291
+ if (message && typeof message === "object") {
292
+ const wrappedMessage = { ...message };
293
+ const send = wrappedMessage.send;
294
+ if (send && typeof send === "object") {
295
+ wrappedMessage.send = wrapSurface("message.send", send);
296
+ }
297
+ plugin.message = wrappedMessage;
298
+ }
299
+ return plugin;
300
+ }
301
+ function reportOpenClawRegistrationError(error) {
302
+ reportOpenClawPluginError("plugin.register", error, { handled: false });
303
+ }
304
+
305
+ // src/index.ts
35
306
  function registerInlinePluginFull(api) {
36
307
  const register = loadBundledEntryExportSync(import.meta.url, {
37
308
  specifier: "./runtime-register-api.js",
38
309
  exportName: "registerInlinePluginFull"
39
310
  });
40
- register(api);
311
+ try {
312
+ register(instrumentOpenClawPluginApi(api));
313
+ } catch (error) {
314
+ reportOpenClawRegistrationError(error);
315
+ throw error;
316
+ }
41
317
  }
42
318
  var src_default = defineBundledChannelEntry({
43
319
  id: "inline",
@@ -66,5 +342,5 @@ export {
66
342
  src_default as default
67
343
  };
68
344
 
69
- //# debugId=FDD2427739E33F0064756E2164756E21
345
+ //# debugId=4B9195CA65AD814864756E2164756E21
70
346
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts"],
3
+ "sources": ["../src/index.ts", "../src/telemetry.ts"],
4
4
  "sourcesContent": [
5
- "import {\n defineBundledChannelEntry,\n loadBundledEntryExportSync,\n type OpenClawPluginApi,\n} from \"openclaw/plugin-sdk/channel-entry-contract\"\n\nfunction registerInlinePluginFull(api: OpenClawPluginApi): void {\n const register = loadBundledEntryExportSync<(api: OpenClawPluginApi) => void>(import.meta.url, {\n specifier: \"./runtime-register-api.js\",\n exportName: \"registerInlinePluginFull\",\n })\n register(api)\n}\n\nexport default defineBundledChannelEntry({\n id: \"inline\",\n name: \"Inline\",\n description: \"Inline channel plugin for OpenClaw bots.\",\n importMetaUrl: import.meta.url,\n plugin: {\n specifier: \"./channel-plugin-api.js\",\n exportName: \"inlineChannelPlugin\",\n },\n secrets: {\n specifier: \"./secret-contract-api.js\",\n exportName: \"channelSecrets\",\n },\n runtime: {\n specifier: \"./runtime-setter-api.js\",\n exportName: \"setInlineRuntime\",\n },\n accountInspect: {\n specifier: \"./account-inspect-api.js\",\n exportName: \"inspectInlineReadOnlyAccount\",\n },\n registerFull: registerInlinePluginFull,\n})\n"
5
+ "import {\n defineBundledChannelEntry,\n loadBundledEntryExportSync,\n type OpenClawPluginApi,\n} from \"openclaw/plugin-sdk/channel-entry-contract\"\nimport {\n instrumentOpenClawPluginApi,\n reportOpenClawRegistrationError,\n} from \"./telemetry.js\"\n\nfunction registerInlinePluginFull(api: OpenClawPluginApi): void {\n const register = loadBundledEntryExportSync<(api: OpenClawPluginApi) => void>(import.meta.url, {\n specifier: \"./runtime-register-api.js\",\n exportName: \"registerInlinePluginFull\",\n })\n try {\n register(instrumentOpenClawPluginApi(api))\n } catch (error) {\n reportOpenClawRegistrationError(error)\n throw error\n }\n}\n\nexport default defineBundledChannelEntry({\n id: \"inline\",\n name: \"Inline\",\n description: \"Inline channel plugin for OpenClaw bots.\",\n importMetaUrl: import.meta.url,\n plugin: {\n specifier: \"./channel-plugin-api.js\",\n exportName: \"inlineChannelPlugin\",\n },\n secrets: {\n specifier: \"./secret-contract-api.js\",\n exportName: \"channelSecrets\",\n },\n runtime: {\n specifier: \"./runtime-setter-api.js\",\n exportName: \"setInlineRuntime\",\n },\n accountInspect: {\n specifier: \"./account-inspect-api.js\",\n exportName: \"inspectInlineReadOnlyAccount\",\n },\n registerFull: registerInlinePluginFull,\n})\n",
6
+ "import { randomUUID } from \"node:crypto\"\nimport { readFile } from \"node:fs/promises\"\n\nconst TELEMETRY_TIMEOUT_MS = 2_000\nconst TELEMETRY_DEDUP_MS = 5 * 60_000\nconst MAX_ERROR_MESSAGE_LENGTH = 8_000\nconst MAX_STACK_FRAMES = 80\nconst SENSITIVE_ENV_NAME = /(?:token|secret|password|api[_-]?key|authorization)/i\n\ntype TelemetryFrame = {\n filename: string\n abs_path: string\n function: string\n lineno: number\n colno?: number\n in_app: boolean\n}\n\ntype OpenClawTelemetryEvent = {\n event_id: string\n timestamp: string\n platform: \"javascript\"\n level: \"error\"\n logger: \"inline.openclaw.plugin\"\n release?: string\n exception: {\n values: Array<{\n type: string\n value: string\n mechanism: { type: \"inline_plugin_boundary\"; handled: boolean }\n stacktrace?: { frames: TelemetryFrame[] }\n }>\n }\n tags: Record<string, string>\n sdk: { name: \"inline.plugin.telemetry\"; version: \"1\" }\n}\n\nconst lastReports = new Map<string, number>()\nlet releasePromise: Promise<string | undefined> | undefined\n\nfunction telemetryDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n const disabled = (value: string | undefined) =>\n value != null && [\"1\", \"true\", \"yes\", \"on\"].includes(value.trim().toLowerCase())\n const optedOut = (value: string | undefined) =>\n value != null && [\"0\", \"false\", \"off\"].includes(value.trim().toLowerCase())\n return disabled(env.DO_NOT_TRACK) || optedOut(env.INLINE_PLUGIN_TELEMETRY)\n}\n\nfunction resolveDsn(env: NodeJS.ProcessEnv = process.env): string {\n if (telemetryDisabled(env)) return \"\"\n return env.INLINE_OPENCLAW_SENTRY_DSN?.trim() ?? \"\"\n}\n\nfunction sensitiveValues(env: NodeJS.ProcessEnv = process.env): string[] {\n return Object.entries(env)\n .filter(([name, value]) => SENSITIVE_ENV_NAME.test(name) && (value?.length ?? 0) >= 8)\n .map(([, value]) => value!)\n}\n\nexport function redactOpenClawTelemetryText(\n value: unknown,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n let text = String(value ?? \"\")\n .replace(/\\b(Authorization\\s*[:=]\\s*)(?:Basic|Bearer)\\s+\\S+/gi, \"$1[REDACTED]\")\n .replace(/\\b((?:Basic|Bearer)\\s+)\\S+/gi, \"$1[REDACTED]\")\n .replace(/(https?:\\/\\/)[^/\\s:@]+:[^@\\s/]+@/gi, \"$1[REDACTED]@\")\n .replace(\n /([?&](?:access_token|auth|authorization|key|password|secret|token)[^=\\s&]*)=([^&\\s]+)/gi,\n \"$1=[REDACTED]\",\n )\n .replace(\n /\\b([A-Za-z0-9_-]*(?:token|secret|password|api[_-]?key|authorization)[A-Za-z0-9_-]*)\\s*([=:])\\s*\\S+/gi,\n \"$1$2[REDACTED]\",\n )\n for (const secret of sensitiveValues(env)) {\n text = text.replaceAll(secret, \"[REDACTED]\")\n }\n return text.slice(0, MAX_ERROR_MESSAGE_LENGTH)\n}\n\nfunction safeTag(value: string): string {\n const normalized = value.trim().toLowerCase()\n return normalized.length > 0 && normalized.length <= 80 && /^[a-z0-9._-]+$/.test(normalized)\n ? normalized\n : \"unknown\"\n}\n\nfunction parseStack(error: Error, env: NodeJS.ProcessEnv): TelemetryFrame[] {\n const stack = error.stack ?? \"\"\n const frames: TelemetryFrame[] = []\n for (const rawLine of stack.split(\"\\n\").slice(1)) {\n const line = redactOpenClawTelemetryText(rawLine.trim(), env)\n const match = /^at\\s+(?:(.*?)\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/.exec(line)\n if (!match) continue\n const filename = match[2]!\n const frame: TelemetryFrame = {\n filename,\n abs_path: filename,\n function: match[1] || \"<anonymous>\",\n lineno: Number(match[3]),\n colno: Number(match[4]),\n in_app:\n filename.includes(\"@inline-openclaw/inline\") ||\n filename.includes(\"/openclaw/\") ||\n /\\/(?:channel-plugin-api|runtime-register-api|index)\\.js$/.test(filename),\n }\n frames.push(frame)\n if (frames.length >= MAX_STACK_FRAMES) break\n }\n // Sentry's event protocol expects oldest frames first.\n return frames.reverse()\n}\n\nexport function buildOpenClawTelemetryEvent(\n operation: string,\n error: unknown,\n options: { handled?: boolean; env?: NodeJS.ProcessEnv } = {},\n): OpenClawTelemetryEvent {\n const env = options.env ?? process.env\n const exception = error instanceof Error ? error : new Error(String(error ?? \"Unknown error\"))\n const frames = parseStack(exception, env)\n return {\n event_id: randomUUID().replaceAll(\"-\", \"\"),\n timestamp: new Date().toISOString(),\n platform: \"javascript\",\n level: \"error\",\n logger: \"inline.openclaw.plugin\",\n exception: {\n values: [{\n type: redactOpenClawTelemetryText(exception.name || \"Error\", env),\n value: redactOpenClawTelemetryText(exception.message || String(error), env),\n mechanism: {\n type: \"inline_plugin_boundary\",\n handled: options.handled ?? true,\n },\n ...(frames.length > 0 ? { stacktrace: { frames } } : {}),\n }],\n },\n tags: {\n operation: safeTag(operation),\n runtime: \"node\",\n os: process.platform,\n arch: process.arch,\n },\n sdk: { name: \"inline.plugin.telemetry\", version: \"1\" },\n }\n}\n\nasync function resolveRelease(): Promise<string | undefined> {\n releasePromise ??= (async () => {\n try {\n const parsed = JSON.parse(\n await readFile(new URL(\"../package.json\", import.meta.url), \"utf8\"),\n ) as { version?: unknown }\n if (typeof parsed.version === \"string\" && parsed.version.trim()) {\n return `inline-openclaw-plugin@${parsed.version.trim()}`\n }\n } catch {\n // Release metadata is helpful but must never interfere with reporting.\n }\n return undefined\n })()\n return releasePromise\n}\n\nfunction parseSentryDsn(dsn: string): { endpoint: string; publicKey: string } | null {\n try {\n const parsed = new URL(dsn)\n if (!/^https?:$/.test(parsed.protocol) || !parsed.username) return null\n const parts = parsed.pathname.split(\"/\").filter(Boolean)\n const projectId = parts.pop()\n if (!projectId || !/^\\d+$/.test(projectId)) return null\n const prefix = parts.length > 0 ? `/${parts.join(\"/\")}` : \"\"\n return {\n endpoint: `${parsed.origin}${prefix}/api/${projectId}/envelope/`,\n publicKey: parsed.username,\n }\n } catch {\n return null\n }\n}\n\nexport async function sendOpenClawPluginError(\n operation: string,\n error: unknown,\n options: { handled?: boolean; env?: NodeJS.ProcessEnv } = {},\n): Promise<boolean> {\n const env = options.env ?? process.env\n const dsn = resolveDsn(env)\n const target = parseSentryDsn(dsn)\n if (!target) return false\n\n const event = buildOpenClawTelemetryEvent(operation, error, options)\n const release = await resolveRelease()\n if (release) event.release = release\n const envelope = [\n JSON.stringify({ event_id: event.event_id, dsn, sent_at: event.timestamp }),\n JSON.stringify({ type: \"event\", content_type: \"application/json\" }),\n JSON.stringify(event),\n ].join(\"\\n\")\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS)\n timeout.unref?.()\n try {\n const response = await fetch(target.endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/x-sentry-envelope\",\n \"x-sentry-auth\": `Sentry sentry_version=7, sentry_key=${target.publicKey}, sentry_client=inline.plugin.telemetry/1`,\n },\n body: envelope,\n signal: controller.signal,\n })\n return response.ok\n } catch {\n return false\n } finally {\n clearTimeout(timeout)\n }\n}\n\nexport function reportOpenClawPluginError(\n operation: string,\n error: unknown,\n options: { handled?: boolean } = {},\n): void {\n try {\n const exception = error instanceof Error ? error : new Error(String(error ?? \"Unknown error\"))\n const key = `${safeTag(operation)}\\0${exception.name}\\0${redactOpenClawTelemetryText(exception.message)}`\n const now = Date.now()\n if (now - (lastReports.get(key) ?? 0) < TELEMETRY_DEDUP_MS) return\n lastReports.set(key, now)\n void sendOpenClawPluginError(operation, exception, options).catch(() => {})\n } catch {\n // Observability must never alter host plugin behavior.\n }\n}\n\nfunction wrapCallback<T extends (...args: never[]) => unknown>(operation: string, callback: T): T {\n return function (this: unknown, ...args: Parameters<T>): ReturnType<T> {\n try {\n const result = Reflect.apply(callback, this, args) as ReturnType<T>\n if (result && typeof (result as { then?: unknown }).then === \"function\") {\n return Promise.resolve(result).catch((error) => {\n reportOpenClawPluginError(operation, error)\n throw error\n }) as ReturnType<T>\n }\n return result\n } catch (error) {\n reportOpenClawPluginError(operation, error)\n throw error\n }\n } as T\n}\n\nfunction wrapSurface<T extends object>(prefix: string, surface: T): T {\n const wrapped = { ...surface } as Record<string, unknown>\n for (const [name, member] of Object.entries(wrapped)) {\n if (typeof member === \"function\") {\n wrapped[name] = wrapCallback(`${prefix}.${name}`, member as (...args: never[]) => unknown)\n }\n }\n return wrapped as T\n}\n\nfunction instrumentToolValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(instrumentToolValue)\n if (!value || typeof value !== \"object\") return value\n\n const tool = value as Record<string, unknown>\n const execute = tool.execute\n if (typeof execute !== \"function\") return value\n const name = typeof tool.name === \"string\" ? safeTag(tool.name) : \"unknown\"\n return new Proxy(tool, {\n get(target, property, receiver) {\n if (property === \"execute\") {\n return wrapCallback(`tool.${name}`, execute as (...args: never[]) => unknown)\n }\n return Reflect.get(target, property, receiver)\n },\n })\n}\n\nexport function instrumentOpenClawPluginApi<T extends object>(value: T): T {\n const api = value as Record<string, unknown>\n return new Proxy(api, {\n get(target, property, receiver) {\n const member = Reflect.get(target, property, receiver)\n if (property === \"registerTool\" && typeof member === \"function\") {\n return (toolOrFactory: unknown, options?: unknown) => {\n const wrapped = typeof toolOrFactory === \"function\"\n ? wrapCallback(\"tool.factory\", (...args: never[]) =>\n instrumentToolValue(Reflect.apply(toolOrFactory, undefined, args)))\n : instrumentToolValue(toolOrFactory)\n return Reflect.apply(member, target, [wrapped, options])\n }\n }\n if (property === \"registerCommand\" && typeof member === \"function\") {\n return (command: Record<string, unknown>) => {\n const handler = command.handler\n const name = typeof command.name === \"string\" ? safeTag(command.name) : \"unknown\"\n const wrapped = typeof handler === \"function\"\n ? { ...command, handler: wrapCallback(`command.${name}`, handler as (...args: never[]) => unknown) }\n : command\n return Reflect.apply(member, target, [wrapped])\n }\n }\n if (property === \"on\" && typeof member === \"function\") {\n return (event: string, handler: (...args: never[]) => unknown) =>\n Reflect.apply(member, target, [event, wrapCallback(`hook.${safeTag(event)}`, handler)])\n }\n return member\n },\n }) as T\n}\n\nexport function instrumentOpenClawChannelPlugin<T extends object>(value: T): T {\n const plugin = { ...value } as Record<string, unknown>\n for (const name of [\n \"lifecycle\",\n \"pairing\",\n \"outbound\",\n \"heartbeat\",\n \"directory\",\n \"resolver\",\n \"allowlist\",\n \"status\",\n \"gateway\",\n ]) {\n const surface = plugin[name]\n if (surface && typeof surface === \"object\") {\n plugin[name] = wrapSurface(name, surface)\n }\n }\n const message = plugin.message\n if (message && typeof message === \"object\") {\n const wrappedMessage = { ...message } as Record<string, unknown>\n const send = wrappedMessage.send\n if (send && typeof send === \"object\") {\n wrappedMessage.send = wrapSurface(\"message.send\", send)\n }\n plugin.message = wrappedMessage\n }\n return plugin as T\n}\n\nexport function reportOpenClawRegistrationError(error: unknown): void {\n reportOpenClawPluginError(\"plugin.register\", error, { handled: false })\n}\n"
6
7
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,wBAAwB,CAAC,KAA8B;AAAA,EAC9D,MAAM,WAAW,2BAA6D,YAAY,KAAK;AAAA,IAC7F,WAAW;AAAA,IACX,YAAY;AAAA,EACd,CAAC;AAAA,EACD,SAAS,GAAG;AAAA;AAGd,IAAe,wCAA0B;AAAA,EACvC,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,eAAe,YAAY;AAAA,EAC3B,QAAQ;AAAA,IACN,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,cAAc;AAChB,CAAC;",
8
- "debugId": "FDD2427739E33F0064756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "4B9195CA65AD814864756E2164756E21",
9
10
  "names": []
10
11
  }