Skip to content

Settings Refresh#390

Merged
arul28 merged 3 commits into
mainfrom
ade/settings-refresh-2db507ca
May 29, 2026
Merged

Settings Refresh#390
arul28 merged 3 commits into
mainfrom
ade/settings-refresh-2db507ca

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented May 28, 2026

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.

ADE   Open in ADE  ·  ade/settings-refresh-2db507ca branch  ·  PR #390

Greptile Summary

This PR is a Settings Refresh that reorganizes and expands the settings UI, adds self-healing transcript repair for corrupted Claude SDK sessions, and introduces a GitHub release-check endpoint for update notifications.

  • Settings restructure: "Workspace" and "AI" sections are merged/renamed into "AI Connections" and "Background Jobs"; a new AboutSection component surfaces app version, latest release, and update-check controls, extracting that logic from GeneralSection; new dedicated onboarding cards (GitHubCard, LinearCard, WorktreesCard, AiRuntimesBand) are added.
  • Transcript self-healing: claudeThinkingTranscriptRepair.ts detects reused message.id collisions in Claude SDK JSONL transcripts and rewrites them atomically; agentChatService.ts invokes the repair at pre-warm, cold-resume, and error-recovery sites.
  • Update checking: fetchAdeLatestRelease fetches GitHub Releases API and compares against the running version to surface an "Update available" badge in the About panel.

Confidence Score: 4/5

Safe to merge with one small fix: the LinearCard error message when a token is rejected is misleading and should be corrected first.

The transcript repair, settings restructure, and update-check plumbing are all well-implemented with proper guards. The one concrete defect is in LinearCard: when setLinearToken returns a non-connected status the error toast says "Linear connected", which actively misinforms the user about what went wrong.

apps/desktop/src/renderer/components/onboarding/LinearCard.tsx — the saveApiKey return value for the connection-failed case uses the wrong message string.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/components/onboarding/LinearCard.tsx New card for Linear integration; saveApiKey returns the success string "Linear connected" as its error message when the API call succeeds but connected is false, causing the InputPopover to render "Linear connected" in red.
apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts New module: atomically repairs Claude SDK JSONL transcripts with reused message IDs; path-traversal guard present, idempotent, and fully unit-tested. Error logging on write failure is absent (previously flagged).
apps/desktop/src/main/services/chat/agentChatService.ts Adds three transcript-repair call sites (pre-warm, cold-resume, error self-heal) and emits a system_notice event on full-auto plan-mode exit to fix a stale UI chip; changes look correct and well-commented.
apps/desktop/src/main/services/github/githubService.ts Adds fetchAdeLatestRelease using the GitHub Releases API; gracefully returns null on any failure, handles token optionally, and normalises the version string. Looks correct.
apps/desktop/src/renderer/components/settings/AboutSection.tsx New component extracted from GeneralSection; shows installed/latest version, update badge, and runtime daemon status. formatReleasedAgo handles future timestamps gracefully.
apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx New band component for AI runtime cards and background-helper toggles; opencodeBinaryInstalled !== false over-counts ready runtimes when the field is undefined (previously flagged outside diff).
apps/desktop/src/renderer/components/onboarding/GitHubCard.tsx New GitHub integration card; error handling in savePat is correct (returns ghAuthError when connected is false).
apps/desktop/src/renderer/components/app/SettingsPage.tsx Renames sections and wires up new section IDs; TAB_ALIASES updated correctly for backward-compat navigation.
apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx New card for importing external git worktrees as lanes; batch attach with per-item error collection and retry-on-failure selection looks solid.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[AgentChatPane receives system_notice] -->|exited_plan_mode| B[setInteractionMode default]
    B --> C[setClaudePermissionMode default if was plan]
    A -->|entered_plan_mode| D[setInteractionMode plan]

    E[Chat error handler] -->|isCorruptThinkingTranscriptError| F[repairClaudeResumeTranscript]
    F -->|repaired| G[refreshReconstructionContext + prewarm]
    F -->|no-op| H[emit error event as-is]

    I[prewarmClaudeQuery] --> J{options.resume?}
    J -->|yes| K[repairClaudeResumeTranscript at prewarm]
    J -->|no| L[skip repair]

    M[cold start path] --> N{options.resume && !warmQuery?}
    N -->|yes| O[repairClaudeResumeTranscript at resume]
    N -->|no| P[skip repair]

    Q[AboutSection mounts] --> R[window.ade.app.getLatestRelease]
    R --> S{updateAvailable?}
    S -->|yes| T[Show warning badge + release notes button]
    S -->|no| U[Show up-to-date badge]
