Skip to content

Expose ComfyUI telemetry bridge#1069

Open
benceruleanlu wants to merge 3 commits into
mainfrom
bl/mar-240-desktop-telemetry-bridge
Open

Expose ComfyUI telemetry bridge#1069
benceruleanlu wants to merge 3 commits into
mainfrom
bl/mar-240-desktop-telemetry-bridge

Conversation

@benceruleanlu

@benceruleanlu benceruleanlu commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

  • expose window.__comfyDesktop2.Telemetry.capture from the ComfyUI preload bridge
  • route hosted frontend telemetry through the existing telemetry:capture IPC path
  • allow primitive arrays for event properties while keeping person properties scalar-only
  • scrub string entries inside telemetry arrays before PostHog capture

Paired change

Note: full pnpm run format:check is pre-existing-broken on this worktree due unrelated repo-wide formatting drift and a parse error in src/renderer/src/components/DetailSection.vue.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a043880e14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/preload/comfyPreload.ts Outdated

const Telemetry = {
capture: (event: string, properties?: TelemetryProperties): void => {
ipcRenderer.send('telemetry:capture', { event, properties })

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the telemetry bridge fire-and-forget

When the hosted ComfyUI code accidentally includes a non-structured-cloneable value in telemetry properties (for example a function, symbol, or DOM object), ipcRenderer.send throws before the main-process asProps filter can drop it. The existing window.api.captureTelemetry wrapper catches this for the renderer, but this new exposed bridge lets a telemetry mistake propagate back into the frontend and break the caller, so the send should be wrapped in a try/catch or the payload should be sanitized in preload first.

Useful? React with 👍 / 👎.

…d-forget

`ipcRenderer.send` throws synchronously on non-structured-cloneable
payloads (functions, DOM nodes, symbols, circular refs). Since the
new `__comfyDesktop2.Telemetry.capture` surface is exposed to the
hosted ComfyUI frontend — code we don't fully control — a stray bad
payload would otherwise propagate into unrelated frontend code and
break it.

Mirror the same try/catch contract already used by
`window.api.captureTelemetry` in `src/preload/api.ts` (verbatim
comment lifted: "telemetry must never break the renderer"). Codex
flagged this as P2; agreeing because the contract is established
elsewhere in the same repo and the new bridge regressed it.
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR extends telemetry array support by introducing separate validation filters for general properties versus person attributes, implementing PII redaction for string array elements, and exposing a new renderer-side Telemetry bridge. The changes flow through the IPC boundary with proper type constraints and error handling.

Changes

Telemetry Array Support with PII Scrubbing

Layer / File(s) Summary
Telemetry IPC contract and validation filters
src/main/lib/ipc/registerTelemetryHandlers.ts
isTelemetryValueArray type guard and dual-filter approach: asProps allows primitive arrays (for general events), while asPersonProps restricts to primitives only (for user/person attributes). Handlers switch to asPersonProps for stricter person-property validation.
Array-aware PII scrubbing and privacy test
src/main/lib/telemetry.ts, src/main/lib/telemetry.test.ts
scrubProperties iterates over string array elements applying scrubAll() redaction while preserving non-strings unchanged. New test verifies Windows user paths in model_paths arrays are replaced with [REDACTED] while other entries remain intact—you might say the test really arrays its evidence!
Renderer-side telemetry and listener bridges
src/preload/comfyPreload.ts
Terminal and Logs listeners gain proper IpcRendererEvent typing with consistent unsubscribe functions. New Telemetry bridge wraps ipcRenderer.send in try/catch to prevent errors from throwing, and __comfyDesktop2 API gains onDownloadProgress subscription and Telemetry export.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bl/mar-240-desktop-telemetry-bridge
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch bl/mar-240-desktop-telemetry-bridge

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/lib/ipc/registerTelemetryHandlers.ts`:
- Around line 37-53: The asProps/isTelemetryValueArray validation currently
accepts unbounded renderer-controlled objects and arrays; limit work done at the
IPC boundary by enforcing caps: in asProps, stop iterating after a maxKeys
threshold (e.g., 50) and ignore additional keys; in isTelemetryValueArray, cap
checked/retained array length to maxArrayLen (e.g., 20) and only validate/trust
up to that many items; when accepting string TelemetryValue (checked by
isTelemetryValue), truncate strings to a maxStringLen (e.g., 200) before
assigning into the returned mainTelemetry.TelemetryContext; update references to
isTelemetryValue/isTelemetryValueArray and the out assignment logic so oversized
inputs are skipped/truncated rather than fully processed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ba60f3b5-b89b-4700-a918-679fae3bbba1

📥 Commits

Reviewing files that changed from the base of the PR and between c77f4f2 and db68fab.

📒 Files selected for processing (4)
  • src/main/lib/ipc/registerTelemetryHandlers.ts
  • src/main/lib/telemetry.test.ts
  • src/main/lib/telemetry.ts
  • src/preload/comfyPreload.ts

Comment on lines +37 to +53
function isTelemetryValueArray(v: unknown): v is mainTelemetry.TelemetryValue[] {
return Array.isArray(v) && v.every(isTelemetryValue)
}

// Per-key filter to the TelemetryContext contract.
function asProps(value: unknown): mainTelemetry.TelemetryContext {
if (!value || typeof value !== 'object' || Array.isArray(value)) return {}
const out: Record<string, mainTelemetry.TelemetryValue> = {}
const out: mainTelemetry.TelemetryContext = {}
for (const [key, raw] of Object.entries(value)) {
if (typeof key !== 'string') continue
if (isTelemetryValue(raw)) {
out[key] = raw
} else if (isTelemetryValueArray(raw)) {
out[key] = raw
}
// Drop anything else (objects, arrays, functions, symbols, etc.) silently.
}
return out

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Bound telemetry payload size at the IPC trust boundary.

Line 42 and Line 49 accept renderer-controlled objects/arrays with no size limits, so a huge hosted-frontend payload can synchronously stall main-process validation/scrubbing (a little “freeze-lemtry”); cap key count, array length, and string length before writing into out.

Proposed boundary hardening
+const MAX_TELEMETRY_KEYS = 128
+const MAX_TELEMETRY_ARRAY_ITEMS = 128
+const MAX_TELEMETRY_STRING_LENGTH = 2048
+
+function clampTelemetryValue(v: mainTelemetry.TelemetryValue): mainTelemetry.TelemetryValue {
+  return typeof v === 'string' ? v.slice(0, MAX_TELEMETRY_STRING_LENGTH) : v
+}
+
 function isTelemetryValueArray(v: unknown): v is mainTelemetry.TelemetryValue[] {
-  return Array.isArray(v) && v.every(isTelemetryValue)
+  return (
+    Array.isArray(v) &&
+    v.length <= MAX_TELEMETRY_ARRAY_ITEMS &&
+    v.every(isTelemetryValue)
+  )
 }
 
 // Per-key filter to the TelemetryContext contract.
 function asProps(value: unknown): mainTelemetry.TelemetryContext {
   if (!value || typeof value !== 'object' || Array.isArray(value)) return {}
   const out: mainTelemetry.TelemetryContext = {}
-  for (const [key, raw] of Object.entries(value)) {
+  for (const [key, raw] of Object.entries(value).slice(0, MAX_TELEMETRY_KEYS)) {
     if (typeof key !== 'string') continue
     if (isTelemetryValue(raw)) {
-      out[key] = raw
+      out[key] = clampTelemetryValue(raw)
     } else if (isTelemetryValueArray(raw)) {
-      out[key] = raw
+      out[key] = raw.map(clampTelemetryValue)
     }
   }
   return out
 }
 
 function asPersonProps(value: unknown): Record<string, mainTelemetry.TelemetryValue> {
   if (!value || typeof value !== 'object' || Array.isArray(value)) return {}
   const out: Record<string, mainTelemetry.TelemetryValue> = {}
-  for (const [key, raw] of Object.entries(value)) {
+  for (const [key, raw] of Object.entries(value).slice(0, MAX_TELEMETRY_KEYS)) {
     if (typeof key !== 'string') continue
-    if (isTelemetryValue(raw)) out[key] = raw
+    if (isTelemetryValue(raw)) out[key] = clampTelemetryValue(raw)
   }
   return out
 }

Also applies to: 56-63

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/lib/ipc/registerTelemetryHandlers.ts` around lines 37 - 53, The
asProps/isTelemetryValueArray validation currently accepts unbounded
renderer-controlled objects and arrays; limit work done at the IPC boundary by
enforcing caps: in asProps, stop iterating after a maxKeys threshold (e.g., 50)
and ignore additional keys; in isTelemetryValueArray, cap checked/retained array
length to maxArrayLen (e.g., 20) and only validate/trust up to that many items;
when accepting string TelemetryValue (checked by isTelemetryValue), truncate
strings to a maxStringLen (e.g., 200) before assigning into the returned
mainTelemetry.TelemetryContext; update references to
isTelemetryValue/isTelemetryValueArray and the out assignment logic so oversized
inputs are skipped/truncated rather than fully processed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants