Skip to content

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

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
oxoxDev:fix/1068-dev-restart-app-reload
May 2, 2026
Merged

fix(app): reload webview instead of restart_app in dev mode (#1068)#1071
senamakel merged 2 commits into
tinyhumansai:mainfrom
oxoxDev:fix/1068-dev-restart-app-reload

Conversation

@oxoxDev
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev commented May 1, 2026

Summary

  • Replace Tauri app.restart() with window.location.reload() in pnpm dev:app so the dev session survives an identity flip / restart trigger.
  • Packaged builds keep the original app.restart() path; no behaviour change there.
  • Add Vitest coverage for the dev (reload) and prod (invoke('restart_app')) branches in restartApp.

Problem

pnpm dev:app runs pnpm tauri dev -> cargo run -> tauri-cef CLI -> vite (child). When restartApp() invokes Tauri's app.restart(), the cargo parent exits and orphans the vite child, killing the entire dev session — the desktop window disappears and the user has to re-run pnpm dev:app by hand.

The dominant caller is the identity-flip path in app/src/providers/CoreStateProvider.tsx, which fires automatically when persisted OPENHUMAN_ACTIVE_USER_ID differs from the bootstrap snapshot's auth.userId (e.g. after switching profiles in the UI). This made dev-mode profile switching effectively unusable.

Solution

Gate at the source — restartApp() in app/src/utils/tauriCommands/core.ts:

  • In dev mode (IS_DEV from app/src/utils/config.ts), call window.location.reload(). Module init re-runs, so the freshly-set OPENHUMAN_ACTIVE_USER_ID localStorage seed (already updated by setActiveUserId upstream of restartApp) is read at boot, redux-persist re-hydrates from the new user's namespace, and singleton services come up clean — without touching the cargo / vite processes.
  • In production mode, keep the original app.restart() invocation. There is no vite child to orphan, and the existing CEF profile-path machinery still needs the full process restart.

Gating at the source means every current and future caller benefits without per-call-site changes. IS_DEV is the canonical re-export from app/src/utils/config.ts, per the project's "no import.meta.env outside config.ts" rule.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per docs/TESTING-STRATEGY.md
  • N/A: behaviour-only — no matrix rows touched. Coverage matrix not affected; existing restartApp row still describes the user-visible contract.
  • N/A: behaviour-only — no new feature IDs. Listed under ## Related below.
  • No new external network dependencies introduced (mock backend used per docs/TESTING-STRATEGY.md)
  • N/A: dev-only path — release-cut surfaces unchanged; app.restart() continues to run in packaged builds, which is what RELEASE-MANUAL-SMOKE.md covers.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Runtime: Desktop dev (pnpm dev:app) only. Packaged macOS/Windows/Linux builds keep app.restart() unchanged.
  • Performance: Dev reload is faster than the previous (broken) full process restart and avoids the manual re-launch cost.
  • Security: None — same trust boundary; the reload still re-runs the bootstrap/auth chain.
  • Migration: None.
  • Compatibility: All current restartApp() callers (identity flip, CEF profile rotation, post-update relaunch in dev) get the new behaviour automatically. Production semantics are byte-identical.

Related

Summary by CodeRabbit

  • Bug Fixes
    • Improved app restart functionality with enhanced runtime environment detection for more reliable restart behavior across different deployment scenarios.

oxoxDev added 2 commits May 1, 2026 16:28
…nsai#1068)

`pnpm dev:app` launcher graph is:
  `pnpm tauri dev` -> `cargo run` -> `tauri-cef` CLI -> `vite` (child).

Calling Tauri's `app.restart()` exits the cargo parent, which orphans
the vite child and kills the whole dev session — the user has to
re-run `pnpm dev:app` by hand. The dominant caller is the identity-
flip path in `CoreStateProvider`, which fires automatically when
`OPENHUMAN_ACTIVE_USER_ID` differs from the bootstrap snapshot's
auth.userId.

In dev mode, swap `app.restart()` for `window.location.reload()`.
The webview reload re-runs module init, so the freshly-set
localStorage seed is read at boot, redux-persist re-hydrates from
the new user's namespace, and singleton services come up clean —
without touching the cargo / vite processes. Packaged builds keep
the original `app.restart()` path; there is no vite child to orphan.

Gate at the source (`restartApp()`) so all current and future callers
benefit; do not gate at individual call sites.

Closes tinyhumansai#1068
…humansai#1068)

Add two new cases to the existing `restartApp` suite:

- Dev mode (`IS_DEV=true`, the vitest default via `setup.ts`) calls
  `window.location.reload()` and skips `invoke('restart_app')`.
- Production mode (`IS_DEV=false`) re-mocks `../config` via
  `vi.doMock` + `vi.resetModules()` so a fresh `./core` import
  evaluates the prod branch and calls `invoke('restart_app')`.

`window.location.reload` is non-configurable on jsdom's stock
location, so each restartApp test swaps in a mocked location object
and restores it in `afterEach`.

Closes tinyhumansai#1068
@oxoxDev oxoxDev requested a review from a team May 1, 2026 11:06
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

The restartApp() function now conditionally uses window.location.reload() in dev mode instead of invoking Tauri's app.restart(), preventing the termination of the development vite process. Corresponding tests were added to verify both dev and production behavior.

Changes

Cohort / File(s) Summary
Dev Mode Restart Logic
app/src/utils/tauriCommands/core.ts, app/src/utils/tauriCommands/core.test.ts
restartApp() now branches on IS_DEV: dev mode calls window.location.reload() and returns early, while production mode invokes invoke<void>('restart_app'). Tests mock window.location, verify reload is never called outside Tauri, and include separate test cases for dev (reload called once, invoke uncalled) and production (invoke called, reload uncalled) modes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A reload in dev, a restart in prod,
No more vite orphans when we restart our code!
The dev session thrives while we build and we test,
Window's gentle refresh puts the module at rest. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing Tauri app.restart() with window.location.reload() in dev mode, which directly aligns with the changeset modifying restartApp() behavior.
Linked Issues check ✅ Passed The PR fully addresses issue #1068 requirements: uses window.location.reload() in dev mode, preserves app.restart() for production, applies gating at restartApp() source, adds tests covering both branches, and closes the linked issue.
Out of Scope Changes check ✅ Passed All changes are scoped to the restartApp() implementation and its tests. No unrelated modifications to other systems, APIs, or functionalities were introduced outside the dev mode reload fix.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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: 3/5 reviews remaining, refill in 21 minutes and 2 seconds.

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.

🧹 Nitpick comments (1)
app/src/utils/tauriCommands/core.test.ts (1)

75-84: ⚡ Quick win

IS_DEV=false factory mock pattern is likely brittle in this repo’s jsdom setup

This file combines module-level mocks with vi.doMock('../config') + vi.resetModules(), which has previously broken jsdom setup here. Consider replacing this with a less fragile strategy (e.g., testing an extracted mode-param helper, or validating prod behavior outside this jsdom path).

Based on learnings: In tinyhumansai/openhuman, testing IS_DEV=false via a factory mock of ../../utils/config breaks the jsdom environment setup chain in files with module-level mocks.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/utils/tauriCommands/core.test.ts` around lines 75 - 84, The test uses
a brittle pattern (vi.doMock('../config') + vi.resetModules()) to force
IS_DEV=false before importing ./core; replace this with a less fragile approach:
either extract the environment-dependent logic into a helper function you can
call with an explicit mode (e.g., create a getMode or isDev param and test that
function directly) or set the config value via a stable DI/override mechanism
before importing (for example use vi.mock('../config', () => ({ IS_DEV: false,
...vi.importActual('../config') })) without resetModules or refactor core to
accept a mode param so the test can import ./core normally and call the
production path explicitly instead of relying on module-level re-mocking; update
the test named "invokes restart_app in production mode (IS_DEV=false)" to use
the new helper/DI approach and remove vi.doMock + vi.resetModules usage and the
fragile factory mock of IS_DEV.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/utils/tauriCommands/core.test.ts`:
- Around line 75-84: The test uses a brittle pattern (vi.doMock('../config') +
vi.resetModules()) to force IS_DEV=false before importing ./core; replace this
with a less fragile approach: either extract the environment-dependent logic
into a helper function you can call with an explicit mode (e.g., create a
getMode or isDev param and test that function directly) or set the config value
via a stable DI/override mechanism before importing (for example use
vi.mock('../config', () => ({ IS_DEV: false, ...vi.importActual('../config') }))
without resetModules or refactor core to accept a mode param so the test can
import ./core normally and call the production path explicitly instead of
relying on module-level re-mocking; update the test named "invokes restart_app
in production mode (IS_DEV=false)" to use the new helper/DI approach and remove
vi.doMock + vi.resetModules usage and the fragile factory mock of IS_DEV.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e311940d-59ec-42f1-baff-6cfd4c451434

📥 Commits

Reviewing files that changed from the base of the PR and between 6ac7885 and 9e0d3f6.

📒 Files selected for processing (2)
  • app/src/utils/tauriCommands/core.test.ts
  • app/src/utils/tauriCommands/core.ts

@senamakel senamakel merged commit fbd4c7e into tinyhumansai:main May 2, 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>
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.

[Bug] dev:app restartApp() kills vite parent → entire dev session exits

2 participants