Skip to content

fix(sentry): auto-send React events; collapse core→tauri for desktop#1086

Merged
senamakel merged 9 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/405-sentry-followups
May 1, 2026
Merged

fix(sentry): auto-send React events; collapse core→tauri for desktop#1086
senamakel merged 9 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/405-sentry-followups

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 1, 2026

Summary

  • React Sentry now auto-sends sanitized events to openhuman-react instead of queueing them behind a user-opt-in notification — pre-feat(sentry): split errors into per-surface projects (react, core, tauri) #1032 the trickle that landed in Sentry came from users occasionally clicking "Send"; post-split the trickle dried up across three projects, so this PR flips React to classic auto-send (still consent-gated + privacy-stripped).
  • Removes the errorReportQueue + ErrorReportNotification opt-in scaffolding (the in-app toast + queue) and rewires the one user-facing call site (OAuth stale-app version) to Sentry.captureMessage + console.warn.
  • Collapses the desktop openhuman-core Sentry surface into openhuman-tauri because since fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q #1061 the core lives in-process inside the Tauri shell binary — one Rust process → one sentry::init → one hub. Repoints the Rust DIF upload step accordingly.
  • Adds a VITE_SENTRY_SMOKE_TEST env-gated one-shot trigger mirroring the existing OPENHUMAN_TAURI_SENTRY_TEST so the pipeline can be verified end-to-end.

Problem

After #1032 split errors into three projects (openhuman-react / openhuman-tauri / openhuman-core), all three projects went silent — the user reported zero events captured in the last 2 hours across all three. Diagnosis surfaced three independent issues, ordered by impact:

  1. React opt-in gate is the dominant cause of silence. analytics.ts::beforeSend returns null for every event unless _bypassBeforeSend = true, queueing each event in errorReportQueue for user approval via ErrorReportNotification. Pre-feat(sentry): split errors into per-surface projects (react, core, tauri) #1032 a single project occasionally received approved events; post-split the same trickle is now divided across three projects and effectively dries up.
  2. openhuman-core is structurally dead in the desktop build. PR fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q #1061 made the core a library linked into the Tauri shell (path dep openhuman_core in app/src-tauri/Cargo.toml:114). src/main.rs::main() — the only place that calls sentry::init for OPENHUMAN_SENTRY_DSN — only runs for the standalone CLI (release-packages.yml Linux-arm64, Docker). When openhuman_core code emits tracing::error! or calls sentry::capture_* inside the desktop app, the active Sentry hub is the Tauri shell's, so events route to openhuman-tauri, not openhuman-core.
  3. Workflow was uploading desktop Rust DIFs to the wrong project. Both release.yml and release-staging.yml were uploading the Tauri shell binary's debug info (which covers the linked-in core too) to vars.SENTRY_PROJECT_CORE — a project that no events from the desktop binary ever land in.

Solution

React: auto-send with privacy-preserving sanitization (app/src/services/analytics.ts)

beforeSend now returns the (sanitized) event instead of null:

  • Consent gate: drop events when isAnalyticsEnabled() is false (reads coreState.analyticsEnabled per-event, so toggling consent in Settings takes effect immediately).
  • PII strip: sendDefaultPii: false (no IP, no cookies); reduce event.user to a stable anonymous id only.
  • State strip: wipe breadcrumbs / request / extras; restrict event.contexts to {os, browser, device} (drops anything that could carry Redux / localStorage state).
  • Frame strip: delete vars / context_line / pre_context / post_context / mechanism.data from every stack frame so live local values + raw source snippets never leave the user's machine.
  • Tag: every event tagged surface: "react".

Defaults that already enforce privacy stay: no breadcrumb-producing integrations (defaultIntegrations: false + a hand-picked allowlist), no replays, no traces.

Removed dead scaffolding

errorReportQueue.ts (+ tests), ErrorReportNotification.tsx, the second React root in main.tsx, and the tagErrorSource ErrorBoundary callback in App.tsx are all gone. The OAuth stale-app version notification in desktopDeepLinkListener.ts (which was the last in-app caller of enqueueError) is rewired to call Sentry.captureMessage(..., { level: 'warning', tags: ... }) + console.warn — preserves the Sentry signal, drops the in-app toast (the user already opens the download URL externally).

Workflow: collapse core → tauri for desktop builds

  • release.yml — renames "Upload core sidecar debug symbols" → "Upload Rust debug symbols (tauri project)" and points it at vars.SENTRY_PROJECT_TAURI. Comments updated to explain the in-process consequence.
  • release-staging.yml — splits the upload into two steps: Tauri shell DIFs (app/src-tauri/target/<triple>/debug) → SENTRY_PROJECT_TAURI; standalone CLI DIFs (target/<triple>/debug, built by the existing "Build sidecar core binary" step) → SENTRY_PROJECT_CORE. The CLI still has its own sentry::init in src/main.rs and routes to openhuman-core for any operator running it.
  • release-packages.yml unchanged — the Linux-arm64 standalone CLI genuinely uses OPENHUMAN_SENTRY_DSN and routes to openhuman-core.

Smoke trigger

VITE_SENTRY_SMOKE_TEST=true in the build env fires one react-sentry-smoke-test info event at initSentry() time. Mirrors the existing OPENHUMAN_TAURI_SENTRY_TEST=panic|message trigger at app/src-tauri/src/lib.rs:838. Documented in app/.env.example. Set for one staging build to verify, then remove.

Known limitation (deliberately deferred)

The Tauri shell's sentry::init captures panics (via sentry::panic_integration) and explicit captures, but plain tracing::error! from linked-in core code is not auto-routed to Sentry inside the desktop binary — init_for_cli_run (which installs the sentry-tracing layer at src/core/logging.rs:198) only runs for the openhuman run/serve CLI subcommands, not the in-process run_server_embedded path. Closing this gap means installing sentry::integrations::tracing::layer() inside the Tauri shell process before the core boots; flagged for a follow-up rather than expanding this PR.

