feat(sidebar): Agents tab + agent logos in terminal tabs#891
feat(sidebar): Agents tab + agent logos in terminal tabs#891roberto-fernandino wants to merge 27 commits into
Conversation
feat(tabs): select tabs by index within active space
…dow-shortcut feat(shortcuts): add ai toggle mini shortcut
…nd-palette feat: terminals in command-palette
Adds a new keyboard shortcut (Cmd+Shift+G by default) that switches the
sidebar to the Files/explorer view. Pairs naturally with Cmd+G (source
control) so the user can toggle between them without touching the mouse.
The shortcut uses cycleSidebarView("explorer") — same pattern as pane.source
uses for source-control — and is fully configurable in Settings > Shortcuts.
Also exposed as "Show Files sidebar" in the command palette.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tcut feat(shortcuts): add configurable shortcut to show Files sidebar
Documents and enforces the mandatory workflow: branch → commit → dual PR (fork + upstream cross-fork) → merge fork → back to main. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New "Agents" sidebar tab lists every Claude Code, Codex, Gemini, OpenCode and Cursor agent running in terminals, with status badges (working / needs input) and one-click navigation to the terminal tab - Terminal tabs whose agent is detected by the backend now show that tool's logo (Claude, Gemini, Codex/OpenCode, or robotic fallback) instead of the generic terminal icon - "Show Agents sidebar tab" toggle in Settings > General (default on); disabling it falls back to the Files view - Merged upstream additions: Codex/Gemini notification hooks, per-agent notification bell, jump-to-attention shortcut Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-and-logos feat(sidebar): Agents tab + agent logos in terminal tabs
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds an Agents sidebar with live process data, terminal tab decoration, shortcut and command-palette changes, cursor-driven git blame in the status bar, a terminal cursor-style preference, and a repository PR workflow skill document. ChangesAgents sidebar and terminal workflow
Estimated code review effort: 5 (Critical) | ~120 minutes Editor cursor-driven git blame in status bar
Estimated code review effort: 4 (Complex) | ~45 minutes Terminal cursor style preference
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related PRs
Poem A rabbit hops through terminal panes, 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 @.claude/skills/terax-pr-workflow/SKILL.md:
- Line 74: The skill document contains an emoji in the generated-by line, which
violates the no-emojis rule. Remove the robot emoji from the affected line in
SKILL.md and keep the rest of the attribution text unchanged so the document
remains compliant with the project-wide formatting guidelines.
- Around line 33-35: The workflow instruction currently uses npx for
type-checking, which conflicts with the repo’s pnpm-only convention. Update the
type-checking command in SKILL.md to use pnpm exec tsc --noEmit (or the existing
check-types script via pnpm) and ensure any references in this workflow doc
consistently avoid npx/npm/yarn; this change is localized to the type-checking
step in the skill instructions.
In `@src/app/App.tsx`:
- Line 687: The “Show Files” command is currently routed through the
toggle-style sidebar helper, so repeated invocations can collapse the explorer
instead of keeping Files open. Update the `sidebar.files` command in `App.tsx`
and the matching palette shortcut path to call the sidebar state setter directly
(or otherwise force the explorer view) instead of
`cycleSidebarView("explorer")`, using the existing sidebar/view logic in `App`
so the action is idempotent.
- Around line 1162-1167: The AgentsPanel selection is only updating activeId,
which breaks cross-space navigation because the workspace can switch to a tab
from another space while the current space UI stays unchanged. In App.tsx,
update the AgentsPanel onSelectTab handler to use the existing space-aware
activation flow used elsewhere in App (the one that changes both the active tab
and the current space/header state) instead of calling setActiveId directly, so
selecting an agent correctly navigates the workspace and keeps the tab strip and
header in sync.
In `@src/modules/agents-panel/AgentsPanel.tsx`:
- Around line 7-10: The agent selection flow in AgentsPanel is using only
setActiveId, which can activate the wrong space or leaf. Update AgentsPanel to
use the existing activation path by threading activateAgentTarget from App
instead of onSelectTab/setActiveId, and ensure the selection action carries both
tabId and leafId so it follows the same notification-style activation flow
across spaces and mounted tabs. Use the AgentsPanel props and App wiring to
locate the callback replacement and keep the activation logic consistent with
the app’s existing target-based flow.
In `@src/modules/ai/components/AiStatusBarControls.tsx`:
- Around line 172-174: The IconBtn in AiStatusBarControls is using the wrong
handler for the mini chat window open/close state: when miniOpen is true the
title says Close, but onClick still calls openMini(), so clicking cannot close
it. Update this control to use toggleMini (or otherwise call the close path when
miniOpen is already true) so the button behavior matches the title and state.
🪄 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 Plus
Run ID: c4bd6798-1fec-43d5-998b-d93f37fa5436
📒 Files selected for processing (19)
.claude/skills/terax-pr-workflow/SKILL.mdpackage.jsonsrc/app/App.tsxsrc/modules/agents-panel/AgentsPanel.tsxsrc/modules/agents-panel/index.tssrc/modules/agents/lib/agentIcon.tsxsrc/modules/agents/lib/format.tssrc/modules/ai/components/AiStatusBarControls.tsxsrc/modules/command-palette/commands.tssrc/modules/header/Header.tsxsrc/modules/settings/store.tssrc/modules/shortcuts/shortcuts.tssrc/modules/sidebar/SidebarRail.tsxsrc/modules/sidebar/types.tssrc/modules/sidebar/useSidebarPanel.tssrc/modules/tabs/TabBar.tsxsrc/modules/tabs/lib/pickTabBySpaceIndex.test.tssrc/modules/tabs/lib/useTabs.tssrc/settings/sections/GeneralSection.tsx
| ```bash | ||
| npx tsc --noEmit | ||
| ``` |
There was a problem hiding this comment.
Use pnpm instead of npx for type-checking.
The project conventions mandate pnpm exclusively, never npm/npx. The repo already defines "check-types": "tsc --noEmit" in package.json and all other documentation (PR template, CONTRIBUTING.md) uses pnpm exec tsc --noEmit. Using npx here risks version skew from a globally-installed tsc and breaks workflow consistency. As per coding guidelines, pnpm only, never npm/npx/yarn.
🤖 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 @.claude/skills/terax-pr-workflow/SKILL.md around lines 33 - 35, The workflow
instruction currently uses npx for type-checking, which conflicts with the
repo’s pnpm-only convention. Update the type-checking command in SKILL.md to use
pnpm exec tsc --noEmit (or the existing check-types script via pnpm) and ensure
any references in this workflow doc consistently avoid npx/npm/yarn; this change
is localized to the type-checking step in the skill instructions.
Source: Coding guidelines
| ## Test plan | ||
| - [ ] item | ||
|
|
||
| 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
There was a problem hiding this comment.
Remove emoji from skill document.
The robot emoji violates the project-wide "No emojis anywhere" rule that applies to code, comments, commits, and docs. As per coding guidelines, no emojis anywhere.
🤖 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 @.claude/skills/terax-pr-workflow/SKILL.md at line 74, The skill document
contains an emoji in the generated-by line, which violates the no-emojis rule.
Remove the robot emoji from the affected line in SKILL.md and keep the rest of
the attribution text unchanged so the document remains compliant with the
project-wide formatting guidelines.
Source: Coding guidelines
| "pane.focusNext": () => focusNextPaneInTab(activeId, 1), | ||
| "pane.focusPrev": () => focusNextPaneInTab(activeId, -1), | ||
| "pane.source": toggleSourceControl, | ||
| "sidebar.files": () => cycleSidebarView("explorer"), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
"Show Files" is wired through a toggle path.
Both call sites use cycleSidebarView("explorer"), which collapses the sidebar when Files is already open. That makes the new shortcut and palette command non idempotent and can hide the explorer on repeated use.
Also applies to: 1014-1014
🤖 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 `@src/app/App.tsx` at line 687, The “Show Files” command is currently routed
through the toggle-style sidebar helper, so repeated invocations can collapse
the explorer instead of keeping Files open. Update the `sidebar.files` command
in `App.tsx` and the matching palette shortcut path to call the sidebar state
setter directly (or otherwise force the explorer view) instead of
`cycleSidebarView("explorer")`, using the existing sidebar/view logic in `App`
so the action is idempotent.
| <IconBtn | ||
| title={miniOpen ? "Mini-window open" : "Open conversation"} | ||
| title={`${miniOpen ? "Close" : "Open"} AI chat window (${fmtShortcut("⇧", MOD_KEY, "I")})`} | ||
| onClick={openMini} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
This button cannot close the mini window.
The new title says "Close" when miniOpen is true, but the handler still calls openMini(), so that path is now a no-op. Use toggleMini here, or branch to a close action when the mini window is already open.
Suggested fix
- const openMini = useChatStore((s) => s.openMini);
+ const toggleMini = useChatStore((s) => s.toggleMini);
@@
- onClick={openMini}
+ onClick={toggleMini}📝 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.
| <IconBtn | |
| title={miniOpen ? "Mini-window open" : "Open conversation"} | |
| title={`${miniOpen ? "Close" : "Open"} AI chat window (${fmtShortcut("⇧", MOD_KEY, "I")})`} | |
| onClick={openMini} | |
| <IconBtn | |
| title={`${miniOpen ? "Close" : "Open"} AI chat window (${fmtShortcut("⇧", MOD_KEY, "I")})`} | |
| onClick={toggleMini} |
🤖 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 `@src/modules/ai/components/AiStatusBarControls.tsx` around lines 172 - 174,
The IconBtn in AiStatusBarControls is using the wrong handler for the mini chat
window open/close state: when miniOpen is true the title says Close, but onClick
still calls openMini(), so clicking cannot close it. Update this control to use
toggleMini (or otherwise call the close path when miniOpen is already true) so
the button behavior matches the title and state.
When an agent process starts (claude, codex, etc.) it was immediately shown as "working" even though it was just sitting at its idle prompt. Added "idle" as a third AgentStatus. The "started" signal now sets idle; only the explicit "working" signal (fired when the agent begins executing a task) promotes it to working. The sidebar badge count excludes idle sessions so the badge only lights up during real activity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(agents): show idle status when agent is at prompt, not working
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…efault feat(ai): open AI panel by default on startup
- "finished" signal now sets status back to "idle" instead of "waiting" so the badge only lights up on genuine attention requests, not routine task completions - Added a useEffect in App.tsx: when the active tab becomes a terminal that has a waiting agent, reset it to idle — the user is already looking at it so the notification is no longer relevant; covers all nav paths (tab click, keyboard shortcut, notification bell, agents panel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on-focus fix(agents): clear needs-input when tab focused; finished resets to idle
Ctrl+C interrupts Claude Code without firing a finished signal, leaving the status permanently stuck on "working". Extend the tab-focus effect to reset any non-idle status (waiting or working) to idle when the user navigates to the terminal. If the agent is genuinely still running, the backend will fire the next working signal and promote it back immediately. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ck-on-interrupt fix(agents): reset working status to idle when terminal tab is focused
…working status Depending on tabs (not tabsRef) caused the effect to re-run on every tab title update. While the agent was working and the user was already on the terminal tab, the next title change re-ran the effect and reset working→idle, breaking real-time status display. Switching to tabsRef means the effect only fires when activeId actually changes (true navigation), not on content updates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a terminalCursorStyle preference that lets users choose between bar, block, and underline cursor shapes in the terminal, matching VS Code's terminal cursor style options. Defaults to bar (previous hardcoded value). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tyle feat(terminal): add cursor style setting (bar/block/underline)
…pboard) Resolves conflicts between fork additions (showAgentsTab, cursor style) and upstream additions (defaultWorkspaceEnv, sidebar collapsed persistence, native clipboard on Linux). Both sides preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When editing a file, the status bar now shows who last committed the current cursor line and how long ago, e.g. "Roberto (2 days ago)". Adds a git_blame Tauri command (git blame -L line,line --porcelain), cursor tracking via a CodeMirror updateListener, debounced blame fetching (300ms), and a relative-time display in the status bar footer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(editor): show git blame for current line in status bar
bd1bdb0 to
1a3af38
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.claude/skills/terax-pr-workflow/SKILL.md (2)
33-35: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winUse pnpm here too.
npx tsc --noEmitconflicts with the repo's pnpm-only workflow, and the same command still appears again in the rules section. As per coding guidelines, "pnpm only, never npm/npx/yarn."Also applies to: 129-129
🤖 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 @.claude/skills/terax-pr-workflow/SKILL.md around lines 33 - 35, The workflow still uses npx tsc --noEmit, which conflicts with the pnpm-only rule. Update the command in SKILL.md to use pnpm for the TypeScript check, and also replace the duplicate occurrence in the rules section so both references are consistent. Use the existing tsc command text in this skill doc to find and fix both instances.Source: Coding guidelines
90-90: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRemove the generated-by emoji.
The robot emoji still violates the repository-wide no-emojis rule for docs. As per coding guidelines, "No emojis anywhere."
🤖 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 @.claude/skills/terax-pr-workflow/SKILL.md at line 90, Remove the generated-by footer emoji from the skill doc; the “Generated with [Claude Code]” line still includes a robot emoji and violates the no-emojis rule. Update the footer text in the SKILL.md content so it remains plain text only, with no emoji characters anywhere.Source: Coding guidelines
🧹 Nitpick comments (2)
src/modules/terminal/lib/rendererPool.ts (1)
938-944: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winImport
TerminalCursorStyleinstead of re-declaring the union.
applyCursorStyle's param type duplicates the"bar" | "block" | "underline"literal fromsettings/store.ts'sTerminalCursorStyle. If the settings union ever gains a value, this copy silently goes stale instead of surfacing a type error at the call site.♻️ Suggested fix
+import type { TerminalCursorStyle } from "`@/modules/settings/store`"; + -export function applyCursorStyle(style: "bar" | "block" | "underline"): void { +export function applyCursorStyle(style: TerminalCursorStyle): void {🤖 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 `@src/modules/terminal/lib/rendererPool.ts` around lines 938 - 944, The applyCursorStyle function currently re-declares the cursor-style union inline, which can drift from settings/store.ts. Update applyCursorStyle to use the shared TerminalCursorStyle type instead of the hardcoded "bar" | "block" | "underline" union, and import that symbol where the function is defined so any future enum changes surface type errors automatically.src-tauri/src/modules/git/operations.rs (1)
1150-1201: 🚀 Performance & Scalability | 🔵 TrivialEvery blamed line == a fresh
git blamechild process.Correctness here is solid (line==0 guard, uncommitted-line filter, graceful
Ok(None)fallbacks). The one thing worth flagging for an app whose whole pitch is "ultra-lightweight": each cursor pause spawns a brand-newgit blame -Lprocess. On a big-history repo or a busy editing session that's a lot of forks for a single-line lookup. A small in-memory cache keyed by(path, line, mtime)(or invalidated on save) would cut this down without touching the correctness logic above.🤖 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 `@src-tauri/src/modules/git/operations.rs` around lines 1150 - 1201, `blame_line` in `operations.rs` currently spawns a new `git blame -L` process for every single-line lookup, which is too expensive for repeated cursor movements. Add a small in-memory cache around `blame_line` keyed by `(path, line, mtime)` or invalidate it on file save, and reuse cached `GitBlameLineInfo` results before calling `run_git`. Keep the existing `canonical_dir`, authorization, `ensure_git_available`, and `Ok(None)` fallback behavior intact.
🤖 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 `@src-tauri/src/modules/proc.rs`:
- Around line 24-27: `proc_list_processes` is currently a synchronous Tauri
command, so the `platform_processes()` scan can block the main UI thread during
polling. Update `proc_list_processes` to be async and run `platform_processes()`
inside `tauri::async_runtime::spawn_blocking(...)`, then await the result and
return the same `Result<Vec<ProcessInfo>, String>` shape. Use the existing
blocking-command pattern in this module as the reference point so the command
stays non-blocking while preserving behavior.
In `@src/modules/ai/lib/native.ts`:
- Around line 389-395: The `gitBlame` call in `App.tsx`’s
`handleEditorCursorChange` needs a staleness/dirty guard because older async
results can overwrite newer cursor state and unsaved edits make the line number
drift from the on-disk file. Update the caller to ignore stale `gitBlame`
responses (for example by tracking the latest request or cursor state and
discarding out-of-date promises) and skip blame updates while the editor buffer
is dirty or otherwise reconcile against the saved document state before calling
`native.gitBlame`.
---
Duplicate comments:
In @.claude/skills/terax-pr-workflow/SKILL.md:
- Around line 33-35: The workflow still uses npx tsc --noEmit, which conflicts
with the pnpm-only rule. Update the command in SKILL.md to use pnpm for the
TypeScript check, and also replace the duplicate occurrence in the rules section
so both references are consistent. Use the existing tsc command text in this
skill doc to find and fix both instances.
- Line 90: Remove the generated-by footer emoji from the skill doc; the
“Generated with [Claude Code]” line still includes a robot emoji and violates
the no-emojis rule. Update the footer text in the SKILL.md content so it remains
plain text only, with no emoji characters anywhere.
---
Nitpick comments:
In `@src-tauri/src/modules/git/operations.rs`:
- Around line 1150-1201: `blame_line` in `operations.rs` currently spawns a new
`git blame -L` process for every single-line lookup, which is too expensive for
repeated cursor movements. Add a small in-memory cache around `blame_line` keyed
by `(path, line, mtime)` or invalidate it on file save, and reuse cached
`GitBlameLineInfo` results before calling `run_git`. Keep the existing
`canonical_dir`, authorization, `ensure_git_available`, and `Ok(None)` fallback
behavior intact.
In `@src/modules/terminal/lib/rendererPool.ts`:
- Around line 938-944: The applyCursorStyle function currently re-declares the
cursor-style union inline, which can drift from settings/store.ts. Update
applyCursorStyle to use the shared TerminalCursorStyle type instead of the
hardcoded "bar" | "block" | "underline" union, and import that symbol where the
function is defined so any future enum changes surface type errors
automatically.
🪄 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 Plus
Run ID: 5159f516-e2d3-4417-8ed4-22fdb6f7d788
📒 Files selected for processing (21)
.claude/skills/terax-pr-workflow/SKILL.mdsrc-tauri/src/lib.rssrc-tauri/src/modules/git/commands.rssrc-tauri/src/modules/git/operations.rssrc-tauri/src/modules/git/types.rssrc-tauri/src/modules/proc.rssrc/app/App.tsxsrc/app/components/WorkspaceSurface.tsxsrc/modules/agents-panel/AgentsPanel.tsxsrc/modules/agents-panel/ProcessesSection.tsxsrc/modules/agents-panel/processClassifier.tssrc/modules/ai/lib/native.tssrc/modules/editor/EditorPane.tsxsrc/modules/editor/EditorStack.tsxsrc/modules/settings/store.tssrc/modules/sidebar/SidebarRail.tsxsrc/modules/sidebar/useSidebarPanel.tssrc/modules/statusbar/StatusBar.tsxsrc/modules/terminal/lib/rendererPool.tssrc/modules/terminal/lib/useTerminalSession.tssrc/settings/sections/GeneralSection.tsx
✅ Files skipped from review due to trivial changes (1)
- src/modules/agents-panel/processClassifier.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/modules/agents-panel/AgentsPanel.tsx
- src/modules/sidebar/SidebarRail.tsx
- src/modules/sidebar/useSidebarPanel.ts
| #[tauri::command] | ||
| pub fn proc_list_processes() -> Result<Vec<ProcessInfo>, String> { | ||
| platform_processes() | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does Tauri 2 execute non-async #[tauri::command] handlers on the main thread by default?
💡 Result:
Yes, in Tauri 2, #[tauri::command] handlers that are not defined as async are executed on the main thread by default [1][2]. Because the main thread is also responsible for the UI, executing long-running or blocking code in a non-async command will cause the application's interface to freeze or become unresponsive [2][3]. To prevent this, Tauri recommends using async commands, which are executed on a separate async task using the runtime's task spawning mechanism [2][4]. You can define a command as async either by using the async keyword in the function signature (e.g., async fn) or by using the #[tauri::command(async)] attribute [2][4].
Citations:
- 1: https://v2.tauri.app/develop/calling-rust/
- 2: https://github.com/tauri-apps/tauri-docs/blob/v2/src/content/docs/develop/calling-rust.mdx
- 3: Any documentation about the main thread? tauri-apps/tauri#3561
- 4: Run command in the background tauri-apps/tauri#7737
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== proc.rs ==\n'
sed -n '1,220p' src-tauri/src/modules/proc.rs
printf '\n== search for ProcessesSection ==\n'
rg -n "ProcessesSection|proc_list_processes|platform_processes|spawn_blocking|blocking\\(" src src-tauri -g '!target'
printf '\n== relevant UI file if found ==\n'
fd -a ".*process.*" src | head -n 20Repository: crynta/terax-ai
Length of output: 8140
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== ProcessesSection.tsx ==\n'
sed -n '1,220p' src/modules/agents-panel/ProcessesSection.tsx
printf '\n== processClassifier.ts ==\n'
sed -n '1,220p' src/modules/agents-panel/processClassifier.tsRepository: crynta/terax-ai
Length of output: 8827
Move proc_list_terminal_processes off the UI thread
#[tauri::command] without async runs on Tauri’s main thread, so this synchronous ps / PowerShell scan can freeze the UI every 4s while the Agents panel polls it. Make it async and wrap platform_processes() in tauri::async_runtime::spawn_blocking(...), matching the existing blocking-command pattern elsewhere.
🤖 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 `@src-tauri/src/modules/proc.rs` around lines 24 - 27, `proc_list_processes` is
currently a synchronous Tauri command, so the `platform_processes()` scan can
block the main UI thread during polling. Update `proc_list_processes` to be
async and run `platform_processes()` inside
`tauri::async_runtime::spawn_blocking(...)`, then await the result and return
the same `Result<Vec<ProcessInfo>, String>` shape. Use the existing
blocking-command pattern in this module as the reference point so the command
stays non-blocking while preserving behavior.
| gitBlame: (cwd: string, path: string, line: number) => | ||
| invoke<GitBlameLineInfo | null>("git_blame", { | ||
| cwd, | ||
| path, | ||
| line, | ||
| workspace: currentWorkspaceEnv(), | ||
| }), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Blame result can race stale, and doesn't account for unsaved edits.
Not a bug in this wrapper itself, but the contract it hands back needs a staleness/dirty guard at the call site (App.tsx's handleEditorCursorChange, visible in the supplied graph context):
- The debounce there only clears the
setTimeout; it never cancels the in-flightgitBlamepromise. An older, slower response can resolve after a newer one and overwrite the status bar with the wrong line's author. git blamereflects the on-disk file. While the tab is dirty (unsaved lines inserted/removed above the cursor), thelinesent no longer maps to the same physical line, so the author shown can be attributed to the wrong line/commit — and this is the common case while actively editing, not a corner case.
🩹 Sketch of the fix (in the caller, not this file)
const handleEditorCursorChange = useCallback(
(id: number, line: number, _col: number) => {
if (id !== activeId) return;
const tab = tabsRef.current.find((t) => t.id === id);
if (!tab || tab.kind !== "editor") return;
const filePath = tab.path;
const cwd = explorerRoot ?? launchCwd ?? home;
- if (!cwd || !filePath || line < 1) {
+ if (!cwd || !filePath || line < 1 || tab.dirty) {
setBlameInfo(null);
return;
}
if (blameDebounceRef.current) clearTimeout(blameDebounceRef.current);
+ const requestedLine = line;
blameDebounceRef.current = setTimeout(() => {
- native.gitBlame(cwd, filePath, line).then(setBlameInfo).catch(() => {
- setBlameInfo(null);
- });
+ native.gitBlame(cwd, filePath, requestedLine).then((info) => {
+ if (pendingLineRef.current !== requestedLine) return; // superseded
+ setBlameInfo(info);
+ }).catch(() => setBlameInfo(null));
}, 300);
},
[activeId, explorerRoot, launchCwd, home],
);🤖 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 `@src/modules/ai/lib/native.ts` around lines 389 - 395, The `gitBlame` call in
`App.tsx`’s `handleEditorCursorChange` needs a staleness/dirty guard because
older async results can overwrite newer cursor state and unsaved edits make the
line number drift from the on-disk file. Update the caller to ignore stale
`gitBlame` responses (for example by tracking the latest request or cursor state
and discarding out-of-date promises) and skip blame updates while the editor
buffer is dirty or otherwise reconcile against the saved document state before
calling `native.gitBlame`.
1a3af38 to
c84686d
Compare
Summary
Test plan
claudein a terminal — tab icon changes to Claude logo; session appears in Agents sidebarpnpm lint && pnpm check-types && pnpm testall pass🤖 Generated with Claude Code
Summary by CodeRabbit