Loading

Comments Outside Diff (2)

  1. apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts, line 525-527 (link)

    P2 Silent swallow of the write error masks filesystem problems. The outer catch returns NO_OP when writeFileSync or renameSync throws, so a disk-full or permission error is silently ignored and the next call also returns NO_OP (because the backup already exists, skipping the backup step, but the file was never actually repaired). Consider at least logging the failure so it shows up in the warning trail alongside the agent_chat.claude_thinking_transcript_repaired log.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts
    Line: 525-527
    
    Comment:
    Silent swallow of the write error masks filesystem problems. The outer `catch` returns `NO_OP` when `writeFileSync` or `renameSync` throws, so a disk-full or permission error is silently ignored and the next call also returns `NO_OP` (because the backup already exists, skipping the backup step, but the file was never actually repaired). Consider at least logging the failure so it shows up in the warning trail alongside the `agent_chat.claude_thinking_transcript_repaired` log.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

  2. apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx, line 1222-1224 (link)

    P2 The readyCount heuristic for OpenCode treats any non-false value of opencodeBinaryInstalled as ready, including undefined (when the field is absent from an older status snapshot). If the backend hasn't populated that field yet, the count will over-report one ready runtime. Guard with a strict === true check to match the pattern used for every other runtime.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx
    Line: 1222-1224
    
    Comment:
    The `readyCount` heuristic for OpenCode treats any non-`false` value of `opencodeBinaryInstalled` as ready, including `undefined` (when the field is absent from an older status snapshot). If the backend hasn't populated that field yet, the count will over-report one ready runtime. Guard with a strict `=== true` check to match the pattern used for every other runtime.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/desktop/src/renderer/components/onboarding/LinearCard.tsx:101-103
When `setLinearToken` succeeds but returns `connected: false` (e.g. an invalid or revoked API key), this function returns `{ ok: false, message: "Linear connected" }`. `InputPopover` renders the `message` field as the error text when `ok` is false, so the user sees "Linear connected" displayed in red — the opposite of what happened.

```suggestion
      const next = await window.ade.cto.setLinearToken({ token });
      setStatus(next as LinearConnectionStatus);
      const connected = (next as LinearConnectionStatus).connected;
      return { ok: connected, message: connected ? "Linear connected" : "Token rejected — check the key and try again" };
```

Reviews (2): Last reviewed commit: "fix: address settings refresh review fin..." | Re-trigger Greptile

@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview May 28, 2026 11:46pm

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 28, 2026

@copilot review but do not make fixes

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

This PR adds Claude thinking transcript auto-repair logic, implements app release version checking with UI integration, redesigns the onboarding flow from a multi-step stepper to a single-page card layout, restructures settings navigation, and fixes a plan-mode state synchronization race condition in the chat pane.

Changes

Claude Thinking Transcript Repair and Session Improvements