Submission Checklist

  • Tests added or updatederrorReportQueue.test.ts removed alongside the module it tested. The remaining analytics.ts change is config (no logic worth unit-testing); the smoke trigger is env-gated dispatch verified manually. All 1033 existing unit tests still pass (pnpm test:unit).
  • N/A coverage matrix — observability/Sentry wiring isn't a feature row in docs/TEST-COVERAGE-MATRIX.md; this changes how events are dispatched, not user-visible behaviour.
  • N/A network deps — no new outbound calls; Sentry.captureEvent already exists.
  • N/A manual smoke checklist — Sentry is observability infrastructure, not a release-cut surface in docs/RELEASE-MANUAL-SMOKE.md.
  • Linked issue — see ## Related.

Impact

  • Runtime (React): events that previously sat in the in-app queue waiting for user approval now auto-flow to Sentry (sanitized, consent-gated). Users who opted out of analytics see no behavioural change. Users with consent on will silently produce error events — same as classic Sentry behaviour; no UI change.
  • Runtime (Rust): zero change to capture paths. Only the destination project of debug-info uploads moves from openhuman-core to openhuman-tauri for the desktop build.
  • Bundle size: −~900 net lines of TS removed (queue + notification component + their tests). Tiny shrink.
  • Backwards compat: vars.OPENHUMAN_CORE_SENTRY_DSN and vars.SENTRY_PROJECT_CORE are no longer read by release.yml and only referenced by release-staging.yml for the standalone CLI upload + by release-packages.yml. Safe to keep — they still apply to CLI surfaces.
  • Privacy posture: equivalent to before. The same fields are stripped; the only difference is that sanitized events now reach Sentry automatically instead of waiting for user approval. Consent gate (isAnalyticsEnabled()) is now enforced inside beforeSend on every event.

Related

  • Closes:
  • Follow-up PR(s)/TODOs:
    • Install sentry::integrations::tracing::layer() in the Tauri shell process so tracing::error! from in-process core code auto-routes to openhuman-tauri (current behaviour: only panics + explicit captures reach Sentry).
    • Decide whether the standalone openhuman-core CLI (Docker / Linux-arm64 / Homebrew) keeps its own Sentry project or also collapses into openhuman-tauri once the desktop split settles.
    • Verify end-to-end on the next staging build with VITE_SENTRY_SMOKE_TEST=true + OPENHUMAN_TAURI_SENTRY_TEST=message, then remove the smoke env vars.

Summary by CodeRabbit

  • New Features

    • Added optional smoke-test toggle for end-to-end Sentry connectivity and release tagging verification.
  • Bug Fixes

    • Switched to consent-gated automatic Sentry error sending; removed the per-error review queue and on-screen error-report notifications.
    • Simplified stale-app OAuth handling to report warnings directly to Sentry.
  • Chores

    • Updated CI workflows for more accurate Sentry debug-symbol uploads and release tagging.
  • Tests

    • Removed legacy tests for the removed error-report queue.

…ansai#405)

Five small additive changes that finish the source-context work for tinyhumansai#405
on top of tinyhumansai#1032's per-surface project split.

1. **`debug-images` feature enabled** in the `sentry` crate for both the
   core (`Cargo.toml`) and the Tauri shell (`app/src-tauri/Cargo.toml`).
   Registers `DebugImagesIntegration` in the default integration set, so
   events arrive with `debug_meta.images` populated and Sentry's
   symbolicator can match the uploaded DIFs to attach `pre_context` /
   `context_line` / `post_context` to each frame. Without this, panics
   render with bare `function_name + 0xNNN` even when DIFs uploaded
   successfully.
