feat(home): banners, welcome typewriter, conversation gating#936
Conversation
… for improved user name resolution
…mponent for improved layout
…d add WelcomeThinkingTypewriter component
…interaction and add unit tests for banner functionality
📝 WalkthroughWalkthroughAdds home-page banners and tests, changes composer blocking and welcome UI with a typewriter, refactors Home header and user resolution, adds CoreStateProvider user fallback, sanitizes and TTL-caches current-user in Rust, tweaks Tauri updater envs in the release workflow, and updates/removes several tests. Changes
Sequence Diagram(s)sequenceDiagram
participant Snapshot as "Snapshot()"
participant Cache as "CurrentUserCache"
participant Backend as "Backend API"
participant Logger as "Logger"
Snapshot->>Cache: lookup(api_base, token)
alt cache fresh
Cache-->>Snapshot: return cached_user
else cache missing or stale
Snapshot->>Backend: fetch /current_user
Backend-->>Snapshot: user_json
Snapshot->>Snapshot: sanitize(user_json)
alt sanitized non-empty
Snapshot->>Cache: store (user_json, now)
Snapshot-->>Snapshot: return sanitized user
else sanitized empty
Snapshot->>Cache: clear entry
Logger-->>Snapshot: warn("empty user from backend")
Snapshot-->>Snapshot: return stored/sanitized snapshot user fallback
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Bootstrap UI moved to settings/LocalModelPanel; the Home page no longer renders Bootstrap/Retry/Running controls. Add APP_VERSION to the shared config mock so other Home-rendering tests keep working.
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
app/src/pages/__tests__/Conversations.test.tsx (1)
5-27: Missing test case forrustChat: false.The
isComposerInteractionBlockedfunction returnstruewhenrustChatisfalse, but this scenario has no test coverage. All three tests passrustChat: true.🧪 Suggested additional test case
it('allows composer interaction when chat is idle and ready', () => { expect( isComposerInteractionBlocked({ activeThreadId: null, welcomePending: false, rustChat: true }) ).toBe(false); }); + + it('blocks composer interaction when rust chat is unavailable', () => { + expect( + isComposerInteractionBlocked({ activeThreadId: null, welcomePending: false, rustChat: false }) + ).toBe(true); + }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/pages/__tests__/Conversations.test.tsx` around lines 5 - 27, Add a test in the existing describe('isComposerInteractionBlocked') block that covers the case when rustChat is false: call isComposerInteractionBlocked with rustChat: false (e.g., activeThreadId: null and welcomePending: false) and assert it returns true; reference the isComposerInteractionBlocked function name to locate where to add the new it(...) test so the branch where rustChat is false is covered.
🤖 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.yml:
- Around line 413-419: Remove the unresolved git conflict markers (<<<<<<<
Updated upstream, =======, >>>>>>> Stashed changes) and restore a valid env
block by keeping the intended variables BASE_URL, UPDATER_PUBLIC_KEY,
UPDATER_ENDPOINT and UPDATER_REPO; locate the conflict around the env mapping
that mentions BASE_URL and UPDATER_* and replace the entire conflict region with
a single clean YAML mapping containing those keys (ensuring UPDATER_PUBLIC_KEY
uses the secrets fallback expression shown and values remain valid YAML), then
validate the YAML to ensure the workflow parses.
In `@app/src/components/home/__tests__/HomeBanners.test.tsx`:
- Around line 8-40: The openUrl mock is shared across tests and accumulates
calls, so add a per-test reset (e.g., a beforeEach or afterEach) that clears
mocks to ensure each spec starts fresh; specifically, in the test suite
containing UsageLimitBanner, PromotionalCreditsBanner, DiscordBanner and the
openUrl/ DISCORD_INVITE_URL assertions, call vi.clearAllMocks() (or
openUrl.mockClear()) before each test to reset call history so each
expect(openUrl).toHaveBeenCalledWith(...) only reflects the current test's
interaction.
In `@app/src/components/home/HomeBanners.tsx`:
- Around line 23-38: The computed tone-specific button classes in styles.button
are never applied, so the CTA uses the hardcoded amber classes; update the JSX
in HomeBanners where the CTA button is rendered (instances that currently
hardcode amber classes around the CTA, including the second occurrence) to use
the dynamic styles.button instead of the static class string—locate the button
elements in HomeBanners.tsx and replace their className with styles.button (or
merge it if other classes are present) so the danger tone renders the correct
coral CTA.
In `@app/src/pages/Conversations.tsx`:
- Line 479: Remove the duplicate guard that checks composerInteractionBlocked
(the unreachable `if (composerInteractionBlocked) return;`) since the same
condition is already handled earlier; locate the redundant line near the handler
in Conversations.tsx (the function surrounding composer interaction logic) and
delete that second check, keeping only the original early return so control flow
and any subsequent logic remain unchanged.
In `@app/src/pages/Home.tsx`:
- Line 50: The console.log call in Home.tsx currently prints the raw user object
(console.log('showPromoBanner', showPromoBanner, user, promoCredits)); remove
the raw user from this render path and instead log only non-sensitive derived
values (e.g., showPromoBanner, promoCredits, user plan/flags or boolean
isSubscribed/isAdmin) or a sanitized user summary that omits identifiers and
PII; update the console.log invocation in the render path to only include those
safe fields or remove it entirely.
In `@src/openhuman/app_state/ops.rs`:
- Around line 492-518: Move the inline tests out of ops.rs into a new tests
module file (e.g., ops_tests.rs) to keep ops.rs under ~500 lines; keep the
existing sanitize_snapshot_user test but replace the TTL-only assertion that
checks Instant math with a behavioral test that exercises
fetch_current_user_cached using a CachedCurrentUser instance and
CURRENT_USER_REFRESH_TTL to assert cache-hit vs cache-miss behavior (e.g.,
prepare cached entry with fetched_at older/newer than CURRENT_USER_REFRESH_TTL
and call fetch_current_user_cached to validate it returns cached user when fresh
and triggers refresh when expired).
---
Nitpick comments:
In `@app/src/pages/__tests__/Conversations.test.tsx`:
- Around line 5-27: Add a test in the existing
describe('isComposerInteractionBlocked') block that covers the case when
rustChat is false: call isComposerInteractionBlocked with rustChat: false (e.g.,
activeThreadId: null and welcomePending: false) and assert it returns true;
reference the isComposerInteractionBlocked function name to locate where to add
the new it(...) test so the branch where rustChat is false is covered.
🪄 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: 64199675-9836-4ce9-a756-cf116537b4b2
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockapp/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
.github/workflows/release.ymlapp/src/components/composio/ComposioConnectModal.tsxapp/src/components/home/HomeBanners.tsxapp/src/components/home/__tests__/HomeBanners.test.tsxapp/src/pages/Conversations.tsxapp/src/pages/Home.tsxapp/src/pages/__tests__/Conversations.test.tsxapp/src/pages/__tests__/Home.test.tsxapp/src/providers/CoreStateProvider.tsxapp/src/providers/__tests__/CoreStateProvider.test.tsxapp/src/types/api.tssrc/openhuman/app_state/ops.rssrc/openhuman/credentials/ops.rssrc/openhuman/credentials/ops_tests.rs
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use serde_json::json; | ||
|
|
||
| #[test] | ||
| fn sanitize_snapshot_user_drops_empty_payloads() { | ||
| assert_eq!(sanitize_snapshot_user(Some(json!({}))), None); | ||
| assert_eq!(sanitize_snapshot_user(Some(Value::Null)), None); | ||
| assert_eq!( | ||
| sanitize_snapshot_user(Some(json!({ "firstName": "steven" }))), | ||
| Some(json!({ "firstName": "steven" })) | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn cached_current_user_entry_expires_after_ttl() { | ||
| let entry = CachedCurrentUser { | ||
| api_base: "https://staging-api.tinyhumans.ai".to_string(), | ||
| token: "tok".to_string(), | ||
| fetched_at: Instant::now() - (CURRENT_USER_REFRESH_TTL + Duration::from_millis(1)), | ||
| user: json!({ "firstName": "steven" }), | ||
| }; | ||
|
|
||
| assert!(entry.fetched_at.elapsed() >= CURRENT_USER_REFRESH_TTL); | ||
| } | ||
| } |
There was a problem hiding this comment.
Strengthen cache TTL test and move inline tests out of ops.rs.
Line 508’s test currently validates Instant math, not fetch_current_user_cached behavior; it won’t catch TTL-branch regressions. Also, this inline module pushes the file over the repository’s ~500-line target.
♻️ Proposed refactor
-#[cfg(test)]
-mod tests {
- use super::*;
- use serde_json::json;
-
- #[test]
- fn sanitize_snapshot_user_drops_empty_payloads() {
- assert_eq!(sanitize_snapshot_user(Some(json!({}))), None);
- assert_eq!(sanitize_snapshot_user(Some(Value::Null)), None);
- assert_eq!(
- sanitize_snapshot_user(Some(json!({ "firstName": "steven" }))),
- Some(json!({ "firstName": "steven" }))
- );
- }
-
- #[test]
- fn cached_current_user_entry_expires_after_ttl() {
- let entry = CachedCurrentUser {
- api_base: "https://staging-api.tinyhumans.ai".to_string(),
- token: "tok".to_string(),
- fetched_at: Instant::now() - (CURRENT_USER_REFRESH_TTL + Duration::from_millis(1)),
- user: json!({ "firstName": "steven" }),
- };
-
- assert!(entry.fetched_at.elapsed() >= CURRENT_USER_REFRESH_TTL);
- }
-}
+#[cfg(test)]
+#[path = "ops_tests.rs"]
+mod tests;// src/openhuman/app_state/ops_tests.rs (new)
// Keep existing sanitize test, and replace TTL arithmetic-only check
// with a behavior test that calls fetch_current_user_cached and asserts
// cache-hit / cache-miss behavior.As per coding guidelines, "src/**/*.rs: Source files should be ≤ ~500 lines; split modules when growing to improve maintainability" and "**/*.{rs,ts,tsx}: Ship unit tests and coverage for behavior you are adding or changing before building additional features on top."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/openhuman/app_state/ops.rs` around lines 492 - 518, Move the inline tests
out of ops.rs into a new tests module file (e.g., ops_tests.rs) to keep ops.rs
under ~500 lines; keep the existing sanitize_snapshot_user test but replace the
TTL-only assertion that checks Instant math with a behavioral test that
exercises fetch_current_user_cached using a CachedCurrentUser instance and
CURRENT_USER_REFRESH_TTL to assert cache-hit vs cache-miss behavior (e.g.,
prepare cached entry with fetched_at older/newer than CURRENT_USER_REFRESH_TTL
and call fetch_current_user_cached to validate it returns cached user when fresh
and triggers refresh when expired).
- release.yml: drop the leftover stash conflict markers around the updater env block so the workflow YAML parses again. - HomeBanners: actually apply the tone-specific button classes so the danger variant renders coral instead of falling back to amber. - HomeBanners.test: clear the openUrl mock between cases so each assertion only sees its own click. - Conversations: drop the duplicate composerInteractionBlocked guard (already early-returned upstream). - Conversations.test: cover the rustChat=false branch. - Home: don't log the raw user object on every render — it carries ids/PII; remove the diagnostic. - app_state/ops: split inline tests into ops_tests.rs and assert both the fresh and expired branches of the current-user cache TTL.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/openhuman/app_state/ops_tests.rs (1)
23-36:⚠️ Potential issue | 🟡 MinorTTL tests still bypass the production freshness predicate.
These checks validate
Instantmath directly, but they won’t fail if the predicate insidefetch_current_user_cachedchanges (for example,<to<=). Consider extracting a small helper (used by production code) and asserting against that helper in tests.♻️ Minimal refactor to bind tests to production logic
diff --git a/src/openhuman/app_state/ops.rs b/src/openhuman/app_state/ops.rs @@ +fn is_cached_current_user_fresh(entry: &CachedCurrentUser) -> bool { + entry.fetched_at.elapsed() < CURRENT_USER_REFRESH_TTL +} @@ - && entry.fetched_at.elapsed() < CURRENT_USER_REFRESH_TTL + && is_cached_current_user_fresh(entry)diff --git a/src/openhuman/app_state/ops_tests.rs b/src/openhuman/app_state/ops_tests.rs @@ - assert!(fresh.fetched_at.elapsed() < CURRENT_USER_REFRESH_TTL); + assert!(is_cached_current_user_fresh(&fresh)); @@ - assert!(expired.fetched_at.elapsed() >= CURRENT_USER_REFRESH_TTL); + assert!(!is_cached_current_user_fresh(&expired));As per coding guidelines, "
**/*.{rs,ts,tsx}: Ship unit tests and coverage for behavior you are adding or changing before building additional features on top."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/app_state/ops_tests.rs` around lines 23 - 36, The tests directly compare Instant math against CURRENT_USER_REFRESH_TTL which can diverge from production logic; extract the production freshness predicate into a small helper (e.g., fn is_cached_entry_fresh(fetched_at: Instant) -> bool) and use that helper inside fetch_current_user_cached and in the tests (replace the assert!(...elapsed() < CURRENT_USER_REFRESH_TTL) / >= checks with calls to is_cached_entry_fresh and its negation), keeping references to make_cached_entry and CURRENT_USER_REFRESH_TTL to locate the impacted code.
🧹 Nitpick comments (4)
.github/workflows/release.yml (2)
413-416: Remove unused updater env vars from this step.
BASE_URL,UPDATER_PUBLIC_KEY,UPDATER_ENDPOINT, andUPDATER_REPOare not consumed byscripts/prepareTauriConfig.js(it only readsWITH_UPDATER/KEYPAIR_ALIAS), so these values are dead here and can cause config-drift assumptions.♻️ Proposed cleanup
- name: Define Tauri configuration overrides id: config-overrides @@ uses: actions/github-script@v7 env: - BASE_URL: ${{ needs.prepare-build.outputs.base_url }} - UPDATER_PUBLIC_KEY: ${{ secrets.UPDATER_PUBLIC_KEY || vars.UPDATER_PUBLIC_KEY }} - UPDATER_ENDPOINT: ${{ vars.UPDATER_ENDPOINT }} - UPDATER_REPO: tinyhumansai/openhuman WITH_UPDATER: "true"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release.yml around lines 413 - 416, Remove the unused updater environment variables from the workflow step by deleting BASE_URL, UPDATER_PUBLIC_KEY, UPDATER_ENDPOINT, and UPDATER_REPO entries so the step only provides the vars actually consumed by scripts/prepareTauriConfig.js (WITH_UPDATER and KEYPAIR_ALIAS); update the environment block in the step to only export required vars and verify no other steps reference those removed names (BASE_URL, UPDATER_PUBLIC_KEY, UPDATER_ENDPOINT, UPDATER_REPO) to avoid breaking dependencies.
529-529: GateWITH_UPDATERby release mode instead of hardcodingtrue.At Line 529 this also enables updater artifact mode for staging builds (
release_enabled == 'false'). Making it conditional keeps staging behavior lean and aligned with release-only updater packaging.🔧 Suggested change (apply in both env blocks: Line 417 and Line 529)
- WITH_UPDATER: "true" + WITH_UPDATER: ${{ needs.prepare-build.outputs.release_enabled == 'true' && 'true' || 'false' }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release.yml at line 529, The WITH_UPDATER env is hardcoded to "true" and should be gated by the release mode; update the two occurrences of WITH_UPDATER in .github/workflows/release.yml to derive their value from the release_enabled environment variable (use the workflow expression that evaluates release_enabled == 'true') so that WITH_UPDATER is true only for release builds; change both env blocks that currently set WITH_UPDATER: "true" to set WITH_UPDATER based on release_enabled (refer to the WITH_UPDATER key and the release_enabled env var when locating the spots to change).app/src/pages/Home.tsx (1)
172-242: Consider removing the large commented-out “Next steps” block.Keeping this much dormant JSX in the component makes future maintenance harder; better to delete it or move it behind a feature flag/ADR reference.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/pages/Home.tsx` around lines 172 - 242, Remove the large commented-out "Next steps" JSX block in Home.tsx to reduce clutter; either delete it entirely or extract it behind a feature flag or into a separate component (e.g., NextSteps) and reference that from the Home component so the commented code no longer sits in the Home.tsx source.src/openhuman/app_state/ops.rs (1)
308-314: Consider de-duplicating user-sanitization logic across domains.
sanitize_snapshot_userduplicates the same null/empty-object filtering already present insrc/openhuman/credentials/ops.rs(sanitize_stored_session_user). A shared helper would reduce drift risk if rules evolve.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/app_state/ops.rs` around lines 308 - 314, Both sanitize_snapshot_user and sanitize_stored_session_user duplicate the same filtering logic (treating Value::Null and empty Object as None); extract that logic into a single shared helper (e.g., sanitize_user_value) and have both functions call it. Update references in src/openhuman/app_state/ops.rs (sanitize_snapshot_user) and src/openhuman/credentials/ops.rs (sanitize_stored_session_user) to delegate to the new helper so behavior is centralized and future changes only touch one function.
🤖 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/pages/Home.tsx`:
- Around line 62-68: statusCopy's object lookup for socketStatus can return
undefined for unexpected states; update the computation of statusCopy (where
socketStatus is used) to provide a defensive fallback string (e.g., a generic
"Status unknown — please try again" message) when the lookup yields undefined —
either by adding a default key in the object or by using a nullish coalescing
fallback after the lookup (statusCopy = {...}[socketStatus] ?? 'fallback
message') to ensure the UI always shows a description.
---
Duplicate comments:
In `@src/openhuman/app_state/ops_tests.rs`:
- Around line 23-36: The tests directly compare Instant math against
CURRENT_USER_REFRESH_TTL which can diverge from production logic; extract the
production freshness predicate into a small helper (e.g., fn
is_cached_entry_fresh(fetched_at: Instant) -> bool) and use that helper inside
fetch_current_user_cached and in the tests (replace the assert!(...elapsed() <
CURRENT_USER_REFRESH_TTL) / >= checks with calls to is_cached_entry_fresh and
its negation), keeping references to make_cached_entry and
CURRENT_USER_REFRESH_TTL to locate the impacted code.
---
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 413-416: Remove the unused updater environment variables from the
workflow step by deleting BASE_URL, UPDATER_PUBLIC_KEY, UPDATER_ENDPOINT, and
UPDATER_REPO entries so the step only provides the vars actually consumed by
scripts/prepareTauriConfig.js (WITH_UPDATER and KEYPAIR_ALIAS); update the
environment block in the step to only export required vars and verify no other
steps reference those removed names (BASE_URL, UPDATER_PUBLIC_KEY,
UPDATER_ENDPOINT, UPDATER_REPO) to avoid breaking dependencies.
- Line 529: The WITH_UPDATER env is hardcoded to "true" and should be gated by
the release mode; update the two occurrences of WITH_UPDATER in
.github/workflows/release.yml to derive their value from the release_enabled
environment variable (use the workflow expression that evaluates release_enabled
== 'true') so that WITH_UPDATER is true only for release builds; change both env
blocks that currently set WITH_UPDATER: "true" to set WITH_UPDATER based on
release_enabled (refer to the WITH_UPDATER key and the release_enabled env var
when locating the spots to change).
In `@app/src/pages/Home.tsx`:
- Around line 172-242: Remove the large commented-out "Next steps" JSX block in
Home.tsx to reduce clutter; either delete it entirely or extract it behind a
feature flag or into a separate component (e.g., NextSteps) and reference that
from the Home component so the commented code no longer sits in the Home.tsx
source.
In `@src/openhuman/app_state/ops.rs`:
- Around line 308-314: Both sanitize_snapshot_user and
sanitize_stored_session_user duplicate the same filtering logic (treating
Value::Null and empty Object as None); extract that logic into a single shared
helper (e.g., sanitize_user_value) and have both functions call it. Update
references in src/openhuman/app_state/ops.rs (sanitize_snapshot_user) and
src/openhuman/credentials/ops.rs (sanitize_stored_session_user) to delegate to
the new helper so behavior is centralized and future changes only touch one
function.
🪄 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: f308e431-9c86-4ac2-a155-62aef696c4f8
📒 Files selected for processing (8)
.github/workflows/release.ymlapp/src/components/home/HomeBanners.tsxapp/src/components/home/__tests__/HomeBanners.test.tsxapp/src/pages/Conversations.tsxapp/src/pages/Home.tsxapp/src/pages/__tests__/Conversations.test.tsxsrc/openhuman/app_state/ops.rssrc/openhuman/app_state/ops_tests.rs
✅ Files skipped from review due to trivial changes (2)
- app/src/components/home/tests/HomeBanners.test.tsx
- app/src/components/home/HomeBanners.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- app/src/pages/tests/Conversations.test.tsx
- app/src/pages/Conversations.tsx
| const statusCopy = { | ||
| connected: | ||
| 'Your device is connected to OpenHuman AI. Keep the app running to keep the connection alive — message your assistant with the button below.', | ||
| connecting: 'Connecting to OpenHuman AI. Hang tight, this usually takes a second.', | ||
| 'Your device is connected. Keep the app running to keep the connection alive. Message your assistant with the button below.', | ||
| connecting: 'Connecting. Hang tight, this usually takes a second.', | ||
| disconnected: | ||
| 'Your device is offline right now. Check your network or restart the app to reconnect.', | ||
| }[socketStatus]; |
There was a problem hiding this comment.
Add a defensive fallback for unexpected socket states.
Right now, an unrecognized socketStatus would render an empty description. A small fallback keeps UX stable if new states are introduced.
💡 Suggested adjustment
- const statusCopy = {
+ const statusCopy = {
connected:
'Your device is connected. Keep the app running to keep the connection alive. Message your assistant with the button below.',
connecting: 'Connecting. Hang tight, this usually takes a second.',
disconnected:
'Your device is offline right now. Check your network or restart the app to reconnect.',
- }[socketStatus];
+ }[socketStatus] ?? 'Checking connection status...';📝 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.
| const statusCopy = { | |
| connected: | |
| 'Your device is connected to OpenHuman AI. Keep the app running to keep the connection alive — message your assistant with the button below.', | |
| connecting: 'Connecting to OpenHuman AI. Hang tight, this usually takes a second.', | |
| 'Your device is connected. Keep the app running to keep the connection alive. Message your assistant with the button below.', | |
| connecting: 'Connecting. Hang tight, this usually takes a second.', | |
| disconnected: | |
| 'Your device is offline right now. Check your network or restart the app to reconnect.', | |
| }[socketStatus]; | |
| const statusCopy = { | |
| connected: | |
| 'Your device is connected. Keep the app running to keep the connection alive. Message your assistant with the button below.', | |
| connecting: 'Connecting. Hang tight, this usually takes a second.', | |
| disconnected: | |
| 'Your device is offline right now. Check your network or restart the app to reconnect.', | |
| }[socketStatus] ?? 'Checking connection status...'; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/pages/Home.tsx` around lines 62 - 68, statusCopy's object lookup for
socketStatus can return undefined for unexpected states; update the computation
of statusCopy (where socketStatus is used) to provide a defensive fallback
string (e.g., a generic "Status unknown — please try again" message) when the
lookup yields undefined — either by adding a default key in the object or by
using a nullish coalescing fallback after the lookup (statusCopy =
{...}[socketStatus] ?? 'fallback message') to ensure the UI always shows a
description.
Summary
WelcomeThinkingTypewritercomponent and gate the conversation composer until the welcome flow completes.snapshot.currentUserfromauth.userwhen missing; tighten provider regression coverage.Problem
Home lacked surfaces for usage limits and promos, anchor-based banner CTAs were inconsistent with the rest of the app's button affordances, and the composer could be used before the welcome agent completed onboarding. Identity flips also risked stale
currentUserstate inCoreStateProvider.Solution
HomeBannerswith proper button semantics + tests.Conversations.CoreStateProviderto backfillcurrentUserand clear scoped caches across identity changes (covered by new tests).Submission Checklist
HomeBanners,Conversationscomposer gating, andCoreStateProvideridentity flows.Impact
Related
Summary by CodeRabbit
New Features
Bug Fixes / Improvements
Tests
Chores