Layer / File(s) Summary
Thinking transcript repair core logic
apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts, apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.test.ts
Pure JSONL line transformer detects and rewrites reused assistant message IDs; file-level wrapper provides atomic repair with backup creation; path resolver validates session ID and finds transcript; error classifier recognizes Anthropic 400 corruption errors. Tests verify idempotency, no-op on healthy transcripts, path traversal prevention, and error matching.
Service integration and error recovery
apps/desktop/src/main/services/chat/agentChatService.ts
Agent chat service imports repair helpers and calls repairClaudeResumeTranscript in three control paths: main Claude error handler (non-auth failures), before direct resume, and before prewarm/transcript loading. Detects corrupt thinking errors, repairs transcript, logs warning, and triggers reconstruction refresh + prewarming when repaired.
Plan mode event-driven state sync
apps/desktop/src/renderer/components/chat/AgentChatPane.tsx, apps/desktop/src/renderer/components/chat/AgentChatPane.test.tsx
AgentChatPane immediately updates composer mode (interactionMode, claudePermissionMode) when receiving system_notice with permissionModeTransition detail, preventing stale UI from async session refresh races. Test verifies exit-plan-mode chip correctly updates even when refetch returns stale state.

Release Version Checking Infrastructure

Layer / File(s) Summary
GitHub release fetch and app update check
apps/desktop/src/main/services/github/githubService.ts, apps/desktop/src/main/services/github/githubService.test.ts
New fetchAdeLatestRelease function queries GitHub /releases/latest API with optional token and repo override; parses and normalizes tag_name to version, maps response fields to tagName, htmlUrl, publishedAt; returns null on errors. Tests verify field mapping, bearer auth header behavior, and null returns for non-OK/invalid/missing payloads.
IPC handler and preload API
apps/desktop/src/main/services/ipc/registerIpc.ts, apps/desktop/src/preload/global.d.ts, apps/desktop/src/preload/preload.ts, apps/desktop/src/shared/ipc.ts, apps/desktop/src/shared/types/core.ts
New IPC.appGetLatestRelease handler fetches release, suppresses token-read errors, and computes updateAvailable by comparing remote version to app.getVersion() (packaged builds only). Preload exposes window.ade.app.getLatestRelease() returning LatestReleaseInfo | null. New LatestReleaseInfo type with version, URLs, published date, and availability flag.
Browser mock updates
apps/desktop/src/renderer/browserMock.ts
Mock adds window.ade.app.getLatestRelease() returning synthetic release payload; updates Claude provider to show binary present with model IDs and pr_descriptions feature enabled; adds featureModelOverrides config; GitHub status shifts to OAuth with added patTokenStored, authSource, ghCliPath fields; window.ade.lanes.listUnregisteredWorktrees() returns example worktrees.

Onboarding Redesign: Theme, Cards, and Page Layout

Layer / File(s) Summary
Onboarding theme tokens and helpers
apps/desktop/src/renderer/components/onboarding/onboardingTheme.ts
Centralized brand colors, card base styles, section label and meta text typography, plus brandCard(), statusDot(), and logoTile() functions for consistent themed styling across onboarding UI.
Onboarding status cards and controls
apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx, apps/desktop/src/renderer/components/onboarding/DevToolsRow.tsx, apps/desktop/src/renderer/components/onboarding/GitHubCard.tsx, apps/desktop/src/renderer/components/onboarding/InputPopover.tsx, apps/desktop/src/renderer/components/onboarding/LinearCard.tsx, apps/desktop/src/renderer/components/onboarding/RescanButton.tsx, apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx
New card components manage onboarding setup: AiRuntimesBand displays CLI runtimes and background helpers with toggles; DevToolsRow detects Git and ADE CLI; GitHubCard manages GitHub token auth; LinearCard handles Linear OAuth and API-key flows; WorktreesCard lists and attaches unregistered worktrees; InputPopover provides reusable token/key input with save callback; RescanButton is a small icon-only refresh trigger.
Project setup page single-page redesign
apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx
Refactored from multi-step stepper/sidebar layout to single-page card layout with AiRuntimesBand on left, right rail containing DevToolsRow/GitHubCard/LinearCard/WorktreesCard. "Skip" and "Finish setup" CTAs replace "Back/Continue"; "Finish setup" gated on gitInstalled === true. Extensive style constants for page/section/rail/header/body layout.

Settings Navigation and Component Restructuring