2. **`[profile.release]` set to emit DWARF** in both Cargo manifests:
   `debug = "line-tables-only"` (file+line tables, no full type info)
   and `split-debuginfo = "packed"` (writes a `.dSYM` bundle on macOS so
   the shipped binary stays slim). Cargo's default `debug = false` for
   release left binaries with no DWARF at all — `sentry-cli upload-dif
   --include-sources` (already on main from tinyhumansai#1032) had nothing to ship.
3. **`SENTRY_RELEASE` aligned with runtime truncation.** `config.ts`,
   `vite.config.ts`, `main.rs`, and `app/src-tauri/src/lib.rs` all slice
   `VITE_BUILD_SHA` / `OPENHUMAN_BUILD_SHA` to 12 chars when computing
   the release tag at runtime, but `release.yml` was passing the full
   40-char SHA into `SENTRY_RELEASE` for both the Vite build and the
   symbols-upload step. The Vite plugin and `sentry-cli` use
   `SENTRY_RELEASE` raw, so artifacts attached to
   `openhuman@<v>+<40char>` while events emitted
   `openhuman@<v>+<12char>` — different releases, no symbolication.
   Added a `short_sha` output to `prepare-build` (sliced to 12 chars in
   the resolve step) and use it in both `SENTRY_RELEASE`
   constructions.
4. **Per-release Sentry deploy marker.** New `Record Sentry deploy
   marker` step in `release.yml` that runs once per matrix target after
   the upload step, calling `sentry-cli releases deploys ... new` with
   `SENTRY_ENVIRONMENT` derived from `inputs.build_target`. Closes
   tinyhumansai#405's "release page links commits → deploys" criterion. Kept out of
   `upload_sentry_symbols.sh` to avoid duplicate markers when the
   script is invoked multiple times in a release lifecycle —
   `sentry-cli releases deploys new` does NOT deduplicate by
   (release, env), so re-running CI for the same release adds a new row
   each time.
5. **`sentry-cli 3.x` log-level compat.** Changed
   `--log-level=warning` to `--log-level=warn` in
   `upload_sentry_symbols.sh`. The full word was rejected as
   `invalid value '...' for '--log-level'` on 3.x and the script
   silently skipped uploads (logged "Some debug symbols may have failed
   to upload" but no DIFs were actually pushed).

Plus housekeeping:
- `scripts/ci-secrets.example.json` updated to the per-surface vars
  `release.yml` actually reads now (`SENTRY_PROJECT_REACT/CORE/TAURI`,
  `OPENHUMAN_REACT/CORE/TAURI_SENTRY_DSN`). Legacy
  `OPENHUMAN_SENTRY_DSN` / `VITE_SENTRY_DSN` /
  `SENTRY_PROJECT(_FRONTEND)` keys removed (no longer read since tinyhumansai#1032).
- `docs/sentry.md` rewrites the surface list, adds a Rust source-context
  section explaining `debug-images` + the DWARF profile + the upload
  lifecycle, updates the required-vars table to the per-surface set, and
  adds troubleshooting entries for the new failure modes.

Cargo.lock files intentionally not modified — the new `debug-images`
feature pulls `findshlibs` transitively, which cargo will resolve into
the lock files on the first build. CI's `cargo build` regenerates them
in place.

Closes tinyhumansai#405. Supersedes tinyhumansai#973 (which was rebased through merging a stale
branch and ended up with diff noise unrelated to the actual fix).
…yhumansai#405)

`release-staging.yml` (added in tinyhumansai#1066) was cutting staging desktop
bundles with **zero** Sentry instrumentation: no `environment:`
declaration on its jobs, no `VITE_SENTRY_DSN` / `OPENHUMAN_TAURI_SENTRY_DSN`
threaded into the Tauri build step, no `SENTRY_AUTH_TOKEN` for source-map
upload, and no symbol-upload / deploy-marker steps. Net effect: the
staging build's `Sentry.init` short-circuits in
`app/src/services/analytics.ts` (`if (!SENTRY_DSN) return;`), and the
Rust core / Tauri shell `option_env!` lookups resolve to empty — so the
shipped staging app reports nothing to Sentry, ever.

This mirrors the existing wiring on `release.yml`'s build-desktop path:

- Both `prepare-build` and `build-desktop` declare `environment:
  Production` so the same `vars.OPENHUMAN_REACT_SENTRY_DSN` /
  `OPENHUMAN_TAURI_SENTRY_DSN` / `SENTRY_PROJECT_REACT/CORE` /
  `SENTRY_ORG` and `secrets.SENTRY_AUTH_TOKEN` already provisioned for
  production resolve here. Staging builds tag events with
  `environment: staging` at runtime (set by `APP_ENVIRONMENT` in
  `config.ts` and `resolve_sentry_environment()` in the Rust shell), so
  Sentry can filter them without separate projects.
- `prepare-build` exposes a `short_sha` output (first 12 chars of `sha`)
  for the canonical release tag. Matches the runtime truncation in
  `config.ts` / `vite.config.ts` / `main.rs` / `app/src-tauri/src/lib.rs`
  so uploaded source maps + DIFs attach to the same release events
  emit.
- `Build and package Tauri app` step now passes `VITE_SENTRY_DSN`,
  `OPENHUMAN_TAURI_SENTRY_DSN`, `OPENHUMAN_BUILD_SHA`, `VITE_BUILD_SHA`,
  `SENTRY_RELEASE` (with `short_sha`), `SENTRY_AUTH_TOKEN`,
  `SENTRY_ORG`, `SENTRY_PROJECT` so `@sentry/vite-plugin` can upload
  source maps for `openhuman-react` and the Tauri shell binary has its
  DSN baked in.
- New `Upload core sidecar debug symbols to Sentry` step reads from
  `app/src-tauri/target/<triple>/debug/deps` (not `release/deps` as on
  production) since staging builds with `--debug`.
- New `Record Sentry deploy marker` step fires once per matrix target
  with `SENTRY_ENVIRONMENT=staging`, satisfying the same release-page
  link as production.

Closes the staging half of tinyhumansai#405's "every production/staging event
includes a valid release and environment" criterion.
…er, no error swallowing

Three fixes from CodeRabbit's review on tinyhumansai#1067:

1. **Deploy marker fires once per release, not once per matrix target.**
   The "Record Sentry deploy marker" step lived inside `build-desktop`
   in both workflows, so the matrix (3 platforms on prod, 4 on staging)
   produced 3-4 deploy rows per release instead of 1.
   `sentry-cli releases deploys ... new` does NOT deduplicate by
   (release, env), so each call really did add a new row. Moved the
   marker into a dedicated `record-sentry-deploy` job that
   `needs: [prepare-build, build-desktop]` and runs on a single
   `ubuntu-latest` runner — exactly one row per release.
2. **Stopped swallowing deploy-marker failures.** Both workflows had a
   trailing `|| { echo "[WARN] deploy marker failed (non-fatal)"; }`
   that turned auth/org/release misconfig into a silent green build —
   exactly the "fail clearly on misconfig" anti-pattern tinyhumansai#405's
   acceptance criteria warn against. With `set -euo pipefail` the
   sentry-cli call now fails the job loudly.
3. **release-staging.yml also uploads root target's DIFs.** Staging
   builds both the Tauri shell (`app/src-tauri/target/<triple>/debug`)
   AND a standalone `openhuman-core` CLI binary
   (`target/<triple>/debug`) that's published as a separate artifact
   for operators. The upload step previously only scanned the shell's
   target dir, so crashes from the standalone CLI couldn't symbolicate.
   Now loops over both. Symbols are debug-ID-keyed so upload from both
   binaries to the same Sentry project doesn't collide.

The fourth review comment (template `OPENHUMAN_CORE_SENTRY_DSN` vs
runtime `OPENHUMAN_SENTRY_DSN`) is correct as a runtime/template gap
in isolation, but `release.yml:484` already aliases
`OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN }}` — the
template lists GH Actions var names (matching workflow consumption),
not runtime env var names, so the existing template is correct for its
purpose. Replied on the comment.
…sktop

CodeRabbit caught a real ordering bug on tinyhumansai#1067: the `record-sentry-deploy`
job depended on `build-desktop` directly, so it could run before
`build-docker` / `publish-updater-manifest` finished. If one of those
later phases failed, `cleanup-failed-release` would delete the GitHub
release/tag, but Sentry would already have a deploy row for a release
that never shipped.

Hang off `publish-release` instead. That job already requires the full
matrix + docker + updater manifest to succeed, so the deploy marker
transitively waits for all of them and only fires once the release is
actually published.

`record-sentry-deploy` is unchanged on `release-staging.yml` because that
workflow has no `publish-release` equivalent — its only build phase is
`build-desktop`, so the existing `needs: [prepare-build, build-desktop]`
is already correct.
- React: drop the `beforeSend` opt-in queue and auto-forward sanitized
  events to `openhuman-react`. PII / breadcrumbs / request bodies /
  frame-level locals + source snippets are still stripped, and the
  `isAnalyticsEnabled()` consent check now gates `beforeSend`. Tag
  every event with `surface: "react"`. Add a `VITE_SENTRY_SMOKE_TEST`
  one-shot trigger for verifying the pipeline end-to-end.
- Delete `errorReportQueue` + `ErrorReportNotification` (the user-opt-in
  scaffolding) and the OAuth stale-app-version `enqueueError` call —
  replaced with a direct `Sentry.captureMessage` plus `console.warn`.
- Workflow: since tinyhumansai#1061 the core lives in-process inside the Tauri
  shell binary (one process → one `sentry::init` → one hub), so all
  Rust events from the desktop build route to `openhuman-tauri`.
  Repoint the Rust DIF upload step in `release.yml` and the Tauri-shell
  upload in `release-staging.yml` to `vars.SENTRY_PROJECT_TAURI`.
  Standalone `openhuman-core` CLI binary (built by the staging sidecar
  step and by `release-packages.yml`) still uploads to
  `vars.SENTRY_PROJECT_CORE`.
@CodeGhost21 CodeGhost21 requested a review from a team May 1, 2026 21:09
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

Refactors error reporting from a queue-based, user-review pipeline to consent-gated auto-send via Sentry (sanitizing events in beforeSend), removes the queued notification UI and queue module, adjusts React boundary handling, adds a Sentry smoke-test flag, and splits/updates CI Sentry debug-symbol upload steps for Tauri vs core.

Changes

Cohort / File(s) Summary
GitHub Workflows
.​github/workflows/release-staging.yml, .​github/workflows/release.yml
Threads OPENHUMAN_BUILD_SHA into the build step; splits Rust debug-symbol uploads into distinct steps/projects (Tauri vs core) and changes upload scan targets and release-tag guidance.
Sentry init & Analytics
app/src/services/analytics.ts, app/.env.example, app/src/utils/config.ts, app/src/vite-env.d.ts
Reworks initSentry()/beforeSend to sanitize events and perform per-event consent gating (auto-send when allowed); adds VITE_SENTRY_SMOKE_TEST config and TypeScript typing.
Error Queue & Tests (deleted)
app/src/services/errorReportQueue.ts, app/src/services/errorReportQueue.test.ts
Removes the module-level error-report queue, its API (enqueue/dequeue/subscribe/etc.), and all associated tests.
React UI / Boundary
app/src/App.tsx, app/src/components/ErrorFallbackScreen.tsx, app/src/components/ErrorReportNotification.tsx
Removes custom onError forwarder from Sentry.ErrorBoundary, deletes the ErrorReportNotification UI component, and updates fallback docs to reflect automatic forwarding.
Entrypoint & Utilities
app/src/main.tsx, app/src/utils/desktopDeepLinkListener.ts
Stops mounting the notification root; replaces enqueueing of manual events with direct Sentry.captureMessage for stale-app OAuth warnings.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant React as React Component
    participant ErrorBoundary as Sentry.ErrorBoundary
    participant SentrySDK as Sentry SDK
    participant beforeSend as beforeSend Hook
    participant SentryBackend as Sentry Backend

    Note over React,SentryBackend: New Flow: Direct Auto-Send with Consent Gating

    React->>ErrorBoundary: Error thrown
    ErrorBoundary->>SentrySDK: Capture exception
    SentrySDK->>beforeSend: Event for processing
    beforeSend->>beforeSend: Check analytics consent
    alt Consent Enabled
        beforeSend->>beforeSend: Sanitize event (clear breadcrumbs,<br/>remove request/extra, trim contexts/vars)
        beforeSend->>SentrySDK: Return sanitized event
        SentrySDK->>SentryBackend: Upload event
    else Consent Disabled
        beforeSend->>SentrySDK: Return null (drop event)
    end
Loading
sequenceDiagram
    autonumber
    participant CI as GitHub Actions
    participant Build as Rust/Tauri Build
    participant Upload as Sentry Upload Step
    participant Sentry as Sentry Projects

    Note over CI,Sentry: CI symbol upload split per-surface

    CI->>Build: Build Tauri shell (includes core)
    CI->>Upload: Upload Tauri debug symbols -> `SENTRY_PROJECT_TAURI`
    CI->>Upload: Upload core CLI debug symbols -> `SENTRY_PROJECT_CORE`
    Upload->>Sentry: DIFs ingested per project with release tag
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1067: Modifies the same release workflows and Rust symbol-upload wiring (per-project targeting and release-tag threading).
  • PR #1032: Makes overlapping changes to Sentry workflow symbol uploads and project assignment for Rust/Tauri artifacts.
  • PR #1061: Adjusts Sentry debug-symbol upload steps for in-process/core-linked builds (related CI changes).

Suggested reviewers

  • senamakel

Poem

🐰 A little hop, a tidy switch of queues,

I scrub the crumbs and brighten Sentry's views.
Consent now guides which whispers should take flight;
CI splits the symbols, keeping tags just right.
Hooray — a squeaky-clean, well-logged delight! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: converting to auto-send React events and merging the core→tauri Sentry surface for desktop builds.
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

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

551-557: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Upload the whole Tauri release target, not just release/deps.

The comment above says the shell target dir is scanned recursively, but this step only hands upload_sentry_symbols.sh app/src-tauri/target/${MATRIX_TARGET}/release/deps. That can skip the shell binary’s own debug files, which is where the linked-in core frames now live after the sidecar collapse, so production desktop Rust crashes can still come through unsymbolicated. This also diverges from .github/workflows/release-staging.yml:366-369, which scans the target dir root.

Suggested fix
-          deps_dir="app/src-tauri/target/${MATRIX_TARGET}/release/deps"
-          if [ -d "$deps_dir" ]; then
-            echo "==> Uploading symbols from $deps_dir to ${SENTRY_PROJECT}"
-            bash scripts/upload_sentry_symbols.sh "$VERSION" "$deps_dir"
+          dif_dir="app/src-tauri/target/${MATRIX_TARGET}/release"
+          if [ -d "$dif_dir" ]; then
+            echo "==> Uploading symbols from $dif_dir to ${SENTRY_PROJECT}"
+            bash scripts/upload_sentry_symbols.sh "$VERSION" "$dif_dir"
           else
-            echo "==> Skipping $deps_dir (not present)"
+            echo "==> Skipping $dif_dir (not present)"
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 551 - 557, The workflow currently
sets deps_dir to "app/src-tauri/target/${MATRIX_TARGET}/release/deps", which
misses the shell binary debug files; change the directory passed to
scripts/upload_sentry_symbols.sh to the Tauri release target root (e.g., set
deps_dir to "app/src-tauri/target/${MATRIX_TARGET}/release" or a new variable
like target_dir) so the upload script scans recursively and includes the shell
binary and linked core frames; keep the existence check and the call to bash
scripts/upload_sentry_symbols.sh "$VERSION" "$target_dir" (preserving
MATRIX_TARGET and VERSION usage).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release-staging.yml:
- Around line 374-394: The build uploads Sentry symbols with a release tag
containing the short SHA, but the standalone CLI binary omits the short SHA
unless OPENHUMAN_BUILD_SHA is set at compile time (see build_release_tag() in
src/main.rs); modify the "Build sidecar core binary" step to export
OPENHUMAN_BUILD_SHA using needs.prepare-build.outputs.short_sha
(OPENHUMAN_BUILD_SHA: ${{ needs.prepare-build.outputs.short_sha }}) so the
compiled binary’s release tag matches the Sentry-uploaded symbols.

In `@app/src/services/analytics.ts`:
- Around line 53-55: beforeSend currently drops all events when
isAnalyticsEnabled() is false which suppresses the one-shot smoke test sent from
initSentry (Sentry.captureMessage('react-sentry-smoke-test', ...)); update
beforeSend in analytics.ts to allow this specific synthetic event through (check
event.message === 'react-sentry-smoke-test' or event.tags?.smoke_test) even when
isAnalyticsEnabled() is false, or alternatively move the Sentry.captureMessage
call in initSentry to fire only after analytics consent is resolved; reference
beforeSend, initSentry, Sentry.captureMessage, isAnalyticsEnabled and
VITE_SENTRY_SMOKE_TEST when making the change.
- Line 108: Replace the direct import.meta.env access in analytics.ts with a
config export from app/src/utils/config.ts: add a boolean (or string) export
like VITE_SENTRY_SMOKE_TEST (or SENTRY_SMOKE_TEST) in utils/config.ts that reads
import.meta.env.VITE_SENTRY_SMOKE_TEST and then import that symbol into
analytics.ts and use it in the if check instead of
import.meta.env.VITE_SENTRY_SMOKE_TEST; update any type/coercion so the
conditional logic in analytics.ts (the existing if) behaves the same.

---

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 551-557: The workflow currently sets deps_dir to
"app/src-tauri/target/${MATRIX_TARGET}/release/deps", which misses the shell
binary debug files; change the directory passed to
scripts/upload_sentry_symbols.sh to the Tauri release target root (e.g., set
deps_dir to "app/src-tauri/target/${MATRIX_TARGET}/release" or a new variable
like target_dir) so the upload script scans recursively and includes the shell
binary and linked core frames; keep the existence check and the call to bash
scripts/upload_sentry_symbols.sh "$VERSION" "$target_dir" (preserving
MATRIX_TARGET and VERSION usage).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4059b2ce-24fb-474f-9554-a75b937c3c37

📥 Commits

Reviewing files that changed from the base of the PR and between 1208503 and 7ecd6a6.

📒 Files selected for processing (12)
  • .github/workflows/release-staging.yml
  • .github/workflows/release.yml
  • app/.env.example
  • app/src/App.tsx
  • app/src/components/ErrorFallbackScreen.tsx
  • app/src/components/ErrorReportNotification.tsx
  • app/src/main.tsx
  • app/src/services/analytics.ts
  • app/src/services/errorReportQueue.test.ts
  • app/src/services/errorReportQueue.ts
  • app/src/utils/desktopDeepLinkListener.ts
  • app/src/vite-env.d.ts
💤 Files with no reviewable changes (4)
  • app/src/main.tsx
  • app/src/components/ErrorReportNotification.tsx
  • app/src/services/errorReportQueue.test.ts
  • app/src/services/errorReportQueue.ts

Comment thread .github/workflows/release-staging.yml
Comment thread app/src/services/analytics.ts Outdated
Comment thread app/src/services/analytics.ts Outdated
senamakel added 3 commits May 1, 2026 14:48
- release.yml: scan release/ root (not release/deps/) for Tauri DIF
  upload so shell binary debug files are included alongside linked core
  frames — fixes unsymbolicated desktop Rust crashes (addresses
  @coderabbitai on .github/workflows/release.yml:551-557)

- release-staging.yml: export OPENHUMAN_BUILD_SHA when building the
  standalone core CLI binary so build_release_tag() produces
  openhuman@<version>+<sha>, matching the Sentry-uploaded symbol release
  tag (addresses @coderabbitai on .github/workflows/release-staging.yml:394)

- analytics.ts: route VITE_SENTRY_SMOKE_TEST through utils/config.ts
  (SENTRY_SMOKE_TEST export) instead of reading import.meta.env directly,
  per the centralized frontend config convention (addresses @coderabbitai
  on app/src/services/analytics.ts:108)

- analytics.ts: bypass the analytics-consent gate in beforeSend for the
  smoke-test event so VITE_SENTRY_SMOKE_TEST validation works on a fresh
  install where consent hasn't been granted yet (addresses @coderabbitai
  on app/src/services/analytics.ts:55)
…dored tauri-build

The vendored CEF tauri-build DebConfig uses deny_unknown_fields and does not
have an `args` field (added in newer upstream Tauri). PR tinyhumansai#1087 merged this
field into main, causing cargo check to fail with "unknown field `args`".
Removing it unblocks rust:check; the X11 launcher flags need to be delivered
via a custom desktop-template or a vendored tauri-utils update instead.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@app/src/services/analytics.ts`:
- Around line 59-101: The beforeSend handler still forwards free-text fields
that can contain PII; update the beforeSend function to sanitize/redact those
fields by removing or replacing event.message, event.logentry, and
exception.values[*].value (and any nested free-text fields) before returning the
event; locate the beforeSend implementation and ensure you also sanitize
event.exception.values array entries (the value property) and any other
top-level string fields that could leak user input so only non-PII identifiers
(tags, user.id) and allowed contexts remain.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: e7870e39-fd92-4fa2-8b50-6749755685c5

📥 Commits

Reviewing files that changed from the base of the PR and between 7ecd6a6 and 2ce7073.

📒 Files selected for processing (4)
  • .github/workflows/release-staging.yml
  • .github/workflows/release.yml
  • app/src/services/analytics.ts
  • app/src/utils/config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/release.yml
  • .github/workflows/release-staging.yml

Comment on lines 59 to +101
beforeSend(event) {
// Bypass mode: let the event through (used by sendEventToSentry)
if (_bypassBeforeSend) {
_bypassBeforeSend = false;
return event;
}

// --- Sanitize the event ---
// Always allow the smoke-test event through so pipeline validation works
// even when the user hasn't opted into analytics yet on first boot.
const isSmokeTest = event.message === 'react-sentry-smoke-test';
// Drop events when the user hasn't opted into analytics.
if (!isSmokeTest && !isAnalyticsEnabled()) return null;

// Strip any breadcrumbs that somehow snuck in
// Strip anything that could carry Redux / localStorage / request bodies.
event.breadcrumbs = [];

// Strip request data (cookies, headers, body)
delete event.request;

// Strip user PII — keep only a stable anonymous ID
const userId = getCoreStateSnapshot().snapshot.currentUser?._id;
event.user = userId ? { id: userId } : undefined;

// Strip any extra/contexts that could contain Redux or localStorage data
delete event.extra;
event.contexts = {
// Keep only OS / browser / device metadata
os: event.contexts?.os,
browser: event.contexts?.browser,
device: event.contexts?.device,
};

// --- Build a sanitized snapshot for the user to inspect ---
const sanitized: SanitizedSentryEvent = {
event_id: event.event_id ?? crypto.randomUUID().replace(/-/g, ''),
timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now() / 1000,
platform: event.platform ?? 'javascript',
exception: sanitizeException(event.exception),
contexts: event.contexts as SanitizedSentryEvent['contexts'],
user: event.user as SanitizedSentryEvent['user'],
tags: event.tags as Record<string, string> | undefined,
environment: IS_DEV ? 'development' : 'production',
};
// Tag with surface so events filter cleanly inside `openhuman-react`.
event.tags = { ...(event.tags ?? {}), surface: 'react' };

// Extract human-readable title + message from the exception
const firstException = event.exception?.values?.[0];
const title = firstException?.type ?? 'Error';
const message = firstException?.value ?? 'Unknown error';
// Strip PII; keep a stable anonymous user id only.
const userId = getCoreStateSnapshot().snapshot.currentUser?._id;
event.user = userId ? { id: userId } : undefined;

// Queue the error for the notification UI
enqueueError({
id: crypto.randomUUID(),
timestamp: Date.now(),
source: 'global',
title,
message,
sentryEvent: sanitized,
});
// Strip frame-level local variables and source context — never send
// raw source snippets or live variable values to the dashboard.
if (event.exception?.values) {
for (const v of event.exception.values) {
if (v.stacktrace?.frames) {
for (const f of v.stacktrace.frames) {
delete f.vars;
delete f.context_line;
delete f.pre_context;
delete f.post_context;
}
}
if (v.mechanism) {
delete v.mechanism.data;
}
}
}

// Return null to prevent Sentry from auto-sending
return null;
return event;
Copy link
Copy Markdown
Contributor

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

Exception/message text is still a PII escape hatch.

beforeSend strips structural fields, but it still forwards event.message, event.logentry, and exception.values[*].value. Those strings often contain user input, filenames, URLs, or backend fragments, so the current auto-send path does not fully meet the “No PII” guarantee.

Suggested hardening
     beforeSend(event) {
       // Always allow the smoke-test event through so pipeline validation works
       // even when the user hasn't opted into analytics yet on first boot.
       const isSmokeTest = event.message === 'react-sentry-smoke-test';
       // Drop events when the user hasn't opted into analytics.
       if (!isSmokeTest && !isAnalyticsEnabled()) return null;
+
+      if (!isSmokeTest) {
+        event.message = undefined;
+        event.logentry = undefined;
+      }
 
       // Strip anything that could carry Redux / localStorage / request bodies.
       event.breadcrumbs = [];
       delete event.request;
       delete event.extra;
@@
       if (event.exception?.values) {
         for (const v of event.exception.values) {
+          v.value = undefined;
           if (v.stacktrace?.frames) {
             for (const f of v.stacktrace.frames) {
               delete f.vars;
               delete f.context_line;
               delete f.pre_context;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
beforeSend(event) {
// Bypass mode: let the event through (used by sendEventToSentry)
if (_bypassBeforeSend) {
_bypassBeforeSend = false;
return event;
}
// --- Sanitize the event ---
// Always allow the smoke-test event through so pipeline validation works
// even when the user hasn't opted into analytics yet on first boot.
const isSmokeTest = event.message === 'react-sentry-smoke-test';
// Drop events when the user hasn't opted into analytics.
if (!isSmokeTest && !isAnalyticsEnabled()) return null;
// Strip any breadcrumbs that somehow snuck in
// Strip anything that could carry Redux / localStorage / request bodies.
event.breadcrumbs = [];
// Strip request data (cookies, headers, body)
delete event.request;
// Strip user PII — keep only a stable anonymous ID
const userId = getCoreStateSnapshot().snapshot.currentUser?._id;
event.user = userId ? { id: userId } : undefined;
// Strip any extra/contexts that could contain Redux or localStorage data
delete event.extra;
event.contexts = {
// Keep only OS / browser / device metadata
os: event.contexts?.os,
browser: event.contexts?.browser,
device: event.contexts?.device,
};
// --- Build a sanitized snapshot for the user to inspect ---
const sanitized: SanitizedSentryEvent = {
event_id: event.event_id ?? crypto.randomUUID().replace(/-/g, ''),
timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now() / 1000,
platform: event.platform ?? 'javascript',
exception: sanitizeException(event.exception),
contexts: event.contexts as SanitizedSentryEvent['contexts'],
user: event.user as SanitizedSentryEvent['user'],
tags: event.tags as Record<string, string> | undefined,
environment: IS_DEV ? 'development' : 'production',
};
// Tag with surface so events filter cleanly inside `openhuman-react`.
event.tags = { ...(event.tags ?? {}), surface: 'react' };
// Extract human-readable title + message from the exception
const firstException = event.exception?.values?.[0];
const title = firstException?.type ?? 'Error';
const message = firstException?.value ?? 'Unknown error';
// Strip PII; keep a stable anonymous user id only.
const userId = getCoreStateSnapshot().snapshot.currentUser?._id;
event.user = userId ? { id: userId } : undefined;
// Queue the error for the notification UI
enqueueError({
id: crypto.randomUUID(),
timestamp: Date.now(),
source: 'global',
title,
message,
sentryEvent: sanitized,
});
// Strip frame-level local variables and source context — never send
// raw source snippets or live variable values to the dashboard.
if (event.exception?.values) {
for (const v of event.exception.values) {
if (v.stacktrace?.frames) {
for (const f of v.stacktrace.frames) {
delete f.vars;
delete f.context_line;
delete f.pre_context;
delete f.post_context;
}
}
if (v.mechanism) {
delete v.mechanism.data;
}
}
}
// Return null to prevent Sentry from auto-sending
return null;
return event;
beforeSend(event) {
// Always allow the smoke-test event through so pipeline validation works
// even when the user hasn't opted into analytics yet on first boot.
const isSmokeTest = event.message === 'react-sentry-smoke-test';
// Drop events when the user hasn't opted into analytics.
if (!isSmokeTest && !isAnalyticsEnabled()) return null;
if (!isSmokeTest) {
event.message = undefined;
event.logentry = undefined;
}
// Strip anything that could carry Redux / localStorage / request bodies.
event.breadcrumbs = [];
delete event.request;
delete event.extra;
event.contexts = {
os: event.contexts?.os,
browser: event.contexts?.browser,
device: event.contexts?.device,
};
// Tag with surface so events filter cleanly inside `openhuman-react`.
event.tags = { ...(event.tags ?? {}), surface: 'react' };
// Strip PII; keep a stable anonymous user id only.
const userId = getCoreStateSnapshot().snapshot.currentUser?._id;
event.user = userId ? { id: userId } : undefined;
// Strip frame-level local variables and source context — never send
// raw source snippets or live variable values to the dashboard.
if (event.exception?.values) {
for (const v of event.exception.values) {
v.value = undefined;
if (v.stacktrace?.frames) {
for (const f of v.stacktrace.frames) {
delete f.vars;
delete f.context_line;
delete f.pre_context;
delete f.post_context;
}
}
if (v.mechanism) {
delete v.mechanism.data;
}
}
}
return event;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/services/analytics.ts` around lines 59 - 101, The beforeSend handler
still forwards free-text fields that can contain PII; update the beforeSend
function to sanitize/redact those fields by removing or replacing event.message,
event.logentry, and exception.values[*].value (and any nested free-text fields)
before returning the event; locate the beforeSend implementation and ensure you
also sanitize event.exception.values array entries (the value property) and any
other top-level string fields that could leak user input so only non-PII
identifiers (tags, user.id) and allowed contexts remain.

@senamakel senamakel merged commit a084ebf into tinyhumansai:main May 1, 2026
15 checks passed
jwalin-shah added a commit to jwalin-shah/openhuman that referenced this pull request May 5, 2026
* feat(remotion): Ghosty character library with transparent MOV variants (tinyhumansai#1059)

Co-authored-by: WOZCODE <contact@withwoz.com>

* feat(composio/gmail): sync into memory tree (Slack-parity) (tinyhumansai#1056)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(scheduler-gate): throttle background AI on battery / busy CPU (tinyhumansai#1062)

* fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q (tinyhumansai#1061)

* ci: add dedicated staging release workflow (tinyhumansai#1066)

* fix(sentry): Rust source context + per-release deploy marker (tinyhumansai#405) (tinyhumansai#1067)

* fix(welcome): re-enable OAuth buttons with focus/timeout recovery (tinyhumansai#1049) (tinyhumansai#1069)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(dependencies): update pnpm-lock.yaml and Cargo.lock for package… (tinyhumansai#1082)

* fix(onboarding): personalize welcome agent greeting with user identity (tinyhumansai#1078)

* fix(chat): make agent message bubbles fit content width (tinyhumansai#1083)

* Feat/dmg checks (tinyhumansai#1084)

* fix(linux): Add X11 platform flags to .deb package launcher (tinyhumansai#1087)

Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com>

* fix(sentry): auto-send React events; collapse core→tauri for desktop (tinyhumansai#1086)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* fix(cef): run blank reload guard on the CEF UI thread (tinyhumansai#1092)

* fix(app): reload webview instead of restart_app in dev mode (tinyhumansai#1068) (tinyhumansai#1071)

* fix(linux): deliver X11 ozone flags via custom .desktop template (tinyhumansai#1091)

* fix(webview-accounts): retry data-dir purge so CEF handle race doesn't leak cookies (tinyhumansai#1076) (tinyhumansai#1081)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* fix(webview/slack): media perms + deep-link isolation (tinyhumansai#1074) (tinyhumansai#1080)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* ci(release): split staging vs production workflows; promote staging tags (tinyhumansai#1094)

* Update release-staging.yml (tinyhumansai#1097)

* chore(staging): v0.53.5

* chore(staging): v0.53.6

* ci(staging): cut staging from main; add act local-debug helper (tinyhumansai#1099)

* chore(staging): v0.53.7

* fix(ci): correct sentry-cli download URL and trap scope (tinyhumansai#1100)

* chore(staging): v0.53.8

* feat(chat): forward thread_id to backend for KV cache locality (tinyhumansai#1095)

* fix(ci): bump pinned sentry-cli to 3.4.1 (2.34.2 was never published) (tinyhumansai#1102)

* chore(staging): v0.53.9

* fix(ci): drop bash trap in upload_sentry_symbols.sh; inline cleanup (tinyhumansai#1103)

* chore(staging): v0.53.10

* refactor(session): flatten session_raw/, switch md to YYYY_MM_DD (tinyhumansai#1098)

* Add full Composio managed-auth toolkit catalog (tinyhumansai#1093)

* ci: add diff-aware 80% coverage gate (Vitest + cargo-llvm-cov) (tinyhumansai#1104)

* feat(scripts): pnpm work + pnpm debug for agent-driven workflows (tinyhumansai#1105)

* ci: pull pnpm into CI image, drop redundant setup steps (tinyhumansai#1107)

* docs: add Cursor Cloud specific instructions to AGENTS.md (tinyhumansai#1106)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* chore(staging): v0.53.11

* docs: surface 80% coverage gate and scripts/debug runners (tinyhumansai#1108)

* feat(app): show Composio integrations as sorted icon grid on Skills (tinyhumansai#1109)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* feat(composio): client-side trigger enable/disable toggles (tinyhumansai#1110)

* feat(skills): channels grid + integrations card polish; tolerant Composio trigger decode (tinyhumansai#1112)

* chore(staging): v0.53.12

* feat(home): early-bird banner + assistant→agent terminology (tinyhumansai#1113)

* feat(updater): in-app auto-update with auto-download + restart prompt (tinyhumansai#677) (tinyhumansai#1114)

* chore(claude): add ship-and-babysit slash command (tinyhumansai#1115)

* feat(home): EarlyBirdyBanner + agent terminology + LinkedIn enrichment model pin (tinyhumansai#1118)

* fix(chat): single onboarding thread in sidebar after wizard (tinyhumansai#1116)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com>

* fix: filter out global namespace from citation chips (tinyhumansai#1124)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>

* feat(nav): enable Memory tab in BottomTabBar (tinyhumansai#1125)

* feat(memory): singleton ingestion + status RPC + UI pill (tinyhumansai#1126)

* feat(human): mascot tab with viseme-driven lipsync (staging only) (tinyhumansai#1127)

* Fix CEF zombie processes on full app close and restart (tinyhumansai#1128)

Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>

* Update issue templates for GitHub issue types (tinyhumansai#1146)

* feat(human): expand mascot expressions and tighten reply-speech state machine (tinyhumansai#1147)

* feat(memory): ingestion pipeline + tree-architecture docs + ops/schemas split (tinyhumansai#1142)

* feat(threads): surface live subagent work in parent thread (tinyhumansai#1122) (tinyhumansai#1159)

* fix(human): keep mascot mouth animating when TTS ships no viseme data (tinyhumansai#1160)

* feat(composio): consume backend markdownFormatted for LLM output (tinyhumansai#1165)

* fix(subagent): lazy-register toolkit actions filtered out of fuzzy top-K (tinyhumansai#1162)

* feat(memory): user-facing long-term memory window preset (tinyhumansai#1137) (tinyhumansai#1161)

* fix(tauri-shell): proactively kill stale openhuman RPC on startup (tinyhumansai#1166)

* chore(staging): v0.53.13

* fix(composio): per-action tool consumes backend markdownFormatted (tinyhumansai#1167)

* fix(threads): persist selectedThreadId across reloads (tinyhumansai#1168)

* feat(memory_tree): switch embed model to bge-m3 (1024-dim, 8K context) (tinyhumansai#1174)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(agent): drop redundant [Memory context] recall injection (tinyhumansai#1173)

* chore(memory_tree): drop body-read timeouts on Ollama HTTP calls (tinyhumansai#1171)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(transcript): emit thread_id + fix orchestrator missing cost (tinyhumansai#1169)

* fix(composio/gmail): phase out html2md, prefer text/plain MIME part (tinyhumansai#1170)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(tools): markdown output for internal tool results (tinyhumansai#1172)

* feat(security): enforce prompt-injection guard before model and tool execution (tinyhumansai#1175)

* fix(cef): popup paint dies after first frame — skip blank-page guard for popups (tinyhumansai#1079) (tinyhumansai#1182)

Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>

* chore(sentry): rename OPENHUMAN_SENTRY_DSN → OPENHUMAN_CORE_SENTRY_DSN (tinyhumansai#1186)

* feat(remotion): add yellow mascot character with all animation variants (tinyhumansai#1193)

Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(composio): hide raw connection ID, derive friendly label (tinyhumansai#1153) (tinyhumansai#1185)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* fix(windows): align install.ps1 MSI with per-machine scope (tinyhumansai#913) (tinyhumansai#1187)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(tauri): deterministic CEF teardown on full app close (tinyhumansai#1120) (tinyhumansai#1189)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(composio): cap Gmail HTML body before strip (crash mitigation) (tinyhumansai#1191)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(auth): stop stale chat threads after signup (tinyhumansai#1192)

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sentry): staging-only "Trigger Sentry Test" button (tinyhumansai#1072) (tinyhumansai#1183)

* chore(staging): v0.53.14

* chore(staging): v0.53.15

* feat(composio): format trigger slugs into human-readable labels (tinyhumansai#1129) (tinyhumansai#1179)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* fix(ui): hide unsupported permission UI on non-macOS for Screen Intelligence (tinyhumansai#1194)

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(tauri-shell): retire embedded Gmail webview-account flow (tinyhumansai#1181)

* feat(onboarding): replace welcome-agent bot with react-joyride walkthrough (tinyhumansai#1180)

* chore(release): v0.53.16

* fix(threads): preserve selectedThreadId on cold-boot identity hydration (tinyhumansai#1196)

* feat(core): version/shutdown/update RPCs + mid-thread integration refresh (tinyhumansai#1195)

* fix(mascot): swap to yellow mascot via @remotion/player (tinyhumansai#1200)

* feat(memory_tree): cloud-default LLM, queue priority, entity filter, Memory tab UI (tinyhumansai#1198)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Persist turn state + restore conversation history on cold-boot (tinyhumansai#1202)

* feat(mascot): floating desktop mascot via native NSPanel + WKWebView (macOS) (tinyhumansai#1203)

* fix(memory/tree): emit summary children as Obsidian wikilinks (tinyhumansai#1210)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(tools): coding-harness baseline primitives (tinyhumansai#1205) (tinyhumansai#1208)

* docs: add Codex PR checklist for remote agents

---------

Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
Co-authored-by: WOZCODE <contact@withwoz.com>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cyrus Gray <144336577+graycyrus@users.noreply.github.com>
Co-authored-by: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com>
Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
Co-authored-by: Mega Mind <146339422+M3gA-Mind@users.noreply.github.com>
Co-authored-by: Gaurang Patel <ptelgm.yt@gmail.com>
Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com>
Co-authored-by: Steven Enamakel's Droid <enamakel.agent@tinyhumans.ai>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com>
Co-authored-by: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com>
Co-authored-by: Neil <neil@maha.xyz>
Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local>
Co-authored-by: obchain <167975049+obchain@users.noreply.github.com>
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
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.

2 participants