- Add Sentry debug symbol upload step to the CI pipeline for production builds.
- Implement a helper script for manual symbol uploads with OS and architecture detection.
- Configure automatic Sentry release creation and commit association on main branch pushes.
- Refine Sentry CLI parameters to correctly handle shallow clones and debug ID indexing.
- Initialize CHANGELOG.md to track project changes and infrastructure updates.
- Update workflow permissions to allow Sentry to read action metadata for commit mapping.
Closes#627
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Dedicated narrow workflow that runs only agent-review.spec.ts under
tauri-driver + Xvfb and uploads app/test/e2e/artifacts/**. Gates on
spec presence so it can land before the spec itself. Intentionally does
not re-enable the broader commented E2E matrix in test.yml.
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
* feat(webview): zero-injection CDP migration for 5 providers
Moves the per-provider webview scraping path off injected JS and onto
CDP for the cef runtime. The 5 migrated providers (whatsapp, telegram,
slack, discord, browserscan) now load with zero initialization_script;
their UA fingerprint, DOM chat-list scraping, and multi-account target
matching all run through the Chrome DevTools Protocol.
Shared infrastructure in new `cdp/` module: CdpConn, Snapshot walker
(generic DOMSnapshot.captureSnapshot), UaSpec + setUserAgentOverride
helper, per-account session opener that keeps a long-lived CDP session
attached so the UA override stays resident for the lifetime of the
webview. Webview opens at a data:text/html placeholder, CDP applies UA
override, then Page.navigate drives it to the real provider URL with a
`#openhuman-account-{id}` fragment used by all scanners for
multi-account disambiguation (replaces Telegram's title-marker JS).
Per-provider dom_snapshot.rs files for telegram/slack/discord replicate
the WhatsApp scraper pattern. Emit the same `webview:event` ingest
envelope the old recipes used so the frontend is unchanged.
Deferred (kept JS-injected, separate PRs):
- gmail/linkedin: no Rust scanner yet
- google-meet: 535-line lifecycle + captions recipe
- idb.rs `Runtime.callFunctionOn` serializer: audit listed as future work
Also removes the unused `webview_account_eval` Tauri command.
Wry builds retain the legacy ua_spoof.js + runtime.js + recipe.js path
where those files still exist (no wry-specific regressions introduced).
* fix(release): enable Ubuntu 22.04 platform support in release workflow
Uncommented and configured the Ubuntu 22.04 platform in the release workflow to support the x86_64-unknown-linux-gnu target. This change enhances cross-platform compatibility for the release process.
* fix(webview): address CodeRabbit review comments
- session.rs: boundary-check the `starts_with(real_url)` match so
`https://discord.com` can't accidentally match `https://discord.com.evil/…`
when deciding whether to skip Page.navigate.
- session.rs: drop unused `_app: AppHandle<R>` parameter from spawn_session
(and its generic R); update the webview_accounts call site accordingly.
- session.rs: document the non-graceful shutdown path (cancellation token
left as a follow-up).
- discord/slack/telegram scanners: import CDP_HOST/CDP_PORT from the shared
`cdp` module instead of redeclaring them. (whatsapp_scanner keeps its
locals — the module isn't cef-gated so it can't pull from cef-only cdp::.)
- webview_accounts/mod.rs: collapse the duplicate provider_is_supported
check with provider_url into one early-return.
- emulation.rs: add a TODO documenting when/how to refresh the hardcoded
Chrome UA fingerprint fields.
- discord/slack/telegram dom_snapshot: hash every row for change detection
(was capped at first 5–8 — a reorder past that limit wouldn't invalidate
the cache).
- discord_scanner/dom_snapshot: simplify is_channel_row (single
attr lookup); tighten the pure-unread-marker comment (dropped the
obsolete recipe.js cross-reference).
- slack_scanner/dom_snapshot: align find_badge with the Discord behavior
(empty badge text → Some(0), matching the marker-present-but-no-count
semantics).
Deferred (explicitly called out in the PR): shared CdpConn dedup across
scanners, shared DomScan/ChannelRow types across provider dom_snapshot
files, graceful session shutdown, table-driven scanner startup macro.
* fix(webview): CR round-2 — session teardown, exact target match, real-url validation
- cdp/session.rs: use exact equality for the per-account target match
(`t.title == marker || t.url.ends_with(&fragment)`), so
`…account-abc` can't be mistaken for `…account-abcdef`. Scanners
(whatsapp/telegram/slack/discord) also switched from `url.contains` to
`url.ends_with` on the fragment for the same reason.
- cdp/session.rs: `spawn_session` now returns `JoinHandle<()>`.
- webview_accounts: store the CDP session handle keyed by account_id in
`WebviewAccountsState.cdp_sessions`, abort any prior handle before
spawning a new one on re-open, and abort on close/purge so reopen
cycles don't stack live CDP loops.
- webview_accounts: validate `real_url_str` as a `Url` up front (was
only validating the placeholder), so a malformed `args.url` fails the
command instead of crashing the async session loop later.
- webview_accounts: `provider_is_supported` now derives from
`provider_url` (single canonical registry, no drift).
- telegram_scanner/dom_snapshot: row ids now always include `idx`, so
two chats with the same display name don't collide into one id.
* fix(webview): CR round-3 — scanner prefix, empty-rows emit, wry UA fallback
- DOM poll: drop `!scan.rows.is_empty()` guard in discord/slack/telegram
fast-ticks so the zero-unread transition (last chat read) still emits a
hash-change snapshot. Consumers lose the "clearing" state otherwise.
- webview_accounts: derive `scanner_url_prefix` from the validated
`real_url`'s origin (via `Url::origin().ascii_serialization()`), not
the static `provider_url(...)`. Debug `args.url` overrides and
alternate hosts now drive the scanner target match correctly.
- webview_accounts: cfg-split `build_init_script`. Under cef, migrated
providers return an empty script (zero injection, unchanged). Under
wry, migrated providers that fingerprint on `navigator.*` still ship
`ua_spoof.js` even though their recipe is gone — the previous early
return dropped the UA shim, which would regress Slack/Google login
gates on wry dev builds.
* ci(release): bake Sentry DSN into shipped tauri bundle
Released builds weren't reporting anything to Sentry. Root cause: the
tauri.conf.json `beforeBuildCommand` re-runs `vite build` inside
`cargo tauri build`. The prior `yarn build` step set `VITE_SENTRY_DSN`
for its own run, but the tauri step did not — so the rebuild produced
a DSN-less `dist/` that overwrote the good one, and the shipped web UI
initialized Sentry with an empty DSN (`initSentry` returns early when
`!SENTRY_DSN`).
Fix:
- `release.yml` / `build-desktop` — declare `VITE_SENTRY_DSN` and
`VITE_DEBUG` on the tauri-build step so the `beforeBuildCommand`
rebuild bakes them into the final bundle.
- `release-packages.yml` / `build-cli-linux-arm64` — guard against a
missing `vars.OPENHUMAN_SENTRY_DSN` so the Linux arm64 CLI tarball
cannot ship without error reporting baked in via `option_env!`.
The core sidecar's `option_env!("OPENHUMAN_SENTRY_DSN")` already gets
the value from the dedicated "Build sidecar core binary" step; the
tauri shell doesn't rebuild it (separate crate, not a workspace dep),
so the baked DSN survives into the bundled installer.
* feat(observability): Sentry release tracking + source maps (#405)
Tags every Sentry event with a canonical release identifier shared by
the frontend and Rust core, uploads source maps so stack traces are
symbolicated in the dashboard, and adds a CLI probe for repeatable
verification of any future release.
Release identifier
openhuman@<semver>[+<short_git_sha>]
- Frontend (`app/src/utils/config.ts::SENTRY_RELEASE`) builds the tag
from `VITE_BUILD_SHA`.
- Core sidecar (`src/main.rs::build_release_tag`) builds the same tag
from `option_env!("OPENHUMAN_BUILD_SHA")`, so events from both
surfaces group under one release. Cargo's fingerprint already tracks
`option_env!` changes.
Environment separation
- Frontend: new `APP_ENVIRONMENT` export (`development` | `staging` |
`production`) derived from `VITE_OPENHUMAN_APP_ENV`, passed to
`Sentry.init`.
- Core: `resolve_environment` honors `OPENHUMAN_APP_ENV` at runtime,
falling back to `debug_assertions` detection.
Source-map upload
- `@sentry/vite-plugin` added as an app devDependency.
- `vite.config.ts` emits source maps unconditionally and registers the
plugin only when `SENTRY_AUTH_TOKEN` is present, so local dev skips
silently. The plugin uploads `dist/**/*.js{,.map}` under the
canonical release name and then deletes the on-disk `.map` files so
they never ship to end users.
CI wiring (`release.yml` + `release-packages.yml`)
- `Build frontend` and `Build and package Tauri app` both receive
`VITE_BUILD_SHA`, `SENTRY_RELEASE`, `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`,
`SENTRY_PROJECT_FRONTEND`. The tauri step needs the same env because
its `beforeBuildCommand` re-runs `vite build`.
- `Build sidecar core binary` receives `OPENHUMAN_BUILD_SHA` so
`option_env!` bakes the short SHA into the release tag.
- `build-cli-linux-arm64` mirrors `OPENHUMAN_BUILD_SHA` and
`OPENHUMAN_APP_ENV` for the arm64 CLI tarball.
Verification support
- New `openhuman sentry-test` CLI subcommand captures an `Error`-level
event against the currently-initialized client, flushes, and prints
the event UUID. Optional `--panic` flag exercises the panic
integration. Requires a DSN resolvable at runtime or baked in at
compile time; exits non-zero otherwise so misconfiguration is loud.
- `src/main.rs` now loads `.env` before `sentry::init`, so a DSN
defined only in the repo-local dotenv file (common dev case) is
honored by the startup-time Sentry client.
Docs
- `docs/sentry.md` covers the release identifier, environment table,
source-map pipeline, required CI variables, and a verification
runbook with troubleshooting tips.
- `.env.example` + `app/.env.example` document the new build-time vars.
- Updated the release workflow to include signing of macOS .app tarballs with the Tauri updater key, ensuring integrity for installed clients.
- Modified the upload script to handle the signing process and added error handling for missing signing keys.
- Removed Linux x86_64 asset handling from the updater manifest to streamline the release process.
These changes improve the security and reliability of macOS artifact uploads in the release workflow.
- Commented out the Ubuntu 22.04 platform configuration in the release.yml file to streamline the workflow and focus on active platforms.
- This change helps maintain clarity in the release process by reducing clutter from unused configurations.
- Updated the release workflow to include caching for the vendored `tauri-cli` binary and its installation metadata, improving build efficiency across platforms.
- Modified the `ensure-tauri-cli.sh` script to restore the cached binary if available, reducing installation time and ensuring the correct version is used.
- Changed the build script to utilize `cargo tauri build` instead of `npx tauri build`, aligning with the new CLI setup for better integration with the CEF-aware environment.
These changes streamline the development workflow and enhance the reliability of the Tauri setup.