Layer / File(s) Summary
Settings page section reorganization
apps/desktop/src/renderer/components/app/SettingsPage.tsx
SECTIONS replaces "workspace"/"ai" with "AI Connections"/"Background Jobs"; TAB_ALIASES maps legacy query values to new canonical ids; sidebar data-tour now differentiates background-jobs tab; right-panel rendering: section === "ai" renders ProvidersSection, section === "background-jobs" renders AiFeaturesSection.
Command palette and general settings updates
apps/desktop/src/renderer/components/app/CommandPalette.tsx, apps/desktop/src/renderer/components/settings/GeneralSection.tsx
CommandPalette renames "Go to AI Settings" to "Go to AI Connections", adds "Go to Background Jobs" command, removes "Go to Workspace Settings". GeneralSection removes AppInfo loading and "Background Runtime" section rendering; replaces with new AboutSection; simplifies to onboarding status only.
About section and integrations styling
apps/desktop/src/renderer/components/settings/AboutSection.tsx, apps/desktop/src/renderer/components/settings/IntegrationsSettingsSection.tsx
New AboutSection displays app version, latest release info, update status pill, and conditional "Check for Updates"/"View Release Notes" buttons. IntegrationsSettingsSection enriches tabs with brand icons and colors; refactors tab button rendering to display branded icons with active/inactive opacity styling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • arul28/ADE#381: Modifies plan-mode system notice and session permission handling in agentChatService.ts, directly related to the plan-mode event sync layer in this PR.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Settings Refresh' is overly broad and vague. While the PR includes settings UI changes, it encompasses far more than just settings—including major features like Claude thinking transcript repair, ADE release lookup, chat service enhancements, and comprehensive onboarding component refactoring. Consider a more specific title that captures the primary change, such as 'Refactor onboarding and settings UI with transcript repair' or 'Add ADE release check and Claude transcript repair support'.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/settings-refresh-2db507ca

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 28, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

Comment thread apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

PR Review

Scope: 32 file(s), +2945 / −802
Verdict: Needs changes

This PR reshapes first-run onboarding into a dashboard of setup cards, splits Settings into clearer tabs (AI Connections, Background Jobs, About), and adds Claude thinking-transcript self-repair plus plan-mode UI fixes. The onboarding and chat work look solid, but the settings consolidation removes user-facing project maintenance controls without relocating them.


🐛 Functionality

[High] Project repair and integrity UI removed with no replacement

File: apps/desktop/src/renderer/components/settings/ProjectSection.tsx (deleted); apps/desktop/src/renderer/components/app/SettingsPage.tsx:L26-L28,L171-L172
Issue: ProjectSection (project snapshot, structure repair, integrity check) and the Workspace settings tab are deleted. Deep links ?tab=workspace / ?tab=project now alias to General, which only shows setup re-entry, CLI, and About — there is no remaining renderer call to window.ade.project.getSnapshot, initializeOrRepair, or runIntegrityCheck.
Repro: Open Settings → General (or command palette / bookmark ?tab=workspace). Previously available repair/integrity actions are gone.
Fix: Restore project health controls (e.g. reintroduce ProjectSection under General or a dedicated subsection) or mount the same actions on another settings surface before merging.

[Medium] Finish setup stays disabled when essentials scan fails

File: apps/desktop/src/renderer/components/onboarding/DevToolsRow.tsx:L20-L34; apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx:L63-L64
Issue: gitInstalled starts as null and is only updated inside the try of refresh(). If window.ade.devTools.detect() rejects, onGitStatusChange never runs, so gitInstalled stays null and Finish setup remains disabled (gitInstalled !== true) even though Skip still works.
Repro: Simulate or trigger a failed devTools.detect IPC (runtime unavailable) on the onboarding page.
Fix: Call onGitStatusChange(false) in a catch (or finally when tools is missing), and/or treat null as “unknown” with an explicit error state instead of locking Finish.

[Medium] Linear OAuth polling can stack on repeated Sign in

File: apps/desktop/src/renderer/components/onboarding/LinearCard.tsx:L49-L82
Issue: Each beginOAuth() starts a new setInterval without clearing an existing pollRef. A second click while oauthBusy leaves two pollers running until one completes, causing duplicate getLinearOAuthSession calls and possible duplicate state updates.
Repro: Click Sign in twice quickly on the Linear card.
Fix: Clear any existing interval at the start of beginOAuth, and disable the button while oauthBusy (already partially done — also guard against re-entry).


