Skip to content

refactor: streamline component props and improve readability - #3

Merged
Meanski merged 6 commits into
mainfrom
fix/sonarqube-rd-1
Jul 10, 2026
Merged

refactor: streamline component props and improve readability#3
Meanski merged 6 commits into
mainfrom
fix/sonarqube-rd-1

Conversation

@Meanski

@Meanski Meanski commented Jul 10, 2026

Copy link
Copy Markdown
Owner
  • Refactored StatusBar to use a utility function for counting active tunnels.
  • Updated TabBar to use Readonly types for props and consolidated tab icon rendering logic.
  • Simplified DisconnectedOverlay by extracting reconnect label logic into a separate function.
  • Introduced StatusDot component in HostHeader for better status representation.
  • Enhanced SnippetRunner with a VarInput component for variable input handling.
  • Improved TerminalSearchBar by extracting results label logic into a dedicated function.
  • Added cooldown management in TerminalView for connection retries.
  • Resolved SSH credentials in a separate function for clarity.
  • Refactored TunnelsView to improve toggle icon logic and component structure.
  • Updated UnlockScreen components to use Readonly types for props.
  • Enhanced color generation logic in colors.ts for better performance.
  • Improved memory formatting in format.ts for better type handling.
  • Simplified store logic in index.ts for session type handling and tab view mapping.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Remote Desktop connection reliability, frame integrity, and non-interactive certificate handling, with clearer end-session/error messaging.
    • Enhanced Docker log streaming and exec error reporting.
    • Strengthened connection-form validation (including DB SSL/Redis DB ranges) and improved session cleanup across connections.
    • Added support for parameterized database queries from the UI/API.
  • Accessibility
    • Expanded keyboard support and improved semantic controls (buttons, Enter/Space/Escape, click-outside behavior) across key navigation and dialogs.
  • Tests
    • Expanded automated Vitest coverage across IPC, connection workflows, and major UI components.

- Refactored StatusBar to use a utility function for counting active tunnels.
- Updated TabBar to use Readonly types for props and consolidated tab icon rendering logic.
- Simplified DisconnectedOverlay by extracting reconnect label logic into a separate function.
- Introduced StatusDot component in HostHeader for better status representation.
- Enhanced SnippetRunner with a VarInput component for variable input handling.
- Improved TerminalSearchBar by extracting results label logic into a dedicated function.
- Added cooldown management in TerminalView for connection retries.
- Resolved SSH credentials in a separate function for clarity.
- Refactored TunnelsView to improve toggle icon logic and component structure.
- Updated UnlockScreen components to use Readonly types for props.
- Enhanced color generation logic in colors.ts for better performance.
- Improved memory formatting in format.ts for better type handling.
- Simplified store logic in index.ts for session type handling and tab view mapping.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Meanski, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10d69058-e266-4ca3-9005-7f3ad0c14aa6

📥 Commits

Reviewing files that changed from the base of the PR and between ce98dc7 and a4b048e.

📒 Files selected for processing (2)
  • src/renderer/src/components/Database/DatabaseExplorer.tsx
  • src/renderer/src/components/Runner/RunnerView.tsx
📝 Walkthrough

Walkthrough

This PR hardens RDP transport and diagnostics, adds parameterized database queries, refactors IPC and renderer components, improves validation and accessibility behavior, expands automated coverage, and enables Vitest coverage reporting in CI.

Changes

RDP transport and session diagnostics

Layer / File(s) Summary
RDP sidecar and frame pipeline
native/rdp-spike/sidecar.c, src/main/ipc/rdp.ts, src/renderer/src/components/RDP/RdpView.tsx
Certificate handling, credential parsing, binary stdout framing, frame validation, sidecar diagnostics, connection sizing, and throttled canvas rendering are updated.
RDP validation coverage
src/main/ipc/__tests__/rdp.test.ts, src/renderer/src/components/RDP/__tests__/RdpView.test.tsx
Tests cover process wiring, frame buffering and resynchronization, stderr reasons, lifecycle ownership, credential requirements, rendering, and cleanup.

IPC service and contract changes

Layer / File(s) Summary
Database query and connection contracts
src/main/ipc/database.ts, src/preload/index.ts, src/preload/index.d.ts, src/main/ipc/__tests__/database.test.ts
Validated scalar query parameters flow through IPC into PostgreSQL and MySQL drivers, SSL validation is shared, and database behavior is tested.
IPC service orchestration
src/main/ipc/docker.ts, src/main/ipc/k8s.ts, src/main/ipc/sftp.ts, src/main/ipc/ssh.ts, src/main/ipc/tunnels.ts
Log streaming, Kubernetes forwarding, SFTP operations, SSH shell setup and metrics polling, SOCKS forwarding, and tunnel cleanup are extracted and updated.
Parsing and validation helpers
src/main/ipc/sshConfig.ts, src/main/ipc/sessionTransfer.ts, src/main/ipc/metrics.ts, src/main/ipc/security.ts
SSH directives, imported session fields, metrics values, blocked-command ordering, and path validation are refactored or tightened.

Renderer behavior and composition

