Skip to content

Add privacy-bounded product analytics across ADE surfaces#808

Merged
arul28 merged 3 commits into
mainfrom
ade/okay-start-skill-then-research-16bf822b
Jul 14, 2026
Merged

Add privacy-bounded product analytics across ADE surfaces#808
arul28 merged 3 commits into
mainfrom
ade/okay-start-skill-then-research-16bf822b

Conversation

@arul28

@arul28 arul28 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • add capped, allowlisted PostHog analytics across desktop, runtime, ADE Code, hosted web, native iOS, and the public site
  • add durable consent and opt-out controls, privacy manifests, direct Capture API clients, and release configuration
  • provision five managed dashboards with thirty insights
  • document logging and analytics ground truth and enforce it in /test
  • keep public-site capture direct to PostHog so no Vercel Function, Edge, Web Analytics, or log-drain cost is introduced

Validation

  • quality dual-review and correctness re-review
  • desktop analytics and affected renderer/service tests
  • ADE CLI, RPC, sync, and TUI focused tests
  • 16 targeted iOS tests plus Swift/privacy/config validation
  • public web analytics tests and production build
  • PostHog dashboard spec validation and provisioner tests
  • internal docs validation

Cost controls

  • desktop/runtime/TUI/hosted web share a hard 200 accepted events/day ceiling per installation
  • iOS is capped at 20/day and marketing at 40/day with tighter event/key limits
  • no session replay, autocapture, person profiles, GeoIP, persistent SDK queues, or Vercel server-side analytics path

Summary by CodeRabbit

  • New Features

    • Added anonymous product analytics across desktop, iOS, and web experiences, including screen views, feature usage, errors, pairing, and session activity.
    • Added consent and opt-out controls in desktop, iOS, and website settings or prompts.
    • Added privacy safeguards, event limits, deduplication, and sensitive-data filtering.
    • Added analytics support for paired clients and web sessions.
  • Documentation

    • Documented analytics configuration, privacy behavior, and user controls.
  • Tests

    • Expanded coverage for analytics consent, privacy, budgets, and delivery behavior.

Greptile Summary

This PR adds privacy-bounded product analytics across ADE surfaces. The main changes are:

  • Capped PostHog analytics for desktop, runtime, TUI, hosted web, iOS, and the public site.
  • Durable consent and opt-out controls with local budgets, allowlists, sanitization, and dedupe.
  • Direct Capture API clients, privacy manifests, release configuration, and dashboard provisioning.
  • Usage-ledger export, daily summaries, docs, and focused analytics tests.

Confidence Score: 4/5

Safe to merge after minor redirect hardening.

The reviewed analytics paths apply consent checks, allowlists, local budgets, dedupe, and hashed identifiers. The remaining issue is non-blocking hardening for direct Capture API redirects.

apps/desktop/src/main/services/analytics/productAnalyticsService.ts and apps/web/src/lib/marketingAnalyticsBrowser.ts.

T-Rex T-Rex Logs

What T-Rex did

  • The no-secret local validation path was executed and Trex saved test/build/dev logs under trex-artifacts, recording the command, working directory, and exit status.
  • A pair of videos was captured showing the public site before and after navigating to the privacy analytics control path.
  • Browser request logs from both captures were inspected to confirm there are no _vercel, Vercel Analytics, or external PostHog network calls in this path.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