⚡ Performance

[Medium] Worktree import rescans reset manual selection

File: apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx:L104
Issue: Rescan always calls load({ preselectAll: true }), which replaces selected with every worktree path. Users who unchecked items lose their selection on every rescan.
Impact: Extra accidental bulk imports after adjusting checkboxes and clicking Rescan.
Fix: Use preselectAll only on initial mount; on rescan call load({ keepSelected: selected }) or preserve the current Set.


🎨 UI/UX

[Medium] AI runtimes grid does not adapt on narrow widths

File: apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx:L184-L187
Issue: Runtime cards use gridTemplateColumns: "repeat(6, 1fr)" with fixed column spans. On viewports under ~640px (and inside the setup page’s wrapping flex layout), cards compress to very narrow columns with no minWidth, media query, or single-column fallback.
Fix: Switch to repeat(auto-fit, minmax(…)) or a @media (max-width: 640px) rule that stacks cards in one column (matching the PR’s mobile layout checklist).

[Low] Disconnect actions have no confirmation

File: apps/desktop/src/renderer/components/onboarding/LinearCard.tsx:L155-L157; apps/desktop/src/renderer/components/onboarding/GitHubCard.tsx:L88-L91
Issue: Disconnect clears tokens immediately with no confirm or undo, easy to mis-click during setup.
Fix: Add a lightweight confirm dialog or an undo toast consistent with other settings integrations.

[Low] About block renders nothing while app info loads

File: apps/desktop/src/renderer/components/settings/AboutSection.tsx:L82
Issue: if (!info) return null leaves the About section empty with no skeleton or “Loading…” for the duration of getInfo() / getLatestRelease() (often >300ms on cold open).
Fix: Show a compact loading placeholder in the card until info is available.


Notes

  • Positive: Claude thinking-transcript repair (claudeThinkingTranscriptRepair.ts) is well bounded (session id allowlist, in-place JSONL repair, tests), and the plan-mode composer fix plus system_notice on auto-exit address a real stuck-UI bug.
  • AboutSection + fetchAdeLatestRelease degrade gracefully when GitHub is unreachable; token use reuses existing encrypted store patterns.
  • General settings no longer surfaces local runtime service install/health (removed from GeneralSection); if that was intentional, consider whether operators still need it elsewhere (top bar, diagnostics).
  • Command palette Go to Usage still targets ?tab=usage → General; that predates this PR, but Background Jobs is now a separate tab — worth a follow-up palette entry.
Open in Web View Automation 

Sent by Cursor Automation: BUGBOT in Versic

Copy link
Copy Markdown

@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.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx (1)

19-39: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle IPC failures in finish/skip.

Neither handler catches errors from window.ade.onboarding.complete() / setDismissed(). Combined with onClick={() => void finish()}, a rejected IPC call becomes an unhandled promise rejection and the user sees the button silently revert to "Finish setup" with no indication the action failed.

Separately, busy is shared, so clicking Skip also flips the Finish button to "Saving...". Consider a dedicated flag or only showing the saving label for the finish action.

🛡️ Proposed error handling
   const finish = async () => {
     setBusy(true);
     try {
       const next = await window.ade.onboarding.complete();
       publishOnboardingStatusUpdated(next);
       navigate("/work", { replace: true });
+    } catch (err) {
+      console.error("Failed to complete onboarding", err);
+      // surface a user-visible error (toast/inline message) here
     } finally {
       setBusy(false);
     }
   };

