Skip to content

feat: Discord id cache, resolve fallback, and instant tab-switch#150

Merged
Keith-CY merged 53 commits intofeat/recipe-import-libraryfrom
feat/discord-channels-progressive-ui
Mar 21, 2026
Merged

feat: Discord id cache, resolve fallback, and instant tab-switch#150
Keith-CY merged 53 commits intofeat/recipe-import-libraryfrom
feat/discord-channels-progressive-ui

Conversation

@Keith-CY
Copy link
Copy Markdown
Collaborator

Summary

  • Integrate DiscordIdCache into both remote and local slow paths to persist guild/channel id→name mappings across page reloads (discord-id-cache.json)
  • Fall back to one-by-one channel resolution when batch openclaw channels resolve fails (e.g. single 404 channel blocking all others)
  • Preserve previously-resolved channel names via channel_name_fallback_map when CLI resolution fails, preventing overwrite with raw IDs
  • Fix tab-switch showing wrong VPS channels by resolving remote persistenceScope synchronously during render instead of in useEffect
  • Change useChannelCache initialization from useEffect to useLayoutEffect for zero-flash tab switching

Test plan

  • Unit tests for DiscordIdCache TTL behavior, JSON roundtrip
  • Unit tests for parse_resolve_name_map edge cases
  • Unit tests for channel name fallback preservation
  • Unit tests for loadInitialSharedChannels tab-switch cache behavior
  • Manual: switch between VPS instances and verify channels update instantly
  • Manual: verify Discord channel names persist across page reloads

🤖 Generated with Claude Code

cjs and others added 30 commits March 8, 2026 11:08
- Use gh CLI to get release body (avoids shell escaping issues)
- Use jq for proper JSON construction
- Skip .sig and latest.json files
- Use HTTP/1.1 for large file upload stability
- Detect user timezone to determine if likely in China
- CN users fetch release assets from GitLab (lay2dev/clawpal)
- Other users fetch from GitHub as before
- Falls back to secondary source if primary fails
feat(site): geo-aware download links
- Add canonical, Open Graph, Twitter Card meta tags
- Add SoftwareApplication JSON-LD schema
- Add robots.txt with AI crawler permissions
- Add llms.txt for AI search engines
- Add sitemap.xml
- Improve meta description for better CTR
cjs and others added 23 commits March 13, 2026 15:15
feat(seo): add SEO/GEO optimization for AI search visibility
Co-authored-by: dev01lay2 <dev01lay2@users.noreply.github.com>
list_recipes, manage_rescue_bot, get_rescue_bot_status,
diagnose_primary_via_rescue, and repair_primary_via_rescue were defined
in both mod.rs and their split-out files (recipe_cmds.rs, rescue.rs),
causing E0428 duplicate definition errors during full compilation.
- Agents and model profiles now initialize from localStorage persisted
  cache on mount, showing data immediately without waiting for a fetch
- Increase listAgents cache TTL from 6s/12s to 30s/60s to reduce
  redundant fetches during page navigation
- Combined with the existing RuntimeSnapshot → listAgents cache seeding,
  this means Cook/Recipes dropdowns populate instantly in most scenarios
- Guild names show spinner when name equals ID and full data pending
- Channel names show mono ID + spinner when unresolved, normal text once resolved
- Agent dropdown initializes from persisted cache for instant population
- Uses discordChannelsResolved from InstanceContext (set by App.tsx fast/full loading)
- Call refreshDiscordChannelsCacheFast() on ALL routes (channels/cook/recipes),
  not just cook/recipes — channels page needs the fast skeleton too
- Fix stale persisted cache blocking fast data: only keep prev data if it has
  actually resolved names (channelName !== channelId), not just non-empty
…switch

- Integrate DiscordIdCache into both remote and local slow paths to persist
  guild/channel id→name mappings across page reloads (discord-id-cache.json)
- Fall back to one-by-one channel resolution when batch openclaw channels
  resolve fails (e.g. single 404 channel blocking all others)
- Preserve previously-resolved channel names via channel_name_fallback_map
  when CLI resolution fails, preventing overwrite with raw IDs
- Fix tab-switch showing wrong VPS channels by resolving remote
  persistenceScope synchronously during render (setState-during-render
  pattern) instead of in useEffect, eliminating the one-render lag
- Change useChannelCache initialization from useEffect to useLayoutEffect
  so state maps are populated before browser paint
- Add unit tests for DiscordIdCache, parse_resolve_name_map, channel name
  fallback, loadInitialSharedChannels, and tab-switch cache behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A rate-limited response proves the API key is valid and the endpoint is
reachable — failing the test on 429 causes flaky CI when free-tier
quotas are exhausted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@dev01lay2 dev01lay2 left a comment

Choose a reason for hiding this comment

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

First review — PR #150

Status

  • Merge conflicts — PR is in CONFLICTING state, needs rebase onto main
  • CI — Only mirror ran (fork PR limitation). Cannot verify build/test/lint status.

Architecture

Large but well-structured refactor: Discord channel caching with TTL gates, DiscordIdCache for id→name persistence, streaming session analysis via Tauri events, and hook extraction from monolithic components. The layered cache strategy (fast path → TTL gate → full refresh) is sound.

🔴 Blocking

BS 1: Merge conflicts must be resolved before meaningful CI can run.

BS 2: console.log debug statements left in production code
useChannelCache.ts has multiple console.log calls ([useChannelCache] slow path raw channels:, [useChannelCache] fast path raw channels:, etc.) that should be removed or gated behind a dev flag before merge.

BS 3: discovery.rs guild-level placeholder may cause UI confusion
When a guild has no explicit channel list, a placeholder entry is emitted with channel_id == guild_id. Downstream code that filters or routes by channel_id will treat this as a real channel. Consider using a sentinel value or a separate field to mark it as a placeholder.

🟡 Non-blocking suggestions

NBS 1: useChannelCache.ts — ref sync pattern
The channelNodesByInstanceRef is synced via an unguarded useEffect (no deps array). This works but is unconventional — a direct assignment (channelNodesByInstanceRef.current = channelNodesByInstance outside useEffect, like the version in PR #118's fix) is more idiomatic and avoids a render-phase delay.

NBS 2: sessions.rs code duplication
analyze_sessions_sync duplicates the classification/sorting logic that clawpal_core::sessions::classify_session and sort_sessions already provide. Consider reusing the core functions to reduce drift risk.

NBS 3: parse_json_output forward-scanning approach
The new forward-scanning JSON extractor is more robust than the old reverse-scan, good improvement. Minor: the loop will spin on pathological input with many unbalanced brackets — consider adding a max-iterations guard.

NBS 4: DISCORD_CACHE_TTL_SECS = 7 days is aggressive
Channel names rarely change, but guild restructuring (new channels, renamed channels) would be invisible for a week. Consider making this configurable or reducing to 24h.

NBS 5: shell_escape usage in remote session preview
stream_remote_session_preview builds awk commands with shell_escape — ensure this handles session IDs with special characters robustly (e.g. UUIDs are fine, but user-created session names might not be).

@Keith-CY Keith-CY merged commit 6ccd782 into feat/recipe-import-library Mar 21, 2026
1 check passed
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.

3 participants