Layer / File(s) Summary
Connection and database interfaces
src/renderer/src/components/ConnectionManager/*, src/renderer/src/components/Database/DatabaseExplorer.tsx
Connection form validation and persistence are unified, configuration sections are extracted, SQL cell updates use parameters, CSV escaping is revised, and database panels are decomposed.
View routing and feature panels
src/renderer/src/components/MainContent.tsx, src/renderer/src/components/SFTP/*, src/renderer/src/components/Redis/*, src/renderer/src/components/Terminal/*
View dispatch, terminal panes, SFTP rows and overlays, Redis panes, credential resolution, snippet variables, and status helpers are reorganized.
Accessible controls and shared display helpers
src/renderer/src/components/Sidebar/*, src/renderer/src/components/Dashboard/*, src/renderer/src/components/K8s/*, src/renderer/src/components/TabBar/*, src/renderer/src/lib/*, src/renderer/src/store/index.ts
Interactive containers become semantic buttons, keyboard handling is added, color/status helpers are centralized, props are made readonly, and session types map through shared tab-view logic.

Test infrastructure and CI

Layer / File(s) Summary
Shared renderer test harness
src/renderer/src/__tests__/harness.tsx, src/renderer/src/components/**/__tests__/*
Reusable window API, session, tab, and store fixtures support broad component behavior tests.
IPC and utility coverage
src/main/ipc/__tests__/*, src/renderer/src/lib/__tests__/*, src/renderer/src/store/__tests__/*
Coverage is added for IPC handlers, parsing, formatting, colors, store tab mapping, and renderer workflows.
Coverage configuration
vitest.config.ts, package.json, .github/workflows/ci.yml, .gitignore, sonar-project.properties, tsconfig.web.json
Vitest TSX matching, V8 reports, watch and coverage scripts, CI coverage execution, ignored coverage output, Sonar test targeting, and JSX configuration are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Meanski/noxed#1: Earlier Windows-RDP work introduced the related sidecar framing and IPC behavior further modified here.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main theme: prop refactors and readability-focused cleanup across components and utilities.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sonarqube-rd-1

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.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (3)
src/renderer/src/components/Settings/Settings.tsx (2)

1196-1202: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

handleConfirm can get stuck in "Clearing…" forever on failure.

await onConfirm() has no try/catch/finally. If it rejects, clearing never resets to false, and the buttons stay disabled with no way to retry, dismiss, or see an error — for a destructive credential-wipe action.

As per coding guidelines, renderer code should "catch errors from IPC and surface them to the user via the notification system or inline error state."

🛡️ Proposed fix
 const handleConfirm = async () => {
   setClearing(true)
-  await onConfirm()
+  try {
+    await onConfirm()
+  } catch (err: any) {
+    setClearing(false)
+    // surface err to the user, e.g. via a local error state or addNotification
+  }
 }
🤖 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/renderer/src/components/Settings/Settings.tsx` around lines 1196 - 1202,
Update ClearCredentialsModal.handleConfirm to catch failures from onConfirm,
reset clearing to false in a finally block so the modal remains usable, and
surface the caught error through the renderer’s notification system or an inline
error state. Preserve the successful confirmation flow while allowing retry or
dismissal after failure.

Source: Coding guidelines


1017-1047: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Inconsistent submit timing between button and keyboard input for PIN entry.

The button path (pressKey) now delays onSubmit by 80ms via setTimeout on the 4th digit, but the keyboard handler submits immediately with no delay — a newly introduced divergence between two code paths implementing the same digit-collection logic.

♻️ Suggested consolidation

Route the keyboard handler's digit-entry logic through the same pressKey function instead of duplicating it, so both paths share identical timing:

   useEffect(() => {
     const handler = (e: KeyboardEvent) => {
       if (loading) return
-      if (/^\d$/.test(e.key) && digits.length < 4) {
-        const next = [...digits, e.key]
-        setDigits(next)
-        if (next.length === 4) { onSubmit(next.join('')); setDigits([]) }
-      }
-      if (e.key === 'Backspace') setDigits(d => d.slice(0, -1))
+      if (/^\d$/.test(e.key)) pressKey(e.key)
+      if (e.key === 'Backspace') pressKey('⌫')
     }
     window.addEventListener('keydown', handler)
     return () => window.removeEventListener('keydown', handler)
   }, [digits, loading])
🤖 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/renderer/src/components/Settings/Settings.tsx` around lines 1017 - 1047,
Unify PIN digit handling so keyboard and button input use the same submission
timing. In VerifyPinInput, route numeric keyboard events through pressKey
instead of duplicating digit collection and immediate submission logic, while
retaining Backspace handling separately.
src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx (1)

137-146: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

MariaDB gets the wrong default port.

database returns 3306 only for mysql; MariaDB (a supported dbType, per the DatabaseFields options and DB_TYPE_LABELS) falls through to 5432. MariaDB listens on 3306.

🐛 Proposed fix
-      case 'database': return form.dbType === 'mysql' ? '3306' : '5432'
+      case 'database': return form.dbType === 'postgresql' ? '5432' : '3306'
🤖 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/renderer/src/components/ConnectionManager/AddConnectionModal.tsx` around
lines 137 - 146, Update getDefaultPort in AddConnectionModal so the database
case returns 3306 for both mysql and mariadb, while retaining 5432 for other
database types.
🧹 Nitpick comments (6)
src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx (1)

317-363: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Avoid any in these new signatures.

k8sSessionData()/sessionData() return any, persistSession(data: any), and the extracted components (PasswordInput, SshFields, DatabaseFields, K8sContextForm, ConfigForm) all type form: any. This drops type safety across the save path (e.g. a typo in a session field would go unnoticed). Consider defining a SessionData/FormState type and threading it through. As per coding guidelines: "No any in function signatures. Use unknown and narrow, or define a proper type."

🤖 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/renderer/src/components/ConnectionManager/AddConnectionModal.tsx` around
lines 317 - 363, The new save-path signatures use any, removing type safety
across session creation and extracted form components. Define explicit
SessionData and FormState types based on the supported connection fields, then
apply them to k8sSessionData, sessionData, persistSession, and the form props
for PasswordInput, SshFields, DatabaseFields, K8sContextForm, and ConfigForm;
use appropriate narrowing or unknown where needed instead of any.

Source: Coding guidelines

src/renderer/src/components/Database/DatabaseExplorer.tsx (1)

530-654: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer unknown over any for dynamic cell values.

ResultCell/RowDetailPanel (row: any) and SmartCell/JsonCell (value/parsed: any) type genuinely-dynamic DB values as any, which suppresses narrowing everywhere they flow. As per coding guidelines ("No any in function signatures. Use unknown and narrow, or define a proper type"), unknown fits these cases and forces explicit checks (which the code already does via == null/typeof).

🤖 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/renderer/src/components/Database/DatabaseExplorer.tsx` around lines 530 -
654, Replace any in the function signatures of ResultCell, RowDetailPanel,
SmartCell, JsonCell, and tryParseJsonCell with unknown, including
row/value/parsed parameters and return types as appropriate. Add explicit
narrowing for property access, object checks, JSON parsing, Object.keys, and
rendering so dynamic database values remain type-safe without any.

Source: Coding guidelines

src/main/ipc/tunnels.ts (1)

139-172: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No timeout on forwardOut — a hung SSH server leaves the SOCKS connection open indefinitely.

entry.conn.client.forwardOut has no timeout guard; if the SSH server never invokes the callback, the accepted local socket (and its OS resources) stay open forever.

🔒️ Proposed fix to add a timeout guard
 function handleSocksConnect(entry: ActiveTunnel, socket: Socket, request: Buffer): void {
   const parsed = parseSocksConnectRequest(request)
   if ('errorCode' in parsed) {
     socket.end(socksConnectReply(parsed.errorCode))
     return
   }
+  const timeout = setTimeout(() => {
+    socket.end(socksConnectReply(SOCKS_REPLY.connectionRefused))
+  }, 15_000)
   entry.conn.client.forwardOut(
     socket.remoteAddress ?? '127.0.0.1',
     socket.remotePort ?? 0,
     parsed.host,
     parsed.port,
     (err, stream) => {
+      clearTimeout(timeout)
       if (err) { socket.end(socksConnectReply(SOCKS_REPLY.connectionRefused)); return }
       socket.write(socksConnectReply(SOCKS_REPLY.success))
       pipeBoth(socket, stream)
     },
   )
 }
🤖 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/main/ipc/tunnels.ts` around lines 139 - 172, Add a timeout guard around
the forwardOut call in handleSocksConnect: start a timer before invoking
entry.conn.client.forwardOut, clear it when the callback runs, and on expiry
close the local socket and return a SOCKS connection-refused reply. Ensure
cleanup is safe if the callback arrives after timeout, preventing duplicate
replies or pipe setup.
src/renderer/src/components/SFTP/SftpBrowser.tsx (1)

436-476: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider moving DIFF_BG and DIFF_DOT color constants to lib/colors.ts.

These new constants hardcode hex colors (#10B981, #8B5CF6, #F59E0B) which violates the guideline: "Never hardcode hex colors outside lib/colors.ts." The same colors appear inline elsewhere in the file, so centralizing them is a step in the right direction, but they should ultimately live in lib/colors.ts.

As per coding guidelines: src/renderer/**/*.{tsx,css}: Use CSS custom properties (var(--nox-*)) for theme colors. Never hardcode hex colors outside lib/colors.ts.

♻️ Suggested refactor

Move the constants to lib/colors.ts and import them:

-const DIFF_BG: Record<string, string> = {
-  'local-only': 'rgba(16,185,129,0.06)', 'remote-only': 'rgba(139,92,246,0.06)', different: 'rgba(245,158,11,0.06)',
-}
-const DIFF_DOT: Record<string, string> = {
-  'local-only': '`#10B981`', 'remote-only': '`#8B5CF6`', different: '`#F59E0B`',
-}
+import { DIFF_BG, DIFF_DOT } from '../../lib/colors'

Then export them from lib/colors.ts alongside existing color definitions.

