Uh oh!
There was an error while loading. Please reload this page.
fix(ui): stop showing healthy legacy sessions as 已阻塞; compact sidebar timestamps; localize bypass label - #452
Merged
Conversation
… timestamps; localize bypass label Three fixes from a real-app screenshot report (main window, 2026-07-03): 1. Blocked display semantics. The #410 terminal-ledger invariant marks legacy sessions missing a terminal fact as blocked/unknown. The sidebar groups by raw status, so intact, resumable conversations piled up under an 已阻塞 group with shield icons and the chat header badge read 已阻塞 — for sessions where the model had answered and nothing needed the user's attention. Session-level blocked is now a display-layer distinction: only actionable reasons (NO_REAL_CONNECTION / auth / permission_required) keep the blocked presentation; tool_failed / unknown normalize to active at the renderer state boundary (commitSessions / upsertSessionSummary), so grouping, row icon, and header badge agree. Runtime status writes are untouched. Regression: session-status-display-normalization.test.ts. 2. Sidebar timestamps. Sessions older than 7 days rendered the full medium date + time (2026年6月20日 16:33, ~150px) which crushed the title next to it to ~2 characters. New formatCompactTimestamp in @maka/core: relative inside 7 days, date-only beyond (6月20日 within the year, 2025年6月20日 across years). Sidebar-only; wide surfaces keep formatRelativeTimestamp. 3. i18n consistency. The composer permission-mode pill showed English 'Bypass permissions' between two Chinese modes; now 跳过确认 in the composer, command palette, session settings actions, and the account settings copy. Desktop suite: 1685/1685; typecheck clean.
jackwener added a commit
to sunheyi6/maka-agent
that referenced
this pull request
Jul 3, 2026
Maintainer pass on apache#456 (cold-start reordering + lazy splits). The perf direction is right; this closes the races the reordering opened: - recovery vs live send (review P0): recoverInterruptedSessions now re-checks runtimeKernel.hasActiveRuns immediately before BOTH updateStatus('active') sites, so a message sent mid-recovery owns the session status. Recovery-order contract rewritten to pin the new invariant (recovery inside runBackgroundStartup + the kernel guard) instead of the old recovery-before-window ordering. - snapshot seeding bypassed display normalization (apache#452 regression): the onboarding-snapshot seed is a third renderer state entry — without normalizeSessionSummaryForDisplay legacy blocked/unknown sessions flash an 已阻塞 group on first paint. Now normalized, and a snapshot-IPC-failure fallback calls bootstrapSessions() + refreshConnections() so the sidebar cannot stay empty forever. - env bootstrap connections never reached the renderer (review P1): ensureBootstrapConnection creates connections in background startup but never emitted connections:event — on a fresh env-var cold start the model picker stayed empty until an unrelated refresh. Both creation paths now emitConnectionListChanged(). - bundled-skills race (review P1): the fire-and-forget copy moved from main-window into runBackgroundStartup with a deferred handle; skills:list awaits it so an early Skills-page open cannot observe a half-bundled list (settled promise = zero steady-state cost). - scope: dropped .github/workflows/sync-fork.yml (author's fork-sync cron; on upstream it would be a zombie hourly self-merge job). Kept as-is after verification: dev:hmr -> dev.mjs (the launcher self- contains incremental tsc --build for all workspaces, so the alias is semantically equivalent and faster); lazy markdown split (fallback renders plain text, no unstyled flash). typecheck clean; runtime 806/806; desktop 1696/1696.
jackwener added a commit
that referenced
this pull request
Jul 3, 2026
* Add fork sync GitHub Actions workflow * Change fork sync to hourly * perf(desktop): cut first-paint latency — lazy heavy modules, bundle onboarding data, defer non-critical startup A coordinated cold-start pass so the window shows an interactive shell within milliseconds of launch. Main process: - main.ts: createWindow() now runs before runBackgroundStartup(); credential migration, connection bootstrap, telemetry/pricing, interrupted-session recovery, bot bridges, gateway and schedulers all run concurrently in the background and never block first paint. - main-window.ts: ensureBundledOfficeSkills moved off the createWindow critical path to a fire-and-forget task after loadFile. Renderer — shrink the initial chunk via React.lazy + Suspense: - markdown.tsx + new markdown-body.tsx: split the react-markdown + remark-* + rehype-highlight (highlight.js) pipeline behind lazy so it's only parsed when a message actually renders. - chat-view.tsx: SkillsModuleMain / DailyReviewPanel / PlanReminderPanel. - app-shell.tsx: ArtifactPane / BrowserPanel. - app-shell-overlays.tsx: SettingsModal. - OnboardingHero.tsx / command-palette.tsx: import the fine-grained provider-display / settings-nav leaves instead of the full ProvidersPanel / SettingsModal modules. First-paint data — bundle into the onboarding snapshot to skip redundant IPC round-trips: - onboarding-service.ts / global.d.ts / preload.ts: OnboardingSnapshot now carries sessions / connections / defaultSlug. - use-onboarding-snapshot.ts: expose getSessions/getConnections/ getDefaultSlug. - app-shell.tsx: seed the sidebar + model picker from the snapshot on first load; hoist onboardingComposerHidden to suppress the composer skeleton flash. - app-shell-effects.ts: only refreshShellSettings stays on the critical path (theme + locale); appInfo / memory / skills / planReminders / visual-smoke defer to requestAnimationFrame. Dev: - apps/desktop/package.json: dev:hmr simplified to . Tests follow the refactor: - modal-lifecycle-contract: tolerate the optional <Suspense> boundary around the lazy SettingsModal. - use-onboarding-snapshot: fixture gains the new snapshot fields. - visible-copy-hygiene-contract: read CodeBlock from markdown-body.tsx. * fix(ui): pin home-surface hero to top and fill window width Two layout fixes for the first-run / ready_empty home surface. - onboarding.css: PR-FIRSTRUN-FOLD-0 (PR #436) only flattened the padding stack for .maka-firstrun and intentionally kept the other onboarding states' centered rhythm. ready_empty ("今天想让 Maka 帮你做什么?") is the actual landing page once a model is configured, so mirror the same fold-flattening for :has(.maka-onboarding-ready) — chatContent padding-top clamp(72px,10vh,116px) -> clamp(24px,3.5vh,44px), align-content center -> start, and onboarding-stack min-height -> 0 / padding-top clamp(40px,7vh,76px) -> clamp(12px,2vh,24px). The hero + quickchat + first-run checklist now sit near the top instead of floating mid-window. - sidebar.css: #root (index.html) is display:flex + justify-content: center so the preload skeleton centers before React mounts. Once mounted, .appFrame is that flex container's only child, and without an explicit main-axis size it shrank to content max-content and got centered — so on the narrow-content first-run hero the whole app frame floated mid-window with large L/R gutters, while long-message sessions filled the width. Pin .appFrame width:100% so it always spans the window regardless of inner content. Preload centering is unaffected (it's still the only child at that point). * review: harden background-startup races, seed normalization, and scope Maintainer pass on #456 (cold-start reordering + lazy splits). The perf direction is right; this closes the races the reordering opened: - recovery vs live send (review P0): recoverInterruptedSessions now re-checks runtimeKernel.hasActiveRuns immediately before BOTH updateStatus('active') sites, so a message sent mid-recovery owns the session status. Recovery-order contract rewritten to pin the new invariant (recovery inside runBackgroundStartup + the kernel guard) instead of the old recovery-before-window ordering. - snapshot seeding bypassed display normalization (#452 regression): the onboarding-snapshot seed is a third renderer state entry — without normalizeSessionSummaryForDisplay legacy blocked/unknown sessions flash an 已阻塞 group on first paint. Now normalized, and a snapshot-IPC-failure fallback calls bootstrapSessions() + refreshConnections() so the sidebar cannot stay empty forever. - env bootstrap connections never reached the renderer (review P1): ensureBootstrapConnection creates connections in background startup but never emitted connections:event — on a fresh env-var cold start the model picker stayed empty until an unrelated refresh. Both creation paths now emitConnectionListChanged(). - bundled-skills race (review P1): the fire-and-forget copy moved from main-window into runBackgroundStartup with a deferred handle; skills:list awaits it so an early Skills-page open cannot observe a half-bundled list (settled promise = zero steady-state cost). - scope: dropped .github/workflows/sync-fork.yml (author's fork-sync cron; on upstream it would be a zombie hourly self-merge job). Kept as-is after verification: dev:hmr -> dev.mjs (the launcher self- contains incremental tsc --build for all workspaces, so the alias is semantically equivalent and faster); lazy markdown split (fallback renders plain text, no unstyled flash). typecheck clean; runtime 806/806; desktop 1696/1696. --------- Co-authored-by: jackwener <jakevingoo@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Driven by a real-app screenshot report (2026-07-03): three healthy chat sessions piled under an 已阻塞 sidebar group with shield icons, titles crushed to
?..., and an English 'Bypass permissions' pill in an otherwise Chinese composer.1. Blocked display semantics (the headline bug)
The #410 terminal-ledger invariant marks legacy sessions missing a terminal fact as
blocked/unknown. The sidebar groups by raw status → intact, resumable conversations showed as 已阻塞 (header badge too), reading like data loss when nothing needed the user's attention.First-principles split: session-level 已阻塞 is only worth the interruption when the user can ACT — configure a connection, re-login, confirm a permission.
tool_failed/unknownmean "the last run's bookkeeping didn't close cleanly"; the failure detail already lives on the failed turn in the chat.normalizeSessionSummaryForDisplay()applied at the renderer state boundary (commitSessions/upsertSessionSummary) → grouping, row icon, and header badge all agreeNO_REAL_CONNECTION/auth/permission_required) keep the blocked presentationsession-status-display-normalization.test.ts(4 cases)2. Sidebar timestamps crushed titles
>7-day sessions rendered
2026年6月20日 16:33(~150px) next to the title. NewformatCompactTimestampin @maka/core: relative within 7 days, date-only beyond (6月20日same year,2025年6月20日across years). Sidebar-only; wide surfaces keep the existing formatter (artifact-pane dedup contract still satisfied — one shared implementation in core).3. Bypass permissions → 跳过确认
询问权限 / 自动执行 /
Bypass permissions跳过确认 — consistent zh across composer, command palette, session settings, and account settings copy.Verification
npm --workspace @maka/desktop test: 1685/1685npm run typecheck: clean