(apply the same catch to skip)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx` around
lines 19 - 39, The finish and skip handlers (finish and skip) do not catch
errors from the IPC calls window.ade.onboarding.complete() and
window.ade.onboarding.setDismissed(), causing unhandled promise rejections and
no user feedback; update both functions to wrap the await calls in try/catch
(keeping the existing finally to setBusy(false)), log or surface the error to
the user (e.g., via a toast/error banner or process logger) inside the catch,
and return/short-circuit as appropriate; also separate the shared busy state
into two flags (e.g., finishBusy vs skipBusy or a dedicated isFinishing flag
used for the Finish button label) so clicking Skip does not change the Finish
button label.
🧹 Nitpick comments (1)
apps/desktop/src/main/services/chat/agentChatService.ts (1)

15289-15300: ⚡ Quick win

Extract the repair-and-log into a shared helper.

This repairClaudeResumeTranscript(...) + logger.warn("agent_chat.claude_thinking_transcript_repaired", {...}) block is now repeated three times (here, hunk 3 self-heal, and hunk 5 prewarm) with only the at value differing. A small helper removes the drift risk and centralizes the log shape.

♻️ Suggested helper (types illustrative)
function repairAndLogClaudeTranscript(
  managed: ManagedSession,
  sdkSessionId: string,
  worktreePath: string,
  at: "self_heal" | "resume" | "prewarm",
) {
  const repair = repairClaudeResumeTranscript(sdkSessionId, worktreePath);
  if (repair.repaired) {
    logger.warn("agent_chat.claude_thinking_transcript_repaired", {
      sessionId: managed.session.id,
      sdkSessionId,
      responsesRekeyed: repair.responsesRekeyed,
      reusedMessageIds: repair.reusedMessageIds,
      at,
    });
  }
  return repair;
}

Then each site collapses to e.g.:

-    if (!runtime.warmQuery && options.resume) {
-      const repair = repairClaudeResumeTranscript(options.resume, managed.laneWorktreePath);
-      if (repair.repaired) {
-        logger.warn("agent_chat.claude_thinking_transcript_repaired", {
-          sessionId: managed.session.id,
-          sdkSessionId: options.resume,
-          responsesRekeyed: repair.responsesRekeyed,
-          reusedMessageIds: repair.reusedMessageIds,
-          at: "resume",
-        });
-      }
-    }
+    if (!runtime.warmQuery && options.resume) {
+      repairAndLogClaudeTranscript(managed, options.resume, managed.laneWorktreePath, "resume");
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/chat/agentChatService.ts` around lines 15289 -
15300, The repeated pattern calling repairClaudeResumeTranscript(...) followed
by logger.warn("agent_chat.claude_thinking_transcript_repaired", {...}) should
be extracted into a single helper to avoid duplication and keep the log shape
consistent; add a function (e.g., repairAndLogClaudeTranscript(managed:
ManagedSession, sdkSessionId: string, worktreePath: string, at: "self_heal" |
"resume" | "prewarm")) that calls repairClaudeResumeTranscript(sdkSessionId,
worktreePath), checks repair.repaired, emits the logger.warn with sessionId:
managed.session.id, sdkSessionId, responsesRekeyed, reusedMessageIds and the
provided at value, returns the repair object, and replace the three inline
blocks with calls to this helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/main/services/chat/agentChatService.ts`:
- Around line 11004-11011: The warn call currently logs
"agent_chat.claude_thinking_transcript_repaired" even when
repairClaudeResumeTranscript(...) did not actually repair anything; update the
code to only emit this event when the repair result indicates a real fix (check
repair.repaired === true) by moving the logger.warn call inside an if
(repair.repaired) block (or alternatively change the event name to reflect
"detected" instead of "repaired"); reference the repairClaudeResumeTranscript
return value and the logger.warn invocation to implement this conditional
logging.

In `@apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts`:
- Around line 164-172: The current atomic rewrite uses a deterministic temp name
`${filePath}.repair-${process.pid}.tmp` (tmp) which can collide across
concurrent repairs; change tmp generation in claudeThinkingTranscriptRepair.ts
to a collision-safe name (for example include a random/unique suffix such as
crypto.randomUUID() or use fs.mkdtemp) so each operation writes to a unique temp
file before calling fs.writeFileSync(tmp, ...) and fs.renameSync(tmp, filePath);
keep the existing cleanup code paths that check fs.existsSync(tmp) and
fs.unlinkSync(tmp) but operate on the new unique tmp variable.

In `@apps/desktop/src/renderer/browserMock.ts`:
- Around line 5113-5125: The mock IPC contract is inconsistent: getStatus()
returns the extended shape but setToken() and clearToken() still return the old
shape; update setToken and clearToken to return the same object properties as
getStatus (include tokenStored, patTokenStored, tokenDecryptionFailed,
storageScope, authSource, tokenType, repo, hasOrigin, userLogin, scopes,
ghCliPath, ghAuthError) so renderer flows see a consistent response; locate the
mock handlers named getStatus, setToken, and clearToken in browserMock.ts and
make the mutation return values match the getStatus response shape exactly.

In `@apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx`:
- Around line 227-230: Update the stale helper text in the AiRuntimesBand
component: replace both occurrences of the hardcoded "Settings · AI" string
inside the JSX (in AiRuntimesBand.tsx) with the new settings tab label "Settings
· Integrations" so the helper links point to the renamed Settings tab.

In `@apps/desktop/src/renderer/components/onboarding/LinearCard.tsx`:
- Around line 10-19: The openExternal function currently bypasses the typed
preload contract by casting window.ade to unknown and falls back to window.open;
replace this with a call to the typed preload IPC API (use the existing preload
contract type for window.ade) and invoke the secure opener method
(opener.openExternal) without any unknown casts, and remove the raw window.open
fallback; instead, handle a missing opener by returning an error or logging via
the renderer logger and ensure callers know the promise rejection/void behavior;
refer to the openExternal function, window.ade, and opener.openExternal to
locate the code to update.
- Around line 61-82: The interval callback does not stop polling when
getLinearOAuthSession throws, so inside the catch block of the poll (the
function using pollRef and calling cto.getLinearOAuthSession({ sessionId }))
clear the interval (window.clearInterval(pollRef.current)), set pollRef.current
= null, setOauthBusy(false) and setOauthError(...) with the caught error (e.g.,
e instanceof Error ? e.message : String(e)) before returning; ensure this
mirrors the cleanup done for completed/failed/expired branches and keeps
refresh() behavior unchanged.

In `@apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx`:
- Around line 78-79: The fallback lane name currently derives from wt.path using
wt.path.split("/").pop(), which breaks on Windows; update WorktreesCard.tsx to
use a cross-platform basename (e.g., path.basename) instead: import the Node
path module and replace wt.path.split("/").pop() with path.basename(wt.path) so
the line that sets const name = wt.branch || wt.path.split("/").pop() ||
"worktree"; becomes const name = wt.branch || path.basename(wt.path) ||
"worktree"; (leave the subsequent await window.ade.lanes.attach({ name,
attachedPath: wt.path }) unchanged).

In `@apps/desktop/src/renderer/components/settings/AboutSection.tsx`:
- Around line 66-76: The manual update flow in AboutSection.tsx only toggles
checking via setChecking and never refreshes the latest release data, so after
updateCheckForUpdates completes the UI can still show stale info; update the
logic to re-fetch or update the latest-release state when the check finishes by
calling window.ade.app.getLatestRelease() (or using the AutoUpdateSnapshot
payload) either in the .catch/.finally of window.ade.updateCheckForUpdates()
inside checkForUpdates or inside the window.ade.onUpdateEvent handler that
receives AutoUpdateSnapshot, and then update the component state that holds the
latest release so the version/pill/release-notes link reflect the new release.

---

Outside diff comments:
In `@apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx`:
- Around line 19-39: The finish and skip handlers (finish and skip) do not catch
errors from the IPC calls window.ade.onboarding.complete() and
window.ade.onboarding.setDismissed(), causing unhandled promise rejections and
no user feedback; update both functions to wrap the await calls in try/catch
(keeping the existing finally to setBusy(false)), log or surface the error to
the user (e.g., via a toast/error banner or process logger) inside the catch,
and return/short-circuit as appropriate; also separate the shared busy state
into two flags (e.g., finishBusy vs skipBusy or a dedicated isFinishing flag
used for the Finish button label) so clicking Skip does not change the Finish
button label.

---

Nitpick comments:
In `@apps/desktop/src/main/services/chat/agentChatService.ts`:
- Around line 15289-15300: The repeated pattern calling
repairClaudeResumeTranscript(...) followed by
logger.warn("agent_chat.claude_thinking_transcript_repaired", {...}) should be
extracted into a single helper to avoid duplication and keep the log shape
consistent; add a function (e.g., repairAndLogClaudeTranscript(managed:
ManagedSession, sdkSessionId: string, worktreePath: string, at: "self_heal" |
"resume" | "prewarm")) that calls repairClaudeResumeTranscript(sdkSessionId,
worktreePath), checks repair.repaired, emits the logger.warn with sessionId:
managed.session.id, sdkSessionId, responsesRekeyed, reusedMessageIds and the
provided at value, returns the repair object, and replace the three inline
blocks with calls to this helper.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 079ba577-3d60-46ff-a500-b84ac6ec1340

📥 Commits

Reviewing files that changed from the base of the PR and between d99c8f5 and 288f926.

⛔ Files ignored due to path filters (2)
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
📒 Files selected for processing (30)
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.test.ts
  • apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts
  • apps/desktop/src/main/services/github/githubService.test.ts
  • apps/desktop/src/main/services/github/githubService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/app/CommandPalette.tsx
  • apps/desktop/src/renderer/components/app/SettingsPage.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx
  • apps/desktop/src/renderer/components/onboarding/DevToolsRow.tsx
  • apps/desktop/src/renderer/components/onboarding/GitHubCard.tsx
  • apps/desktop/src/renderer/components/onboarding/InputPopover.tsx
  • apps/desktop/src/renderer/components/onboarding/LinearCard.tsx
  • apps/desktop/src/renderer/components/onboarding/ProjectSetupPage.tsx
  • apps/desktop/src/renderer/components/onboarding/RescanButton.tsx
  • apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx
  • apps/desktop/src/renderer/components/onboarding/onboardingTheme.ts
  • apps/desktop/src/renderer/components/settings/AboutSection.tsx
  • apps/desktop/src/renderer/components/settings/AiSettingsSection.tsx
  • apps/desktop/src/renderer/components/settings/GeneralSection.tsx
  • apps/desktop/src/renderer/components/settings/IntegrationsSettingsSection.tsx
  • apps/desktop/src/renderer/components/settings/ProjectSection.tsx
  • apps/desktop/src/renderer/components/settings/WorkspaceSettingsSection.tsx
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/types/core.ts
💤 Files with no reviewable changes (3)
  • apps/desktop/src/renderer/components/settings/WorkspaceSettingsSection.tsx
  • apps/desktop/src/renderer/components/settings/ProjectSection.tsx
  • apps/desktop/src/renderer/components/settings/AiSettingsSection.tsx

Comment thread apps/desktop/src/main/services/chat/agentChatService.ts Outdated
Comment thread apps/desktop/src/main/services/chat/claudeThinkingTranscriptRepair.ts Outdated
Comment thread apps/desktop/src/renderer/browserMock.ts
Comment thread apps/desktop/src/renderer/components/onboarding/AiRuntimesBand.tsx Outdated
Comment thread apps/desktop/src/renderer/components/onboarding/LinearCard.tsx
Comment thread apps/desktop/src/renderer/components/onboarding/LinearCard.tsx
Comment thread apps/desktop/src/renderer/components/onboarding/WorktreesCard.tsx Outdated
Comment thread apps/desktop/src/renderer/components/settings/AboutSection.tsx Outdated
@arul28 arul28 force-pushed the ade/settings-refresh-2db507ca branch from 55d6bb3 to 4f4e060 Compare May 28, 2026 23:46
@arul28 arul28 merged commit 041d0ba into main May 29, 2026
28 checks passed
@arul28 arul28 deleted the ade/settings-refresh-2db507ca branch May 29, 2026 01:25
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.

1 participant