🤖 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/renderer/src/components/SFTP/SftpBrowser.tsx` around lines 436 - 476,
Move the DIFF_BG and DIFF_DOT color definitions out of SftpBrowser.tsx into
lib/colors.ts, export them there, and import them in SftpBrowser.tsx. Replace
the remaining inline diff-related hex colors in FileRow with the centralized
color constants or theme CSS variables, preserving the existing visual behavior.

Source: Coding guidelines

src/renderer/src/components/Runner/RunnerView.tsx (1)

34-49: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid calling setRunning inside the setResults updater.

State updater functions should be pure. Calling setRunning inside the setResults callback is a side effect that violates React's purity contract — in Strict Mode, the updater is double-invoked, so setRunning fires twice (harmless here but fragile). Extract the running computation into a useEffect that watches results.

♻️ Proposed refactor
 const applyDone = (sessionId: string, exitCode: number | null, error: string | null) => {
   setResults(prev => {
     const next = new Map(prev)
     const r = next.get(sessionId)
     if (r) {
       next.set(sessionId, {
         ...r,
         state: error || exitCode !== 0 ? 'failed' : 'done',
         exitCode,
         error,
       })
     }
     return next
   })
-  setRunning([...next.values()].some(v => v.state === 'running'))
 }

+// Derive `running` from `results` instead of mutating it inside an updater.
+useEffect(() => {
+  setRunning([...results.values()].some(v => v.state === 'running'))
+}, [results])
🤖 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/renderer/src/components/Runner/RunnerView.tsx` around lines 34 - 49, Move
the setRunning call out of the setResults updater in applyDone. Add a useEffect
that watches results and derives whether any entry remains in the running state,
then updates running accordingly; keep the setResults updater pure by only
cloning, updating, and returning the map.
src/renderer/src/components/ConnectionManager/ConnectionManager.tsx (1)

11-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace [k: string]: any in TypeIcon props with a proper SVG props type.

The [k: string]: any index signature violates the coding guideline: "No any in function signatures." Use React.SVGProps<SVGSVGElement> (or LucideProps from lucide-react if available in this version) to type the spread props.

As per coding guidelines: src/**/*.{ts,tsx}: No any in function signatures. Use unknown and narrow, or define a proper type.