apps/desktop/src/main/services/analytics/productAnalyticsService.ts Adds the shared PostHog Capture API client, consent state, quota enforcement, dedupe, and sanitization; redirect handling should be tightened to match iOS.
apps/web/src/lib/marketingAnalyticsBrowser.ts Adds direct browser-to-PostHog transport and local consent wiring; it shares the redirect-hardening gap noted for the Node client.
apps/ios/ADE/Services/ProductAnalytics.swift Adds iOS opt-in analytics with closed enums, local daily budgets, no SDK queueing, and explicit redirect cancellation.
apps/ade-cli/src/services/sync/syncHostService.ts Binds paired-client analytics consent and identity to the peer and suppresses opted-out usage rows before export.
apps/desktop/src/main/services/analytics/usageProductAnalyticsExporter.ts Exports eligible local usage ledger rows into bounded product analytics events with consent cutoffs and at-most-once marking.
apps/desktop/src/renderer/components/analytics/ProductAnalyticsLifecycle.tsx Adds renderer lifecycle screen/project capture and hosted-web consent banner behavior.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant UI as Desktop/Web/iOS/TUI UI
  participant Consent as Consent Preference
  participant Host as Runtime/Sync Host
  participant Policy as Analytics Policy + Budget
  participant PH as PostHog Capture API

  UI->>Consent: read or set analytics preference
  UI->>Host: capture screen/feature/app event
  Host->>Policy: bind surface/project, sanitize, dedupe, reserve quota
  alt disabled, unconfigured, invalid, duplicate, or over budget
    Policy-->>Host: dropped reason
    Host-->>UI: capture result
  else accepted
    Policy->>PH: direct capture payload
    PH-->>Policy: HTTP result
    Policy-->>Host: accepted
    Host-->>UI: capture result
  end
  Host->>Policy: usage-ledger export / daily summary
  Policy->>PH: bounded internal analytics events
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant UI as Desktop/Web/iOS/TUI UI
  participant Consent as Consent Preference
  participant Host as Runtime/Sync Host
  participant Policy as Analytics Policy + Budget
  participant PH as PostHog Capture API

  UI->>Consent: read or set analytics preference
  UI->>Host: capture screen/feature/app event
  Host->>Policy: bind surface/project, sanitize, dedupe, reserve quota
  alt disabled, unconfigured, invalid, duplicate, or over budget
    Policy-->>Host: dropped reason
    Host-->>UI: capture result
  else accepted
    Policy->>PH: direct capture payload
    PH-->>Policy: HTTP result
    Policy-->>Host: accepted
    Host-->>UI: capture result
  end
  Host->>Policy: usage-ledger export / daily summary
  Policy->>PH: bounded internal analytics events
Loading

Reviews (3): Last reviewed commit: "ship: iteration 1 — harden cross-process..." | Re-trigger Greptile

@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jul 14, 2026 2:48am

@arul28 arul28 changed the title cross-platform-product-analytics-research -> Primary Add privacy-bounded product analytics across ADE surfaces Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Changes

Analytics contracts and desktop service