♻️ Proposed fix
-function TypeIcon({ type, ...props }: Readonly<{ type?: string; [k: string]: any }>) {
+function TypeIcon({ type, ...props }: Readonly<{ type?: string } & React.SVGProps<SVGSVGElement>>) {
🤖 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/renderer/src/components/ConnectionManager/ConnectionManager.tsx` around
lines 11 - 27, Replace the any-based index signature in TypeIcon with a proper
SVG icon props type, using React.SVGProps<SVGSVGElement> or the available
LucideProps type. Preserve the optional type property and ensure the spread
props are accepted by all rendered icons without any in the function signature.

Source: Coding guidelines

🤖 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/main/ipc/docker.ts`:
- Around line 63-82: Prevent duplicate docker:logEnd notifications in
attachLogStream by introducing a settled flag or equivalent one-shot
finalization guard shared by the close and error handlers. Only the first
terminal event should delete the stream and send docker:logEnd, preserving the
error message when error occurs before close.

In `@src/main/ipc/tunnels.ts`:
- Line 244: Update disposeAllTunnels to isolate cleanup failures by wrapping
each stopTunnel(id) call in its own try/catch, allowing iteration over
active.keys() to continue when one tunnel fails; preserve or report the caught
error appropriately.

In `@src/renderer/src/components/Database/DatabaseExplorer.tsx`:
- Around line 248-251: Replace the raw SQL construction in the edit handler with
a parameterized database update API: extend the IPC and database-layer methods
behind window.api.database.query to accept bound values, and use placeholders
for newVal and pkVal. Ensure table and column identifiers are escaped through
the database driver or a dedicated identifier-quoting helper rather than
interpolation, then update the renderer call accordingly.

In `@src/renderer/src/components/Docker/DockerDashboard.tsx`:
- Around line 262-273: Replace the hardcoded `#F59E0B` value in
ContainerTableRow’s stateColor initialization with the appropriate --nox-* CSS
custom property, keeping the existing running and exited state colors unchanged.

In `@src/renderer/src/components/K8s/ResourceDetailModal.tsx`:
- Around line 13-28: colorize must HTML-escape the entire raw JSON string before
applying token highlighting, so unmatched resource content cannot reach
dangerouslySetInnerHTML as markup. Update colorize and preserve token
matching/color spans against the escaped text, including escaping &, <, >, ",
and apostrophes as appropriate; ensure the related usage in ResourceDetailModal
renders only the escaped, colorized output.

In `@src/renderer/src/components/TabBar/TabBar.tsx`:
- Around line 142-160: Add explicit VIEW_ICONS mappings for the 'tunnels' and
'runner' tab views in TabBar.tsx, selecting suitable icons and active colors
consistent with the existing entries so tabIcon does not fall back to Terminal.

In `@src/renderer/src/components/Terminal/TerminalView.tsx`:
- Around line 621-623: Update readKeyFile to catch the error with a named
variable and explicitly handle it, preserving diagnostic context by logging or
otherwise reporting the underlying read failure before returning undefined; do
not use a bare catch block.

---

Outside diff comments:
In `@src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx`:
- Around line 137-146: Update getDefaultPort in AddConnectionModal so the
database case returns 3306 for both mysql and mariadb, while retaining 5432 for
other database types.

In `@src/renderer/src/components/Settings/Settings.tsx`:
- Around line 1196-1202: Update ClearCredentialsModal.handleConfirm to catch
failures from onConfirm, reset clearing to false in a finally block so the modal
remains usable, and surface the caught error through the renderer’s notification
system or an inline error state. Preserve the successful confirmation flow while
allowing retry or dismissal after failure.
- Around line 1017-1047: Unify PIN digit handling so keyboard and button input
use the same submission timing. In VerifyPinInput, route numeric keyboard events
through pressKey instead of duplicating digit collection and immediate
submission logic, while retaining Backspace handling separately.

---

Nitpick comments:
In `@src/main/ipc/tunnels.ts`:
- Around line 139-172: Add a timeout guard around the forwardOut call in
handleSocksConnect: start a timer before invoking entry.conn.client.forwardOut,
clear it when the callback runs, and on expiry close the local socket and return
a SOCKS connection-refused reply. Ensure cleanup is safe if the callback arrives
after timeout, preventing duplicate replies or pipe setup.

In `@src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx`:
- Around line 317-363: The new save-path signatures use any, removing type
safety across session creation and extracted form components. Define explicit
SessionData and FormState types based on the supported connection fields, then
apply them to k8sSessionData, sessionData, persistSession, and the form props
for PasswordInput, SshFields, DatabaseFields, K8sContextForm, and ConfigForm;
use appropriate narrowing or unknown where needed instead of any.

In `@src/renderer/src/components/ConnectionManager/ConnectionManager.tsx`:
- Around line 11-27: Replace the any-based index signature in TypeIcon with a
proper SVG icon props type, using React.SVGProps<SVGSVGElement> or the available
LucideProps type. Preserve the optional type property and ensure the spread
props are accepted by all rendered icons without any in the function signature.

In `@src/renderer/src/components/Database/DatabaseExplorer.tsx`:
- Around line 530-654: Replace any in the function signatures of ResultCell,
RowDetailPanel, SmartCell, JsonCell, and tryParseJsonCell with unknown,
including row/value/parsed parameters and return types as appropriate. Add
explicit narrowing for property access, object checks, JSON parsing,
Object.keys, and rendering so dynamic database values remain type-safe without
any.

In `@src/renderer/src/components/Runner/RunnerView.tsx`:
- Around line 34-49: Move the setRunning call out of the setResults updater in
applyDone. Add a useEffect that watches results and derives whether any entry
remains in the running state, then updates running accordingly; keep the
setResults updater pure by only cloning, updating, and returning the map.

In `@src/renderer/src/components/SFTP/SftpBrowser.tsx`:
- Around line 436-476: Move the DIFF_BG and DIFF_DOT color definitions out of
SftpBrowser.tsx into lib/colors.ts, export them there, and import them in
SftpBrowser.tsx. Replace the remaining inline diff-related hex colors in FileRow
with the centralized color constants or theme CSS variables, preserving the
existing visual behavior.
🪄 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: 169b2a7c-6a0b-4427-a0d3-b9f1137923f7

📥 Commits

Reviewing files that changed from the base of the PR and between aa99112 and 934809c.

📒 Files selected for processing (58)
  • native/rdp-spike/sidecar.c
  • src/main/index.ts
  • src/main/ipc/__tests__/keychain.test.ts
  • src/main/ipc/__tests__/security.test.ts
  • src/main/ipc/__tests__/socks.test.ts
  • src/main/ipc/database.ts
  • src/main/ipc/docker.ts
  • src/main/ipc/k8s.ts
  • src/main/ipc/keychain.ts
  • src/main/ipc/localTerminal.ts
  • src/main/ipc/localfs.ts
  • src/main/ipc/metrics.ts
  • src/main/ipc/rdp.ts
  • src/main/ipc/redis.ts
  • src/main/ipc/runner.ts
  • src/main/ipc/security.ts
  • src/main/ipc/sessionTransfer.ts
  • src/main/ipc/sessions.ts
  • src/main/ipc/sftp.ts
  • src/main/ipc/ssh.ts
  • src/main/ipc/sshClients.ts
  • src/main/ipc/sshConfig.ts
  • src/main/ipc/tunnels.ts
  • src/renderer/src/App.tsx
  • src/renderer/src/components/CommandPalette/CommandPalette.tsx
  • src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx
  • src/renderer/src/components/ConnectionManager/ConnectionManager.tsx
  • src/renderer/src/components/Dashboard/Dashboard.tsx
  • src/renderer/src/components/Dashboard/ServerViews.tsx
  • src/renderer/src/components/Database/DatabaseExplorer.tsx
  • src/renderer/src/components/Docker/DockerDashboard.tsx
  • src/renderer/src/components/Docker/DockerLogsModal.tsx
  • src/renderer/src/components/Editor/EditorTab.tsx
  • src/renderer/src/components/K8s/K8sDashboard.tsx
  • src/renderer/src/components/K8s/ResourceDetailModal.tsx
  • src/renderer/src/components/K8sIcon.tsx
  • src/renderer/src/components/MainContent.tsx
  • src/renderer/src/components/Notifications/NotificationHost.tsx
  • src/renderer/src/components/RDP/RdpView.tsx
  • src/renderer/src/components/Redis/RedisExplorer.tsx
  • src/renderer/src/components/Runner/RunnerView.tsx
  • src/renderer/src/components/SFTP/FilesDrawer.tsx
  • src/renderer/src/components/SFTP/SftpBrowser.tsx
  • src/renderer/src/components/ServerContextMenu.tsx
  • src/renderer/src/components/Settings/Settings.tsx
  • src/renderer/src/components/Sidebar/Sidebar.tsx
  • src/renderer/src/components/StatusBar/StatusBar.tsx
  • src/renderer/src/components/TabBar/TabBar.tsx
  • src/renderer/src/components/Terminal/DisconnectedOverlay.tsx
  • src/renderer/src/components/Terminal/HostHeader.tsx
  • src/renderer/src/components/Terminal/SnippetRunner.tsx
  • src/renderer/src/components/Terminal/TerminalSearchBar.tsx
  • src/renderer/src/components/Terminal/TerminalView.tsx
  • src/renderer/src/components/Tunnels/TunnelsView.tsx
  • src/renderer/src/components/UnlockScreen.tsx
  • src/renderer/src/lib/colors.ts
  • src/renderer/src/lib/format.ts
  • src/renderer/src/store/index.ts

Comment thread src/main/ipc/docker.ts
Comment thread src/main/ipc/tunnels.ts Outdated
Comment thread src/renderer/src/components/Database/DatabaseExplorer.tsx Outdated
Comment thread src/renderer/src/components/Docker/DockerDashboard.tsx Outdated
Comment thread src/renderer/src/components/K8s/ResourceDetailModal.tsx Outdated
Comment thread src/renderer/src/components/TabBar/TabBar.tsx
Comment thread src/renderer/src/components/Terminal/TerminalView.tsx
…components

- Implement tests for HostHeader, SnippetRunner, TerminalSearchBar, TerminalView, and TunnelsView components to ensure proper rendering and functionality.
- Enhance MainContent tests to verify view routing and error boundaries.
- Introduce UnlockScreen tests for PIN mode functionality.
- Add color and format utility tests for consistent behavior.
- Extend Zustand store tests to cover session type to tab view mapping.
- Update tsconfig and vitest configuration for improved JSX support and coverage reporting.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploying noxed with  Cloudflare Pages  Cloudflare Pages

Latest commit: a4b048e
Status: ✅  Deploy successful!
Preview URL: https://6f725632.noxed.pages.dev
Branch Preview URL: https://fix-sonarqube-rd-1.noxed.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (10)
src/renderer/src/components/CommandPalette/CommandPalette.tsx (1)

196-199: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant Escape handling may call onClose twice.

The overlay-level onKeyDown (line 197) and the window-level keydown listener (line 166) both handle Escape. When Escape is pressed, both fire, calling onClose() twice. If onClose is idempotent this is harmless, but the overlay onKeyDown is redundant since the window listener already covers Escape.

♻️ Proposed fix: remove redundant overlay onKeyDown
     <div
       className="fixed inset-0 z-50 flex items-start justify-center pt-[16vh] bg-black/50 backdrop-blur-sm animate-fade-in"
       onClick={(e) => { if (e.target === e.currentTarget) onClose() }}
-      onKeyDown={(e) => { if (e.key === 'Escape') onClose() }}
     >
🤖 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/renderer/src/components/CommandPalette/CommandPalette.tsx` around lines
196 - 199, Remove the redundant Escape key handler from the overlay element’s
onKeyDown prop in CommandPalette, leaving the window-level keydown listener
responsible for Escape handling; retain the overlay onClick behavior for closing
when clicking the backdrop.
src/renderer/src/components/ConnectionManager/__tests__/AddConnectionModal.test.tsx (1)

129-129: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Avoid any in function type annotation.

Per coding guidelines, any should not be used in function signatures in src/**/*.{ts,tsx} files. Use unknown or a concrete type instead.

♻️ Proposed fix
-    let resolveCreate!: (v: any) => void
+    let resolveCreate!: (v: unknown) => 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/renderer/src/components/ConnectionManager/__tests__/AddConnectionModal.test.tsx`
at line 129, Replace the any parameter in the resolveCreate function declaration
within the AddConnectionModal test with unknown or the concrete value type
expected by the mocked create operation, and update related usage if necessary
to preserve type safety.

Source: Coding guidelines

src/renderer/src/components/Database/__tests__/DatabaseExplorer.test.tsx (1)

30-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace Record<string, any> in setup and renderConnected function signatures.

Both setup (line 30) and renderConnected (line 56) use Record<string, any> for their override parameters, violating the guideline prohibiting any in function signatures. Use Record<string, unknown> or define proper override types for the session and database API mocks.

As per coding guidelines: "No any in function signatures. Use unknown and narrow, or define a proper type."

♻️ Proposed fix
-function setup(sessionOverrides: Record<string, any> = {}, dbOverrides: Record<string, any> = {}) {
+function setup(sessionOverrides: Record<string, unknown> = {}, dbOverrides: Record<string, unknown> = {}) {
   const session = makeSession({
     type: 'database',
     dbType: 'postgresql',
     databaseName: 'appdb',
     host: 'db.example.com',
     port: 5432,
     username: 'admin',
     sslMode: 'disable',
-    ...sessionOverrides,
+    ...(sessionOverrides as Partial<Session>),
   } as any)
-async function renderConnected(sessionOverrides: Record<string, any> = {}, dbOverrides: Record<string, any> = {}) {
+async function renderConnected(sessionOverrides: Record<string, unknown> = {}, dbOverrides: Record<string, unknown> = {}) {

Also applies to: 56-57

🤖 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/renderer/src/components/Database/__tests__/DatabaseExplorer.test.tsx`
around lines 30 - 31, Replace the Record<string, any> parameter types in setup
and renderConnected with Record<string, unknown>, or define dedicated session
and database override types; update any affected mock construction or property
access to narrow unknown values appropriately.

Source: Coding guidelines

src/renderer/src/components/RDP/__tests__/RdpView.test.tsx (1)

26-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace any[] in the connectImpl function signature.

The connectImpl parameter uses (...args: any[]) => Promise<string>, which violates the guideline prohibiting any in function signatures. Since the mock implementation only uses the return value, unknown[] or a more specific tuple type would suffice.

As per coding guidelines: "No any in function signatures. Use unknown and narrow, or define a proper type."

♻️ Proposed fix
-  connectImpl?: (...args: any[]) => Promise<string>
+  connectImpl?: (...args: unknown[]) => Promise<string>
🤖 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/renderer/src/components/RDP/__tests__/RdpView.test.tsx` around lines 26 -
30, Replace the any[] parameter in setup’s connectImpl function type with
unknown[] or an appropriate specific tuple type, preserving the Promise<string>
return type and updating any mock invocation handling as needed.

Source: Coding guidelines

src/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx (1)

79-84: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace Record<string, any> in the setup function signatures.

Both k8sOverrides and props parameters use Record<string, any>, violating the guideline prohibiting any in function signatures. Use Record<string, unknown> or define proper override types.

As per coding guidelines: "No any in function signatures. Use unknown and narrow, or define a proper type."

♻️ Proposed fix
-function setup(k8sOverrides: Record<string, any> = {}, props: Record<string, any> = {}) {
+function setup(k8sOverrides: Record<string, unknown> = {}, props: Record<string, unknown> = {}) {
   const api = installWindowApi({ k8s: { ...k8sData(), ...k8sOverrides } })
   seedStore({ sessions: [], tabs: [], activeTabId: null })
-  const utils = render(<K8sDashboard context="test-ctx" {...props} />)
+  const utils = render(<K8sDashboard context="test-ctx" {...(props as K8sDashboardProps)} />)
   return { api, ...utils }
 }
🤖 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/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx` around lines
79 - 84, Replace the any-based parameter types in the setup function with
Record<string, unknown> or explicit override types for k8sOverrides and props;
update any affected spreads or call sites to narrow values as needed while
preserving setup behavior.

Source: Coding guidelines

src/renderer/src/components/Dashboard/ServerViews.tsx (1)

63-66: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Consider triggering onConnect on keyup for Space key.

Per WAI-ARIA practices, role="button" elements should activate on keyup for the Space key (to allow users to cancel by holding and moving focus away). Using keydown for both Enter and Space is a common shortcut and functionally works, but keyup for Space would be more spec-compliant. This is a minor accessibility refinement, not a blocker.

Also applies to: 217-220

🤖 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/renderer/src/components/Dashboard/ServerViews.tsx` around lines 63 - 66,
Update the button keyboard handling in the relevant ServerViews component: keep
Enter activation on keydown, but handle Space activation on keyup so users can
cancel before release. Adjust the existing onKeyDown handler and add the
corresponding onKeyUp logic while preserving preventDefault and onConnect
behavior.
src/renderer/src/components/Terminal/__tests__/SnippetRunner.test.tsx (1)

78-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid fragile DOM traversal in test selectors.

screen.getByText('Snippets').parentElement!.querySelectorAll('button')[0]! is brittle and will break on any surrounding DOM change. Prefer a role-based or title-based selector (e.g., screen.getByRole('button', { name: /add/i }) or screen.getByTitle('Add')) to target the "add snippet" button deterministically.

🤖 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/renderer/src/components/Terminal/__tests__/SnippetRunner.test.tsx` at
line 78, Replace the fragile parentElement/querySelectorAll traversal in the
SnippetRunner test with a deterministic accessible selector for the add-snippet
control, such as screen.getByRole('button', { name: /add/i }) or
screen.getByTitle('Add'), then click that element.
src/main/ipc/__tests__/docker.test.ts (1)

31-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace any with unknown in the Handler type to comply with coding guidelines.

The coding guidelines for src/**/*.{ts,tsx} state: "No any in function signatures. Use unknown and narrow, or define a proper type." The Handler type uses any[] for args and any for the return type. All call sites already cast return values with as, which works equally well with unknown, so no additional changes are needed at call sites.

♻️ Proposed refactor
 // eslint-disable-next-line `@typescript-eslint/no-explicit-any`
-type Handler = (...args: any[]) => any
+type Handler = (...args: unknown[]) => unknown
🤖 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/main/ipc/__tests__/docker.test.ts` around lines 31 - 32, Replace the
explicit any types in the Handler function type with unknown for both the
variadic arguments and return value, and remove the eslint suppression since it
is no longer needed.

Source: Coding guidelines

src/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx (1)

169-172: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider role="checkbox" with aria-checked instead of role="button".

The element toggles a selection state (checked/unchecked). role="checkbox" with aria-checked={checked} more accurately conveys the toggle semantics to screen reader users than role="button", which implies an action trigger.

[accessibility_and_i18n]

♿ Proposed refactor
                 className="w-4 h-4 rounded flex items-center justify-center flex-shrink-0"
                 style={{
                   border: `2px solid ${checked ? '`#3B5CCC`' : 'var(--nox-border)'}`,
                   background: checked ? '`#3B5CCC`' : 'transparent',
                 }}
-                role="button"
+                role="checkbox"
+                aria-checked={checked}
                 tabIndex={0}
                 onClick={() => toggle(h.alias)}
                 onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(h.alias) } }}
🤖 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/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx`
around lines 169 - 172, Update the selectable element’s accessibility semantics
in the SSH config list: replace role="button" with role="checkbox" and bind
aria-checked to its checked/selection state, while preserving the existing
keyboard and click handling in the toggle callback.
src/renderer/src/components/Settings/__tests__/Settings.test.tsx (1)

232-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test enshrines a known stale-closure bug instead of testing correct behavior.

The comment at lines 232-235 documents that SetPinInput has a stale closure causing false PIN mismatches, and the test asserts api.auth.setup is never called. This test will fail if the bug is fixed, creating a disincentive for the fix. Consider either fixing the stale closure in SetPinInput and updating the test to assert successful setup, or adding a // TODO(issue) reference to track the fix.

Would you like me to investigate the SetPinInput component and propose a fix for the stale closure?

🤖 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/renderer/src/components/Settings/__tests__/Settings.test.tsx` around
lines 232 - 241, Fix the stale-closure behavior in SetPinInput so PIN
confirmation reads the latest committed digits, then update the test to assert
matching PINs successfully call api.auth.setup and advance past PIN entry
instead of expecting “PINs do not match”; avoid preserving the known-bug
assertion.
🤖 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/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx`:
- Around line 185-186: Replace the fragile parentElement/querySelectorAll chain
in the K8sDashboard test with a semantic selector targeting the plus control,
preferably screen.getByRole('button', { name: /+/ }); if no accessible name
exists, add a stable data-testid to the plus button component and query it
directly.

In `@src/renderer/src/components/K8s/ResourceDetailModal.tsx`:
- Around line 50-64: Escape all untrusted text before constructing HTML in
colorize: HTML-escape token.text and unmatched raw[i] values, while preserving
only the generated span markup and safely handling token.color for the style
attribute. Verify the resulting output used by dangerouslySetInnerHTML cannot
interpret raw JSON characters such as <, >, &, quotes, or apostrophes as markup.

In `@src/renderer/src/components/Runner/__tests__/RunnerView.test.tsx`:
- Line 44: Replace the any type in the startRun function’s api parameter with
the existing WindowApiMock type, importing it through the test harness if
necessary, and ensure all startRun call sites remain type-compatible.

In `@src/renderer/src/components/Terminal/__tests__/TerminalView.test.tsx`:
- Line 48: Replace the any type in the setup function’s apiOverrides parameter
with Record<string, unknown>; add explicit type narrowing or a suitable specific
type wherever the overrides are consumed.

---

Nitpick comments:
In `@src/main/ipc/__tests__/docker.test.ts`:
- Around line 31-32: Replace the explicit any types in the Handler function type
with unknown for both the variadic arguments and return value, and remove the
eslint suppression since it is no longer needed.

In `@src/renderer/src/components/CommandPalette/CommandPalette.tsx`:
- Around line 196-199: Remove the redundant Escape key handler from the overlay
element’s onKeyDown prop in CommandPalette, leaving the window-level keydown
listener responsible for Escape handling; retain the overlay onClick behavior
for closing when clicking the backdrop.

In
`@src/renderer/src/components/ConnectionManager/__tests__/AddConnectionModal.test.tsx`:
- Line 129: Replace the any parameter in the resolveCreate function declaration
within the AddConnectionModal test with unknown or the concrete value type
expected by the mocked create operation, and update related usage if necessary
to preserve type safety.

In `@src/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx`:
- Around line 169-172: Update the selectable element’s accessibility semantics
in the SSH config list: replace role="button" with role="checkbox" and bind
aria-checked to its checked/selection state, while preserving the existing
keyboard and click handling in the toggle callback.

In `@src/renderer/src/components/Dashboard/ServerViews.tsx`:
- Around line 63-66: Update the button keyboard handling in the relevant
ServerViews component: keep Enter activation on keydown, but handle Space
activation on keyup so users can cancel before release. Adjust the existing
onKeyDown handler and add the corresponding onKeyUp logic while preserving
preventDefault and onConnect behavior.

In `@src/renderer/src/components/Database/__tests__/DatabaseExplorer.test.tsx`:
- Around line 30-31: Replace the Record<string, any> parameter types in setup
and renderConnected with Record<string, unknown>, or define dedicated session
and database override types; update any affected mock construction or property
access to narrow unknown values appropriately.

In `@src/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx`:
- Around line 79-84: Replace the any-based parameter types in the setup function
with Record<string, unknown> or explicit override types for k8sOverrides and
props; update any affected spreads or call sites to narrow values as needed
while preserving setup behavior.

In `@src/renderer/src/components/RDP/__tests__/RdpView.test.tsx`:
- Around line 26-30: Replace the any[] parameter in setup’s connectImpl function
type with unknown[] or an appropriate specific tuple type, preserving the
Promise<string> return type and updating any mock invocation handling as needed.

In `@src/renderer/src/components/Settings/__tests__/Settings.test.tsx`:
- Around line 232-241: Fix the stale-closure behavior in SetPinInput so PIN
confirmation reads the latest committed digits, then update the test to assert
matching PINs successfully call api.auth.setup and advance past PIN entry
instead of expecting “PINs do not match”; avoid preserving the known-bug
assertion.

In `@src/renderer/src/components/Terminal/__tests__/SnippetRunner.test.tsx`:
- Line 78: Replace the fragile parentElement/querySelectorAll traversal in the
SnippetRunner test with a deterministic accessible selector for the add-snippet
control, such as screen.getByRole('button', { name: /add/i }) or
screen.getByTitle('Add'), then click that element.
🪄 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: 5dd10266-5ca9-4aee-ba2f-96607069e6a1

📥 Commits

Reviewing files that changed from the base of the PR and between 934809c and 7ac15c4.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (61)
  • .github/workflows/ci.yml
  • .gitignore
  • package.json
  • sonar-project.properties
  • src/main/ipc/__tests__/docker.test.ts
  • src/main/ipc/__tests__/k8s.test.ts
  • src/main/ipc/__tests__/metrics.test.ts
  • src/main/ipc/__tests__/rdp.test.ts
  • src/main/ipc/__tests__/sessionTransfer.test.ts
  • src/main/ipc/__tests__/sftp.test.ts
  • src/main/ipc/__tests__/ssh.handlers.test.ts
  • src/main/ipc/__tests__/sshConfig.test.ts
  • src/main/ipc/__tests__/tunnels.test.ts
  • src/main/ipc/rdp.ts
  • src/renderer/src/__tests__/harness.tsx
  • src/renderer/src/components/CommandPalette/CommandPalette.tsx
  • src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx
  • src/renderer/src/components/ConnectionManager/ConnectionManager.tsx
  • src/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/AddConnectionModal.test.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/ConnectionManager.test.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/ImportSshConfigModal.test.tsx
  • src/renderer/src/components/Dashboard/ServerViews.tsx
  • src/renderer/src/components/Dashboard/__tests__/Dashboard.test.tsx
  • src/renderer/src/components/Dashboard/__tests__/ServerViews.test.tsx
  • src/renderer/src/components/Database/DatabaseExplorer.tsx
  • src/renderer/src/components/Database/__tests__/DatabaseExplorer.test.tsx
  • src/renderer/src/components/Docker/__tests__/DockerDashboard.test.tsx
  • src/renderer/src/components/Editor/__tests__/EditorTab.test.tsx
  • src/renderer/src/components/K8s/ResourceDetailModal.tsx
  • src/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx
  • src/renderer/src/components/K8s/__tests__/ResourceDetailModal.test.tsx
  • src/renderer/src/components/RDP/RdpView.tsx
  • src/renderer/src/components/RDP/__tests__/RdpView.test.tsx
  • src/renderer/src/components/Redis/RedisExplorer.tsx
  • src/renderer/src/components/Redis/__tests__/RedisExplorer.test.tsx
  • src/renderer/src/components/Runner/RunnerView.tsx
  • src/renderer/src/components/Runner/__tests__/RunnerView.test.tsx
  • src/renderer/src/components/SFTP/SftpBrowser.tsx
  • src/renderer/src/components/SFTP/__tests__/FilesDrawer.test.tsx
  • src/renderer/src/components/SFTP/__tests__/SftpBrowser.test.tsx
  • src/renderer/src/components/Settings/Settings.tsx
  • src/renderer/src/components/Settings/__tests__/Settings.test.tsx
  • src/renderer/src/components/Sidebar/Sidebar.tsx
  • src/renderer/src/components/Sidebar/__tests__/Sidebar.test.tsx
  • src/renderer/src/components/StatusBar/__tests__/StatusBar.test.tsx
  • src/renderer/src/components/TabBar/TabBar.tsx
  • src/renderer/src/components/TabBar/__tests__/TabBar.test.tsx
  • src/renderer/src/components/Terminal/__tests__/DisconnectedOverlay.test.tsx
  • src/renderer/src/components/Terminal/__tests__/HostHeader.test.tsx
  • src/renderer/src/components/Terminal/__tests__/SnippetRunner.test.tsx
  • src/renderer/src/components/Terminal/__tests__/TerminalSearchBar.test.tsx
  • src/renderer/src/components/Terminal/__tests__/TerminalView.test.tsx
  • src/renderer/src/components/Tunnels/__tests__/TunnelsView.test.tsx
  • src/renderer/src/components/__tests__/MainContent.test.tsx
  • src/renderer/src/components/__tests__/UnlockScreen.test.tsx
  • src/renderer/src/lib/__tests__/colors.test.ts
  • src/renderer/src/lib/__tests__/format.test.ts
  • src/renderer/src/store/__tests__/store.test.ts
  • tsconfig.web.json
  • vitest.config.ts
✅ Files skipped from review due to trivial changes (2)
  • sonar-project.properties
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/renderer/src/components/ConnectionManager/ConnectionManager.tsx
  • src/renderer/src/components/TabBar/TabBar.tsx
  • src/renderer/src/components/Runner/RunnerView.tsx
  • src/renderer/src/components/Redis/RedisExplorer.tsx
  • src/renderer/src/components/SFTP/SftpBrowser.tsx
  • src/renderer/src/components/RDP/RdpView.tsx
  • src/main/ipc/rdp.ts
  • src/renderer/src/components/Settings/Settings.tsx
  • src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx
  • src/renderer/src/components/Database/DatabaseExplorer.tsx

Comment thread src/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx Outdated
Comment thread src/renderer/src/components/K8s/ResourceDetailModal.tsx
Comment thread src/renderer/src/components/Runner/__tests__/RunnerView.test.tsx Outdated
Comment thread src/renderer/src/components/Terminal/__tests__/TerminalView.test.tsx Outdated
…ndling

- Updated various test cases to use `expect(...).toBeTruthy()` for better readability.
- Changed button roles in the DatabaseExplorer, RedisExplorer, and Sidebar components for improved accessibility.
- Enhanced error handling in the TerminalView for reading key files.
- Refactored the ChangeAuthModal to handle confirmation PIN submission more reliably.
- Improved the handling of keyboard events in the RunnerView and Sidebar components.
- Added HTML escaping in the ResourceDetailModal to prevent XSS vulnerabilities.
- Updated the TabBar to include new icons for tunnels and runner views.
- Refactored the KeyListPane in RedisExplorer to use buttons for key selection.
- Improved the handling of session connections in the Sidebar and Runner components.
@Meanski

Meanski commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai - we good to merge now?

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 3 --repo Meanski/noxed --json state,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,title,isDraft
echo "---REVIEWS---"
gh pr view 3 --repo Meanski/noxed --json reviews --jq '.reviews[] | {author: .author.login, state: .state}'
echo "---COMMENTS (coderabbitai)---"
gh api repos/Meanski/noxed/pulls/3/comments --jq '.[] | select(.user.login=="coderabbitai") | {id, path, in_reply_to_id: .in_reply_to_id, resolved: false}' | head -100

Length of output: 1818


@Meanski: Yes, looks good from my end:

  • Merge state: CLEAN / MERGEABLE, no conflicts.
  • CI checks: all green — "Test and SonarQube", "Cloudflare Pages", and "CodeRabbit / Review" all completed successfully.
  • Outstanding review comments: none open from me on this PR.

One thing to note: reviewDecision is empty, meaning no one has formally approved the PR yet on GitHub (my own reviews were "commented" only, not approvals). If your branch protection requires an approval before merging, you'll want to get a human sign-off, or you can ask me to @coderabbitai approve if that satisfies your workflow.

Otherwise, from a code/CI health perspective, this is ready to merge whenever you are.

(‐^ᴥ^‐)

@Meanski

Meanski commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai - based on your findings and the two commits in this PR, are there any outstanding issues?

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 3 --repo Meanski/noxed --json commits --jq '.commits[] | {oid: .oid, messageHeadline: .messageHeadline}'
echo "---PR COMMENTS---"
gh api repos/Meanski/noxed/pulls/3/comments --jq '.[] | {id, path, line, body: (.body[0:200])}'
echo "---ISSUE COMMENTS---"
gh api repos/Meanski/noxed/issues/3/comments --jq '.[] | {id, body: (.body[0:200])}'
echo "---REVIEW THREADS RESOLVED STATUS---"
gh api graphql -f query='
query {
  repository(owner: "Meanski", name: "noxed") {
    pullRequest(number: 3) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          comments(first: 1) { nodes { path body } }
        }
      }
    }
  }
}'

Length of output: 32196


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "F59E0B|stateColor" src/renderer/src/components/Docker/DockerDashboard.tsx

Length of output: 611


Confirmed — one item is still outstanding. Here's the status based on the two new commits (934809c, 7ac15c4) plus the fix commit 2b102e2:

Resolved (9/10 threads): duplicate docker:logEnd guard, disposeAllTunnels try/catch isolation, DatabaseExplorer parameterized SQL, XSS-safe colorize() in ResourceDetailModal, bare catch {} in TerminalView's readKeyFile, fragile DOM selector in K8sDashboard test, and any → proper types in RunnerView/TerminalView tests.

Still open (1/10): src/renderer/src/components/Docker/DockerDashboard.tsx, Line 271 — stateColor is still hardcoded to '#F59E0B' (and Line 272 to '#10B981'), while Line 273 already uses var(--nox-text-3). Per your coding guidelines, hex colors shouldn't be hardcoded outside lib/colors.ts. Suggested fix:

- let stateColor = '`#F59E0B`'
- if (isRunning) stateColor = '`#10B981`'
+ let stateColor = 'var(--nox-warning)'
+ if (isRunning) stateColor = 'var(--nox-success)'
  else if (container.State === 'exited') stateColor = 'var(--nox-text-3)'

(Adjust the CSS variable names to whatever your lib/colors.ts/theme actually defines for warning/success.)

Everything else looks clean — CI is green and merge state is still CLEAN. This remaining item is a minor/quick-win style nit, not a blocker, so it's your call whether to fix it now or merge and follow up.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/renderer/src/components/Runner/RunnerView.tsx (1)

50-52: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider deriving running with useMemo instead of useEffect + setRunning.

The current useEffect calls setRunning whenever results changes, causing an extra render cycle. Since running is purely derived from results, computing it during render with useMemo eliminates the extra render and makes the direct setRunning calls in run() (line 87), the error handler (line 91), and cancel() (line 107) unnecessary.

♻️ Proposed refactor
- const [running, setRunning] = useState(false)
+ const running = useMemo(
+   () => [...results.values()].some(v => v.state === 'running'),
+   [results],
+ )

Then remove the useEffect on lines 50–52 and the direct setRunning calls on lines 87, 91, and 107. The results state already serves as the single source of truth.

🤖 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/renderer/src/components/Runner/RunnerView.tsx` around lines 50 - 52,
Replace the `running` state and `useEffect` in `RunnerView` with a `useMemo`
derived from `results`, checking whether any result is in the `running` state.
Remove the direct `setRunning` calls from `run()`, its error handler, and
`cancel()`, ensuring `results` remains the single source of truth.
🤖 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/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx`:
- Around line 163-174: Replace the hardcoded `#3B5CCC` values in
ImportSshConfigModal’s checked button styles with the centralized color source,
using an existing --nox-primary CSS variable or defining it through
lib/colors.ts if absent. Apply the same update to the corresponding
checked-state styles in ConnectionManager and RunnerView, preserving the current
visual behavior.

In `@src/renderer/src/components/Database/DatabaseExplorer.tsx`:
- Around line 530-535: The row divs rendered by sortedRows.map are not
keyboard-focusable, so their onKeyDown selection handler cannot be reached. Add
tabIndex={0} and an appropriate row-selection role to each row div, preserving
the existing onClick and onKeyDown behavior in the row rendering.

---

Nitpick comments:
In `@src/renderer/src/components/Runner/RunnerView.tsx`:
- Around line 50-52: Replace the `running` state and `useEffect` in `RunnerView`
with a `useMemo` derived from `results`, checking whether any result is in the
`running` state. Remove the direct `setRunning` calls from `run()`, its error
handler, and `cancel()`, ensuring `results` remains the single source of truth.
🪄 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: 9a1fddaa-39b0-46ba-9150-2089b963cf5d

📥 Commits

Reviewing files that changed from the base of the PR and between 7ac15c4 and ce98dc7.

📒 Files selected for processing (36)
  • src/main/ipc/__tests__/database.test.ts
  • src/main/ipc/__tests__/docker.test.ts
  • src/main/ipc/__tests__/rdp.test.ts
  • src/main/ipc/database.ts
  • src/main/ipc/docker.ts
  • src/main/ipc/tunnels.ts
  • src/preload/index.d.ts
  • src/preload/index.ts
  • src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx
  • src/renderer/src/components/ConnectionManager/ConnectionManager.tsx
  • src/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/AddConnectionModal.test.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/ConnectionManager.test.tsx
  • src/renderer/src/components/ConnectionManager/__tests__/ImportSshConfigModal.test.tsx
  • src/renderer/src/components/Dashboard/ServerViews.tsx
  • src/renderer/src/components/Dashboard/__tests__/ServerViews.test.tsx
  • src/renderer/src/components/Database/DatabaseExplorer.tsx
  • src/renderer/src/components/Database/__tests__/DatabaseExplorer.test.tsx
  • src/renderer/src/components/Docker/DockerDashboard.tsx
  • src/renderer/src/components/K8s/ResourceDetailModal.tsx
  • src/renderer/src/components/K8s/__tests__/K8sDashboard.test.tsx
  • src/renderer/src/components/RDP/__tests__/RdpView.test.tsx
  • src/renderer/src/components/Redis/RedisExplorer.tsx
  • src/renderer/src/components/Redis/__tests__/RedisExplorer.test.tsx
  • src/renderer/src/components/Runner/RunnerView.tsx
  • src/renderer/src/components/Runner/__tests__/RunnerView.test.tsx
  • src/renderer/src/components/Settings/Settings.tsx
  • src/renderer/src/components/Settings/__tests__/Settings.test.tsx
  • src/renderer/src/components/Sidebar/Sidebar.tsx
  • src/renderer/src/components/Sidebar/__tests__/Sidebar.test.tsx
  • src/renderer/src/components/TabBar/TabBar.tsx
  • src/renderer/src/components/Terminal/TerminalView.tsx
  • src/renderer/src/components/Terminal/__tests__/SnippetRunner.test.tsx
  • src/renderer/src/components/Terminal/__tests__/TerminalView.test.tsx
  • src/renderer/src/lib/__tests__/colors.test.ts
  • src/renderer/src/lib/colors.ts
🚧 Files skipped from review as they are similar to previous changes (18)
  • src/renderer/src/components/RDP/tests/RdpView.test.tsx
  • src/renderer/src/components/ConnectionManager/tests/ConnectionManager.test.tsx
  • src/main/ipc/tunnels.ts
  • src/renderer/src/lib/tests/colors.test.ts
  • src/renderer/src/components/TabBar/TabBar.tsx
  • src/renderer/src/components/Terminal/tests/TerminalView.test.tsx
  • src/main/ipc/tests/docker.test.ts
  • src/main/ipc/docker.ts
  • src/renderer/src/components/K8s/ResourceDetailModal.tsx
  • src/renderer/src/components/Terminal/tests/SnippetRunner.test.tsx
  • src/renderer/src/components/Redis/RedisExplorer.tsx
  • src/renderer/src/components/ConnectionManager/tests/AddConnectionModal.test.tsx
  • src/renderer/src/components/Terminal/TerminalView.tsx
  • src/renderer/src/components/K8s/tests/K8sDashboard.test.tsx
  • src/renderer/src/components/Settings/Settings.tsx
  • src/main/ipc/tests/rdp.test.ts
  • src/renderer/src/components/ConnectionManager/AddConnectionModal.tsx
  • src/renderer/src/components/Database/tests/DatabaseExplorer.test.tsx

Comment on lines +163 to +174
<button
type="button"
className="w-4 h-4 rounded flex items-center justify-center flex-shrink-0"
style={{
border: `2px solid ${checked ? '#3B5CCC' : 'var(--nox-border)'}`,
background: checked ? '#3B5CCC' : 'transparent',
}}
aria-pressed={checked}
onClick={() => toggle(h.alias)}
>
{checked && <Check className="w-3 h-3 text-white" />}
</div>
</button>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Hardcoded #3B5CCC violates the color centralization guideline.

Lines 167–168 use #3B5CCC directly in inline styles. As per coding guidelines, hex colors should not be hardcoded outside lib/colors.ts — use a CSS custom property (var(--nox-*)) or import from the centralized color module instead.

The same pattern appears in ConnectionManager.tsx (lines 145–146, 175–176) and RunnerView.tsx (lines 146–147).

🎨 Suggested fix
                   style={{
-                    border: `2px solid ${checked ? '`#3B5CCC`' : 'var(--nox-border)'}`,
-                    background: checked ? '`#3B5CCC`' : 'transparent',
+                    border: `2px solid ${checked ? 'var(--nox-primary)' : 'var(--nox-border)'}`,
+                    background: checked ? 'var(--nox-primary)' : 'transparent',
                   }}

If --nox-primary doesn't exist, define #3B5CCC in lib/colors.ts and reference it from there.

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

Suggested change
<button
type="button"
className="w-4 h-4 rounded flex items-center justify-center flex-shrink-0"
style={{
border: `2px solid ${checked ? '#3B5CCC' : 'var(--nox-border)'}`,
background: checked ? '#3B5CCC' : 'transparent',
}}
aria-pressed={checked}
onClick={() => toggle(h.alias)}
>
{checked && <Check className="w-3 h-3 text-white" />}
</div>
</button>
<button
type="button"
className="w-4 h-4 rounded flex items-center justify-center flex-shrink-0"
style={{
border: `2px solid ${checked ? 'var(--nox-primary)' : 'var(--nox-border)'}`,
background: checked ? 'var(--nox-primary)' : 'transparent',
}}
aria-pressed={checked}
onClick={() => toggle(h.alias)}
>
{checked && <Check className="w-3 h-3 text-white" />}
</button>
🤖 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/renderer/src/components/ConnectionManager/ImportSshConfigModal.tsx`
around lines 163 - 174, Replace the hardcoded `#3B5CCC` values in
ImportSshConfigModal’s checked button styles with the centralized color source,
using an existing --nox-primary CSS variable or defining it through
lib/colors.ts if absent. Apply the same update to the corresponding
checked-state styles in ConnectionManager and RunnerView, preserving the current
visual behavior.

Source: Coding guidelines

Comment thread src/renderer/src/components/Database/DatabaseExplorer.tsx Outdated
@Meanski
Meanski merged commit 75c5e3e into main Jul 10, 2026
3 checks 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.

1 participant