Layer / File(s) Summary
Analytics contracts, policy, storage, and export
apps/desktop/src/shared/types/*, apps/desktop/src/main/services/analytics/*, apps/desktop/src/main/services/state/*, apps/desktop/src/main/services/usage/*
Adds typed capture contracts, sanitization, consent, quotas, deduplication, PostHog delivery, usage-event export, and migration support.
Desktop runtime, IPC, sync, and TUI
apps/ade-cli/src/*, apps/desktop/src/main/services/ipc/*, apps/desktop/src/main/services/adeActions/*, apps/desktop/src/main/main.ts
Wires analytics through runtime lifecycle, IPC, paired-client commands, agent-turn events, TUI events, and shutdown handling.
Desktop renderer and web adapter
apps/desktop/src/preload/*, apps/desktop/src/renderer/components/*, apps/desktop/src/renderer/webclient/adapter/*
Adds analytics APIs, consent prompts, settings controls, route tracking, and browser-local consent synchronization.
iOS analytics and instrumentation
apps/ios/ADE/Services/*, apps/ios/ADE/App/*, apps/ios/ADE/Views/*, apps/ios/ADETests/*
Adds the iOS analytics service, privacy-bounded transport and policy tests, lifecycle and interaction events, screen tracking, consent controls, and paired-client preference propagation.
Web marketing analytics
apps/web/src/lib/*, apps/web/src/components/*, apps/web/src/app/*
Adds browser marketing analytics with consent, quotas, route and feature tracking, privacy controls, tagged links/buttons, and focused tests.
Build and CI configuration
.github/*, apps/*/tsup.config.ts, apps/web/vite.config.ts, package.json, .agents/skills/test/SKILL.md
Adds PostHog build configuration and validation, CI analytics tests, secure iOS xcconfig handling, and an always-running logging/analytics test gate.
PostHog dashboard management
scripts/posthog/*
Adds a declarative dashboard catalog, validation, secure API access, dry-run and idempotent provisioning, and provisioning tests.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • arul28/ADE#702 — Both changes modify agentChatService.ts turn-finalization behavior and the createAgentChatService integration point.

Suggested labels: desktop, ios, web, docs, ci

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding privacy-bounded product analytics across ADE surfaces.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/okay-start-skill-then-research-16bf822b

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.

@arul28

arul28 commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

@arul28

arul28 commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@arul28
arul28 force-pushed the ade/okay-start-skill-then-research-16bf822b branch from a840079 to d47a58c Compare July 14, 2026 02:09

@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: d47a58cb23

ℹ️ 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".

if (key === "action") {
if (typeof value !== "string" || value.length > 256) return null;
const raw = value.trim();
return raw === "open" || isMeaningfulUsageAction(raw) ? raw.toLowerCase() : null;

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 Preserve canonical action values

When the usage exporter sends any of the camelCase actions that already passed isMeaningfulUsageAction (for example work.startCliSession, chat.respondToInput, or lanes.createFromUnstaged), this lowercases the value before it reaches PostHog. Those values no longer match the canonical action taxonomy used by the local ledger and docs, so action breakdowns or filters will split/miss those events; preserve the validated raw action value or define a separate lowercase taxonomy consistently.

Useful? React with 👍 / 👎.

Comment on lines +745 to +747
const uuid = input.clientEventId?.length === 36 && UUID_VALUE.test(input.clientEventId)
? input.clientEventId.toLowerCase()
: randomUUID();

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 Regenerate non-random client event IDs

For IPC/sync/TUI/web captures that provide clientEventId, this forwards any UUID version 1-8 verbatim as PostHog's uuid. Version 1 UUIDs can contain a node/MAC identifier and time-ordered UUIDs expose timestamps, so a client-supplied insert id can bypass the content-free analytics boundary; accept only random v4 IDs generated by ADE or regenerate/hash anything else before sending.

Useful? React with 👍 / 👎.

@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: 8

🧹 Nitpick comments (4)
apps/ade-cli/src/tuiClient/productAnalytics.ts (1)

17-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding unit tests for deriveTuiAnalyticsScreen.

This pure function has several priority-ordered branches that silently determine analytics screen attribution; a small table-driven test would guard against regressions when new panes/states are added.

🤖 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 `@apps/ade-cli/src/tuiClient/productAnalytics.ts` around lines 17 - 28, Add a
table-driven unit test for deriveTuiAnalyticsScreen covering each
priority-ordered branch, including terminal control, drawer, details with empty
and non-empty right panes, add mode, grid view, and the default chat screen.
Assert the expected screen identifier for each input and include
overlapping-state cases to verify the existing precedence order.
apps/ade-cli/src/adeRpcServer.ts (1)

3341-3350: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Duplicated isUserClient gate; also verify it classifies TUI/CLI sessions correctly.

The 4-line isUserClient check is duplicated verbatim between the listing filter and the invocation gate. Extracting a shared helper avoids the two enforcement points drifting apart if identity-shape semantics change later. Separately, please confirm that interactive TUI sessions (which call analytics.capture via apps/ade-cli/src/tuiClient/productAnalytics.ts) are actually classified as isUserClient (i.e. never carry chatSessionId/runId/stepId/attemptId) across both the headless CLI and the desktop socket-backed ADE RPC path — otherwise legitimate product-analytics capture could be silently rejected.

♻️ Proposed helper extraction
+function isUserClientSession(session: SessionState): boolean {
+  return !session.identity.runId
+    && !session.identity.stepId
+    && !session.identity.attemptId
+    && !session.identity.chatSessionId;
+}
+
 // list_ade_actions
-    const isUserClient = !session.identity.runId
-      && !session.identity.stepId
-      && !session.identity.attemptId
-      && !session.identity.chatSessionId;
+    const isUserClient = isUserClientSession(session);

 // run_ade_action
-    const isUserClient = !session.identity.runId
-      && !session.identity.stepId
-      && !session.identity.attemptId
-      && !session.identity.chatSessionId;
+    const isUserClient = isUserClientSession(session);

Also applies to: 3398-3401

🤖 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 `@apps/ade-cli/src/adeRpcServer.ts` around lines 3341 - 3350, Extract the
repeated identity-shape check into a shared helper near the affected listing and
invocation logic, and use it for both analytics action filtering and the
invocation gate. Verify the helper classifies headless CLI, interactive TUI, and
desktop socket-backed sessions as user clients when identity.runId, stepId,
attemptId, and chatSessionId are all absent; preserve rejection for sessions
carrying any of those fields.

Source: Path instructions

apps/web/vite.config.ts (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate PostHog token-validation regex across two build configs. apps/web/vite.config.ts and apps/desktop/tsup.config.ts both hardcode the identical /^phc_[A-Za-z0-9_-]{8,}$/ regex and error message; extracting a small shared helper would prevent the two copies from drifting if the token format or messaging changes.

  • apps/web/vite.config.ts#L1-15: import a shared assertPublicPostHogToken(token) helper (e.g. from a small shared Node util) instead of inlining the regex/throw here.
  • apps/desktop/tsup.config.ts#L3-6: use the same shared helper instead of its own copy of the regex/throw.
🤖 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 `@apps/web/vite.config.ts` at line 1, Extract the duplicated PostHog token
validation from the web Vite configuration and desktop tsup configuration into a
shared Node utility exposing assertPublicPostHogToken(token). Update both
configuration entry points to import and call this helper, removing their local
regex and error-message implementations while preserving the existing validation
behavior.
apps/web/src/app/pages/TermsPage.tsx (1)

5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the shared ANALYTICS_FEATURE_ATTRIBUTE constant instead of hardcoding the attribute name.

ShipShowcase.tsx (same PR) applies this attribute via the exported ANALYTICS_FEATURE_ATTRIBUTE constant; this file hardcodes the literal data-ade-analytics-feature string instead. If the attribute name ever changes in marketingAnalytics.ts, this file's links will silently stop being tracked while other call sites keep working.

♻️ Proposed fix
-import { MARKETING_FEATURES } from "../../lib/marketingAnalytics";
+import { ANALYTICS_FEATURE_ATTRIBUTE, MARKETING_FEATURES } from "../../lib/marketingAnalytics";
-                  <a className="focus-ring rounded-md text-muted-fg hover:text-fg" href={LINKS.github} data-ade-analytics-feature={MARKETING_FEATURES.VIEW_GITHUB} target="_blank" rel="noreferrer">
+                  <a className="focus-ring rounded-md text-muted-fg hover:text-fg" href={LINKS.github} {...{ [ANALYTICS_FEATURE_ATTRIBUTE]: MARKETING_FEATURES.VIEW_GITHUB }} target="_blank" rel="noreferrer">
                     GitHub
                   </a>
-                  <a className="focus-ring rounded-md text-muted-fg hover:text-fg" href={LINKS.docs} data-ade-analytics-feature={MARKETING_FEATURES.VIEW_DOCS} target="_blank" rel="noreferrer">
+                  <a className="focus-ring rounded-md text-muted-fg hover:text-fg" href={LINKS.docs} {...{ [ANALYTICS_FEATURE_ATTRIBUTE]: MARKETING_FEATURES.VIEW_DOCS }} target="_blank" rel="noreferrer">
                     Docs
                   </a>

Also applies to: 49-49, 52-52

🤖 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 `@apps/web/src/app/pages/TermsPage.tsx` at line 5, Update the TermsPage link
attributes to use the shared ANALYTICS_FEATURE_ATTRIBUTE constant imported from
marketingAnalytics instead of the hardcoded data-ade-analytics-feature string.
Apply this consistently to all affected links while preserving their existing
analytics values.
🤖 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 `@apps/ade-cli/src/services/sync/syncHostService.ts`:
- Around line 431-432: Preserve peer analytics consent across project-host
handoffs: update the handoff snapshot construction in dispose() to include
productAnalyticsEnabled, and restore it in adoptHandedOffPeers() alongside
rosterSubscribed using the existing fail-closed boolean behavior. Keep
registerPeer’s default for genuinely new connections unchanged.

In `@apps/ade-cli/src/services/sync/syncRemoteCommandService.ts`:
- Around line 4742-4780: Register an `analytics.flush` handler alongside the
existing analytics handlers in `syncRemoteCommandService` that delegates to
`productAnalyticsService.flush()` and safely handles the service being
unconfigured, so the shutdown action invoked by `app.tsx` succeeds and drains
queued analytics. The `app.tsx` call site requires no direct change.

In `@apps/desktop/src/main/services/analytics/dailyUsageAnalytics.ts`:
- Around line 105-127: Update the overall capture in captureDailyUsageAnalytics
to derive provider_count and model_count from the same fallback arrays used
elsewhere: prefer stats.adeProviders and stats.adeModels, falling back to
stats.providers and stats.models. Preserve the existing count behavior while
ensuring these totals match the arrays used for topProvider and topModel
aggregation.

In `@apps/desktop/src/main/services/analytics/productAnalyticsService.ts`:
- Around line 748-783: Update the synchronous failure handling in the
posthog.capture flow to roll back the quota reservation before recording the
transport_error drop. Decrement state.quota.accepted and
state.quota.acceptedByEvent[input.event], remove the corresponding recent
timestamp from state.quota.minuteWindows[input.event], and clear the dedupe
entry when applicable, then persist the corrected state and return the existing
rejection result.
- Around line 302-333: Replace the blocking Atomics.wait retry in
acquireStateLock with a non-blocking retry/backoff mechanism, such as scheduling
subsequent lock attempts asynchronously, while preserving stale-lock cleanup,
the waitMs deadline, and null-on-timeout behavior. Update the callers capture,
getStatus, and setEnabled as needed so lock acquisition never blocks the
Electron main process.

In `@apps/desktop/src/main/services/ipc/registerIpc.ts`:
- Around line 2058-2075: Wrap the error-path productAnalyticsService?.capture
call in the global IPC error interceptor with its own try/catch, matching the
protected success-path capture nearby. Ensure any synchronous analytics
exception is contained so the interceptor still rethrows the original error
unchanged.

In `@apps/desktop/src/renderer/webclient/adapter/analytics.ts`:
- Around line 88-112: The failed consent path in syncClientConsent must not
immediately tear down the shared infra.client connection. Replace the direct
disconnect in the catch block with retry handling for the
analytics.setClientEnabled request, and only apply a narrowly scoped disconnect
after the final retry failure if required to preserve fail-closed behavior; keep
unrelated pairing, session, and lane RPCs connected.

In `@scripts/posthog/provision.mjs`:
- Around line 471-477: Update the top-level catch in the isDirectRun block to
redact using the same trimmed API key value produced by configFromEnv, rather
than the raw process.env[API_KEY_ENV] value. Reuse the existing normalized
configuration or trimming logic so redaction matches the runtime key while
preserving current error handling.

---

Nitpick comments:
In `@apps/ade-cli/src/adeRpcServer.ts`:
- Around line 3341-3350: Extract the repeated identity-shape check into a shared
helper near the affected listing and invocation logic, and use it for both
analytics action filtering and the invocation gate. Verify the helper classifies
headless CLI, interactive TUI, and desktop socket-backed sessions as user
clients when identity.runId, stepId, attemptId, and chatSessionId are all
absent; preserve rejection for sessions carrying any of those fields.

In `@apps/ade-cli/src/tuiClient/productAnalytics.ts`:
- Around line 17-28: Add a table-driven unit test for deriveTuiAnalyticsScreen
covering each priority-ordered branch, including terminal control, drawer,
details with empty and non-empty right panes, add mode, grid view, and the
default chat screen. Assert the expected screen identifier for each input and
include overlapping-state cases to verify the existing precedence order.

In `@apps/web/src/app/pages/TermsPage.tsx`:
- Line 5: Update the TermsPage link attributes to use the shared
ANALYTICS_FEATURE_ATTRIBUTE constant imported from marketingAnalytics instead of
the hardcoded data-ade-analytics-feature string. Apply this consistently to all
affected links while preserving their existing analytics values.

In `@apps/web/vite.config.ts`:
- Line 1: Extract the duplicated PostHog token validation from the web Vite
configuration and desktop tsup configuration into a shared Node utility exposing
assertPublicPostHogToken(token). Update both configuration entry points to
import and call this helper, removing their local regex and error-message
implementations while preserving the existing validation behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 85480d54-4295-48ce-8c32-a9a32c0a76c8

📥 Commits

Reviewing files that changed from the base of the PR and between c6d56cb and a84007984e0fc13b0b7a4e721be1a835b53b3cc2.

⛔ Files ignored due to path filters (8)
  • apps/ios/ADE.xcodeproj/project.pbxproj is excluded by !**/*.xcodeproj/project.pbxproj
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/README.md is excluded by !docs/**
  • docs/features/ade-code/README.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
  • docs/features/web-client/README.md is excluded by !docs/**
  • docs/logging.md is excluded by !docs/**
📒 Files selected for processing (106)
  • .agents/skills/test/SKILL.md
  • .github/scripts/ios-testflight-internal-build-bump-asc.sh
  • .github/workflows/ci.yml
  • .github/workflows/ios-testflight-internal-build-bump-self-hosted.yml
  • .github/workflows/release-core.yml
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/services/sync/productAnalyticsRemoteCommand.ts
  • apps/ade-cli/src/services/sync/syncHostService.test.ts
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.test.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/ade-cli/src/services/sync/syncService.ts
  • apps/ade-cli/src/tuiClient/__tests__/appPolling.test.tsx
  • apps/ade-cli/src/tuiClient/app.tsx
  • apps/ade-cli/src/tuiClient/cli.tsx
  • apps/ade-cli/src/tuiClient/productAnalytics.ts
  • apps/ade-cli/tsup.config.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/analytics/agentTurnProductAnalytics.ts
  • apps/desktop/src/main/services/analytics/dailyUsageAnalytics.ts
  • apps/desktop/src/main/services/analytics/productAnalyticsPolicy.ts
  • apps/desktop/src/main/services/analytics/productAnalyticsService.test.ts
  • apps/desktop/src/main/services/analytics/productAnalyticsService.ts
  • apps/desktop/src/main/services/analytics/usageProductAnalyticsExporter.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/state/kvDb.migrations.test.ts
  • apps/desktop/src/main/services/state/kvDb.ts
  • apps/desktop/src/main/services/usage/usageStatsStore.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/analytics/ProductAnalyticsLifecycle.tsx
  • apps/desktop/src/renderer/components/app/AppShell.aiStatus.test.tsx
  • apps/desktop/src/renderer/components/app/AppShell.tsx
  • apps/desktop/src/renderer/components/settings/GeneralSection.tsx
  • apps/desktop/src/renderer/components/settings/ProductAnalyticsSection.tsx
  • apps/desktop/src/renderer/webclient/adapter/__tests__/adapter.test.ts
  • apps/desktop/src/renderer/webclient/adapter/analytics.ts
  • apps/desktop/src/renderer/webclient/adapter/index.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/types/index.ts
  • apps/desktop/src/shared/types/productAnalytics.ts
  • apps/desktop/src/shared/types/sync.ts
  • apps/desktop/tsup.config.ts
  • apps/ios/ADE/App/ADEApp.swift
  • apps/ios/ADE/App/ADEAppDelegate.swift
  • apps/ios/ADE/App/ContentView.swift
  • apps/ios/ADE/App/DeepLinkRouter.swift
  • apps/ios/ADE/Info.plist
  • apps/ios/ADE/PrivacyInfo.xcprivacy
  • apps/ios/ADE/Services/Dictation/DictationController.swift
  • apps/ios/ADE/Services/ProductAnalytics.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADE/Views/Components/GlobalDictationPill.swift
  • apps/ios/ADE/Views/Cto/CtoSettingsScreen.swift
  • apps/ios/ADE/Views/Files/FilesDetailScreen.swift
  • apps/ios/ADE/Views/Files/FilesSearchScreen.swift
  • apps/ios/ADE/Views/Lanes/LaneDetailScreen.swift
  • apps/ios/ADE/Views/PRs/CreatePrWizardView.swift
  • apps/ios/ADE/Views/PRs/PrDetailScreen.swift
  • apps/ios/ADE/Views/PersonalChats/PersonalChatsScreen.swift
  • apps/ios/ADE/Views/Settings/ConnectionSettingsView.swift
  • apps/ios/ADE/Views/Settings/SettingsAnalyticsSection.swift
  • apps/ios/ADE/Views/Work/TerminalSessionScreen.swift
  • apps/ios/ADE/Views/Work/WorkNewChatScreen.swift
  • apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift
  • apps/ios/ADEClip/PrivacyInfo.xcprivacy
  • apps/ios/ADETests/ADETests.swift
  • apps/ios/ADETests/ProductAnalyticsPolicyTests.swift
  • apps/ios/ADEWidgets/PrivacyInfo.xcprivacy
  • apps/ios/Scripts/validate-posthog-project-token.sh
  • apps/web/.env.example
  • apps/web/README.md
  • apps/web/package.json
  • apps/web/src/app/App.tsx
  • apps/web/src/app/pages/DownloadPage.tsx
  • apps/web/src/app/pages/NotFoundPage.tsx
  • apps/web/src/app/pages/OpenPage.tsx
  • apps/web/src/app/pages/PairPage.tsx
  • apps/web/src/app/pages/PrivacyPage.tsx
  • apps/web/src/app/pages/TermsPage.tsx
  • apps/web/src/components/CopyButton.tsx
  • apps/web/src/components/LinkButton.tsx
  • apps/web/src/components/MarketingAnalyticsBridge.tsx
  • apps/web/src/components/SiteFooter.tsx
  • apps/web/src/components/SiteHeader.tsx
  • apps/web/src/components/editorial/BackCover.tsx
  • apps/web/src/components/editorial/FeatureGrid.tsx
  • apps/web/src/components/editorial/Lede.tsx
  • apps/web/src/components/editorial/Masthead.tsx
  • apps/web/src/components/editorial/ShipShowcase.tsx
  • apps/web/src/lib/marketingAnalytics.test.ts
  • apps/web/src/lib/marketingAnalytics.ts
  • apps/web/src/lib/marketingAnalyticsBrowser.ts
  • apps/web/tsconfig.json
  • apps/web/vite.config.ts
  • package.json
  • scripts/posthog/dashboard-spec.mjs
  • scripts/posthog/provision.mjs
  • scripts/posthog/provision.test.mjs

Comment thread apps/ade-cli/src/services/sync/syncHostService.ts
Comment thread apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
Comment thread apps/desktop/src/main/services/analytics/dailyUsageAnalytics.ts
Comment thread apps/desktop/src/main/services/analytics/productAnalyticsService.ts Outdated
Comment thread apps/desktop/src/main/services/analytics/productAnalyticsService.ts
Comment thread apps/desktop/src/main/services/ipc/registerIpc.ts
Comment thread apps/desktop/src/renderer/webclient/adapter/analytics.ts
Comment thread scripts/posthog/provision.mjs
@arul28

arul28 commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@arul28
arul28 force-pushed the ade/okay-start-skill-then-research-16bf822b branch from d47a58c to 3bfdf3e Compare July 14, 2026 02:42
@arul28

arul28 commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 14712b27a1

ℹ️ 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".

@arul28
arul28 merged commit 075a82c into main Jul 14, 2026
33 checks passed
@arul28
arul28 deleted the ade/okay-start-skill-then-research-16bf822b branch July 14, 2026 03:24
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.

1 participant