Skip to content

feat(windows): platform title bar + PowerShell hooks + WSL integration - #4

Merged
guan4tou2 merged 2 commits into
mainfrom
windows-support-v3
Jul 29, 2026
Merged

feat(windows): platform title bar + PowerShell hooks + WSL integration#4
guan4tou2 merged 2 commits into
mainfrom
windows-support-v3

Conversation

@guan4tou2

@guan4tou2 guan4tou2 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Platform-aware title barhiddenInset on macOS, hidden + titleBarOverlay on Windows so min/max/close controls work. Renderer gets platform via preload for conditional padding and shortcut labels (Ctrl+ vs ).
  • PowerShell shell hook (hooks/shell-hook.ps1) — captures every command via prompt override + Get-History, sends command_start/command_end events to RedLog using background runspaces (never blocks the prompt). Works on PowerShell 5.1+ and pwsh 7+.
  • PowerShell event sender (hooks/redlog-send.ps1) — Send-RedLogEvent function for scripted use, fire-and-forget.
  • WSL hooksredlog-send.sh (auto-resolves Windows %USERPROFILE% token path, probes reachable host) and wsl-redlog-test.sh (full diagnostic: env, token path, networking, round-trip).
  • hooks-manager — registers PowerShell hook with manual install steps; fixes bash availability detection on Windows (WSL/Git Bash).
  • .gitattributes — enforces LF for .sh/.zsh/.bash/.py to prevent broken shebangs on Windows.
  • docs/windows-setup.md — build prerequisites, PowerShell hooks, WSL integration, operational isolation.

Test plan

  • On Windows: app launches with visible min/max/close controls in title bar
  • Title bar buttons and actions panel don't overlap the Windows controls overlay
  • Keyboard shortcuts in dashboard show Ctrl+ instead of
  • PowerShell hook: . hooks/shell-hook.ps1 → run commands → events appear in timeline
  • Send-RedLogEvent from redlog-send.ps1 posts events successfully
  • WSL: wsl-redlog-test.sh passes all checks with mirrored networking
  • On macOS: no regressions — traffic-light buttons, shortcuts, pl-16 padding all preserved
  • Settings panel shows PowerShell hook as available on Windows, unavailable on macOS

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added PowerShell command capture with automatic start, completion, duration, and exit-status events.
    • Added cross-platform shell event helpers, including WSL-to-Windows integration and a WSL integration test.
    • Improved platform-aware UI (title bar presentation and macOS/Windows shortcut key labels).
  • Documentation
    • Added a Windows/WSL setup guide and expanded Windows build guidance in the README.
  • Bug Fixes
    • Improved IP safety classification when using blacklist-only configurations.
  • Tests
    • Expanded IP safety test coverage.
  • Chores
    • Standardized line endings for shell scripts and Python files.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c039177b-cfc2-4325-90be-c7233751059b

📥 Commits

Reviewing files that changed from the base of the PR and between a2e3644 and 0e7d8d7.

📒 Files selected for processing (14)
  • .gitattributes
  • README.md
  • docs/windows-setup.md
  • hooks/redlog-send.ps1
  • hooks/redlog-send.sh
  • hooks/shell-hook.ps1
  • hooks/wsl-redlog-test.sh
  • src/core/hooks-manager.ts
  • src/core/ip-monitor.ts
  • src/main/windows.ts
  • src/preload/index.ts
  • src/renderer/src/App.tsx
  • src/renderer/src/env.d.ts
  • test/ip-monitor.test.ts

📝 Walkthrough

Walkthrough

Windows and WSL setup documentation, shell event hooks, PowerShell capture registration, platform-aware Electron window behavior, operating-system-specific shortcut labels, and blacklist classification behavior were added or updated.

Changes

Windows and WSL shell integration

Layer / File(s) Summary
Event sender helpers
hooks/redlog-send.ps1, hooks/redlog-send.sh
PowerShell and Bash helpers resolve local RedLog credentials and asynchronously post events.
PowerShell capture registration
hooks/shell-hook.ps1, src/core/hooks-manager.ts
PowerShell command history is captured as start/end events, and the hook is registered with manual installation steps.
WSL setup and validation
docs/windows-setup.md, README.md, hooks/wsl-redlog-test.sh, .gitattributes
Windows/WSL setup, networking, credential paths, shell usage, event validation, and LF normalization are documented or configured.

Platform-aware desktop UI

Layer / File(s) Summary
Platform bridge and window chrome
src/main/windows.ts, src/preload/index.ts, src/renderer/src/env.d.ts
The platform is exposed to the renderer, and Electron title bar configuration varies by operating system.
Platform-specific renderer layout
src/renderer/src/App.tsx
Title bar spacing and shortcut labels use macOS or non-macOS modifier conventions.

IP safety classification

Layer / File(s) Summary
Blacklist fallback and coverage
src/core/ip-monitor.ts, test/ip-monitor.test.ts
Blacklist-only configurations classify non-matching addresses as safe, with corresponding test coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PowerShell
  participant shell-hook.ps1
  participant RedLogAPI
  PowerShell->>shell-hook.ps1: Execute command and update history
  shell-hook.ps1->>RedLogAPI: POST command_start
  shell-hook.ps1->>RedLogAPI: POST command_end with duration and exit code
Loading

Possibly related PRs

  • guan4tou2/REDLOG#1: Modifies the same platform-aware window, preload, and renderer paths.
  • guan4tou2/REDLOG#3: Overlaps on platform detection, preload typing, shortcut labels, and WSL integration.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 clearly captures the main Windows platform work: title bar changes, PowerShell hooks, and WSL integration.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch windows-support-v3

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 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 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 `@docs/windows-setup.md`:
- Around line 104-115: The “Networking — mirrored mode” section should present
mirrored networking as recommended rather than required, state that it is
supported only on Windows 11 22H2 or later, and document that Windows 10 or
unavailable mirrored setups should use the existing NAT fallback through
gateway.docker.internal.

In `@hooks/redlog-send.ps1`:
- Around line 52-61: The asynchronous senders in hooks/redlog-send.ps1 lines
52-61 and hooks/shell-hook.ps1 lines 47-56 leak their PowerShell and runspace
resources. Update both implementations, preferably via a shared sender helper,
so completion invokes EndInvoke(), then disposes the PowerShell instance and
runspace while preserving fire-and-forget behavior.

In `@hooks/redlog-send.sh`:
- Around line 61-64: In the WSL gateway fallback block of redlog-send.sh, remove
the local declaration for gw and assign it as a normal variable before the
existing gateway health check. Preserve the current route lookup and curl logic
unchanged.

In `@hooks/shell-hook.ps1`:
- Around line 65-73: Update the prompt function to capture $success from $?
before assigning or executing any other statement, including the $lastExit
assignment. Preserve the existing exitCode calculation so it reports the prior
command’s actual success or failure status.

In `@hooks/wsl-redlog-test.sh`:
- Around line 116-123: Update the final conditional in the WSL-to-RedLog summary
flow so that a nonzero $fail causes the script to exit with a nonzero status
after printing the failure message. Preserve the successful status when $fail is
zero and keep the existing summary output unchanged.

In `@src/core/hooks-manager.ts`:
- Around line 269-278: Update the shell-powershell branch in the hooks-manager
switch to escape hookFile for PowerShell string literals before constructing
either command. Ensure embedded single quotes are escaped and the emitted path
is literal, preventing expansion of dollar signs and backticks in both the
Add-Content and manual sourcing instructions while preserving the existing
labels.

In `@src/renderer/src/App.tsx`:
- Around line 361-363: Define a shared markerShortcut value in the App component
using ⌘⇧M on macOS and Ctrl+Shift+M otherwise, then reuse it for both the marker
shortcut entry in the dashboard shortcut labels and the marker button tooltip.
Remove the tooltip’s hardcoded shortcut while preserving the existing
translations.
🪄 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 Plus

Run ID: 7bf7de58-c598-4359-9666-6e3f91834c61

📥 Commits

Reviewing files that changed from the base of the PR and between 3d84d11 and a2e3644.

📒 Files selected for processing (12)
  • .gitattributes
  • README.md
  • docs/windows-setup.md
  • hooks/redlog-send.ps1
  • hooks/redlog-send.sh
  • hooks/shell-hook.ps1
  • hooks/wsl-redlog-test.sh
  • src/core/hooks-manager.ts
  • src/main/windows.ts
  • src/preload/index.ts
  • src/renderer/src/App.tsx
  • src/renderer/src/env.d.ts

Comment thread docs/windows-setup.md
Comment on lines +104 to +115
### 5.2 Networking — mirrored mode

The API binds `127.0.0.1` on Windows. Under WSL2's default NAT mode, WSL's
`127.0.0.1` is a separate loopback. Enable **mirrored networking**:

1. Create `%USERPROFILE%\.wslconfig`:
```ini
[wsl2]
networkingMode=mirrored
```
2. `wsl --shutdown` (from Windows PowerShell), then reopen WSL.
3. Verify: `wslinfo --networking-mode` → `mirrored`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== docs/windows-setup.md relevant section =="
sed -n '90,125p' docs/windows-setup.md 2>/dev/null || true

echo
echo "== search for WSL-networking fallback/mirroring references =="
rg -n "mirrored|networkingMode|NAT|gateway|wslinfo|127\.0\.0\.1|Windows 11|Windows 10|22H2" docs hooks . 2>/dev/null \
  | sed -n '1,200p'

echo
echo "== candidate hook files =="
git ls-files hooks/ 2>/dev/null | sed -n '1,120p'

Repository: guan4tou2/REDLOG

Length of output: 11458


Document mirrored mode as optional and version-gated.

These steps present mirrored networking as mandatory, but it requires Windows 11 22H2 or later. Since the WSL hooks already fall back to gateway.docker.internal for NAT mode, describe mirrored mode as recommended and mention the NAT fallback for Windows 10/unavailable mirrored setups.

🤖 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 `@docs/windows-setup.md` around lines 104 - 115, The “Networking — mirrored
mode” section should present mirrored networking as recommended rather than
required, state that it is supported only on Windows 11 22H2 or later, and
document that Windows 10 or unavailable mirrored setups should use the existing
NAT fallback through gateway.docker.internal.

Comment thread hooks/redlog-send.ps1
Comment on lines +52 to +61
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$ps = [powershell]::Create().AddScript({
param($uri, $headers, $body)
try {
Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body -TimeoutSec 2 | Out-Null
} catch {}
}).AddArgument($uri).AddArgument($headers).AddArgument($body)
$ps.Runspace = $rs
$null = $ps.BeginInvoke()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Dispose completed fire-and-forget runspaces.

Each event creates a runspace and PowerShell instance but never calls EndInvoke or disposes either object. Frequent shell activity can accumulate runspaces and degrade the interactive session.

  • hooks/redlog-send.ps1#L52-L61: arrange asynchronous completion to call EndInvoke(), then dispose $ps and $rs.
  • hooks/shell-hook.ps1#L47-L56: apply the same lifecycle cleanup, ideally through a shared sender implementation.
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] 58-58: Empty catch block is used. Please use Write-Error or throw statements in catch blocks.

(PSAvoidUsingEmptyCatchBlock)

📍 Affects 2 files
  • hooks/redlog-send.ps1#L52-L61 (this comment)
  • hooks/shell-hook.ps1#L47-L56
🤖 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 `@hooks/redlog-send.ps1` around lines 52 - 61, The asynchronous senders in
hooks/redlog-send.ps1 lines 52-61 and hooks/shell-hook.ps1 lines 47-56 leak
their PowerShell and runspace resources. Update both implementations, preferably
via a shared sender helper, so completion invokes EndInvoke(), then disposes the
PowerShell instance and runspace while preserving fire-and-forget behavior.

Comment thread hooks/redlog-send.sh
Comment on lines +61 to +64
if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
local gw
gw=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
if [[ -n "$gw" ]] && curl -sf --connect-timeout 1 "http://${gw}:${PORT}/api/health" >/dev/null 2>&1; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Files matching redlog-send.sh:\n'
fd -a 'redlog-send\.sh$' . || true

file="$(fd 'redlog-send\.sh$' . | head -n1 || true)"
if [[ -n "${file:-}" ]]; then
  echo
  printf 'Line count and relevant slice for %s:\n' "$file"
  wc -l "$file"
  sed -n '1,110p' "$file" | nl -ba
fi

printf '\nParsing/local context probe if file exists:\n'
python3 - <<'PY'
from pathlib import Path
files = list(Path('.').rglob('redlog-send.sh'))
print(files)
for p in files:
    text = p.read_text()
    lines = text.splitlines()
    for i,line in enumerate(lines, start=1):
        if 'if [[ -n "${WSL_DISTRO_NAME:-}"' in line:
            print(f"match at {p}:{i}")
            for j in range(max(1,i-4), min(len(lines),i+8)+1):
                print(f"{j}: {lines[j-1]}")
PY

Repository: guan4tou2/REDLOG

Length of output: 351


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo 'Relevant lines from hooks/redlog-send.sh:'
awk '1' hooks/redlog-send.sh | sed -n '1,110p' | cat -n

echo
echo 'Bash local-on-top-level behavior probe:'
bash -n <<'EOF'
set -euo pipefail
if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
  local gw
  gw='x'
fi
EOF
echo "bash -n exit code: $?" || true

bash -n <<'EOF'
set -euo pipefail
if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
  gw='x'
fi
EOF
echo "bash -n normal variable exit code: $?" || true

Repository: guan4tou2/REDLOG

Length of output: 3556


Remove the invalid local declaration.

This local gw is outside a function, so Bash emits an error when falling back to the WSL NAT gateway. Make gw a normal variable.

-      local gw
-      gw=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
+      gw=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
📝 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
if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
local gw
gw=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
if [[ -n "$gw" ]] && curl -sf --connect-timeout 1 "http://${gw}:${PORT}/api/health" >/dev/null 2>&1; then
if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
gw=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
if [[ -n "$gw" ]] && curl -sf --connect-timeout 1 "http://${gw}:${PORT}/api/health" >/dev/null 2>&1; then
🧰 Tools
🪛 Shellcheck (0.11.0)

[error] 62-62: 'local' is only valid in functions.

(SC2168)

🤖 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 `@hooks/redlog-send.sh` around lines 61 - 64, In the WSL gateway fallback block
of redlog-send.sh, remove the local declaration for gw and assign it as a normal
variable before the existing gateway health check. Preserve the current route
lookup and curl logic unchanged.

Source: Linters/SAST tools

Comment thread hooks/shell-hook.ps1
Comment on lines +65 to +73
function prompt {
$lastExit = $LASTEXITCODE
$success = $?

$entry = Get-History -Count 1 -ErrorAction SilentlyContinue
if ($entry -and $entry.Id -ne $script:_RedLogLastId) {
$cmd = $entry.CommandLine
$duration = [int]($entry.EndExecutionTime - $entry.StartExecutionTime).TotalSeconds
$exitCode = if ($success) { 0 } else { if ($lastExit) { $lastExit } else { 1 } }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Capture $? before any assignment.

Line 66 changes $? to successful before Line 67 reads it, so failed commands are reported with exit_code: 0. Preserve the prior command status first.

 function prompt {
-    $lastExit = $LASTEXITCODE
     $success = $?
+    $lastExit = $LASTEXITCODE
📝 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
function prompt {
$lastExit = $LASTEXITCODE
$success = $?
$entry = Get-History -Count 1 -ErrorAction SilentlyContinue
if ($entry -and $entry.Id -ne $script:_RedLogLastId) {
$cmd = $entry.CommandLine
$duration = [int]($entry.EndExecutionTime - $entry.StartExecutionTime).TotalSeconds
$exitCode = if ($success) { 0 } else { if ($lastExit) { $lastExit } else { 1 } }
function prompt {
$success = $?
$lastExit = $LASTEXITCODE
$entry = Get-History -Count 1 -ErrorAction SilentlyContinue
if ($entry -and $entry.Id -ne $script:_RedLogLastId) {
$cmd = $entry.CommandLine
$duration = [int]($entry.EndExecutionTime - $entry.StartExecutionTime).TotalSeconds
$exitCode = if ($success) { 0 } else { if ($lastExit) { $lastExit } else { 1 } }
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'shell-hook.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@hooks/shell-hook.ps1` around lines 65 - 73, Update the prompt function to
capture $success from $? before assigning or executing any other statement,
including the $lastExit assignment. Preserve the existing exitCode calculation
so it reports the prior command’s actual success or failure status.

Comment thread hooks/wsl-redlog-test.sh
Comment on lines +116 to +123
# Summary
step "Summary"
printf " Passed: %d Failed: %d\n" "$pass" "$fail"
if [[ $fail -eq 0 ]]; then
printf "\n $OK WSL → RedLog integration is working.\n\n"
else
printf "\n $FAIL Some checks failed — see above for remediation.\n\n"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return failure when diagnostics fail.

The script prints failed checks but exits successfully because the final printf succeeds. Return nonzero when $fail is nonzero so callers can reliably detect an unhealthy WSL integration.

 if [[ $fail -eq 0 ]]; then
   printf "\n  $OK WSL → RedLog integration is working.\n\n"
 else
   printf "\n  $FAIL Some checks failed — see above for remediation.\n\n"
+  exit 1
 fi
📝 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
# Summary
step "Summary"
printf " Passed: %d Failed: %d\n" "$pass" "$fail"
if [[ $fail -eq 0 ]]; then
printf "\n $OK WSL → RedLog integration is working.\n\n"
else
printf "\n $FAIL Some checks failed — see above for remediation.\n\n"
fi
# Summary
step "Summary"
printf " Passed: %d Failed: %d\n" "$pass" "$fail"
if [[ $fail -eq 0 ]]; then
printf "\n $OK WSL → RedLog integration is working.\n\n"
else
printf "\n $FAIL Some checks failed — see above for remediation.\n\n"
exit 1
fi
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 120-120: Don't use variables in the printf format string. Use printf '..%s..' "$foo".

(SC2059)


[info] 122-122: Don't use variables in the printf format string. Use printf '..%s..' "$foo".

(SC2059)

🤖 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 `@hooks/wsl-redlog-test.sh` around lines 116 - 123, Update the final
conditional in the WSL-to-RedLog summary flow so that a nonzero $fail causes the
script to exit with a nonzero status after printing the failure message.
Preserve the successful status when $fail is zero and keep the existing summary
output unchanged.

Comment thread src/core/hooks-manager.ts
Comment on lines +269 to +278
case 'shell-powershell':
return [
{
label: 'Add to your PowerShell profile so it loads on every session',
command: `Add-Content $PROFILE '. "${hookFile}"'`
},
{
label: 'Or source it manually in the current session',
command: `. "${hookFile}"`
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Escape the hook path for PowerShell literals.

A path such as C:\Users\O'Brien\... breaks both generated commands; double-quoted sourcing can also expand $ and backticks. Escape single quotes and emit a literal PowerShell path before displaying these instructions.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execSync } from 'child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

🤖 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/core/hooks-manager.ts` around lines 269 - 278, Update the
shell-powershell branch in the hooks-manager switch to escape hookFile for
PowerShell string literals before constructing either command. Ensure embedded
single quotes are escaped and the emitted path is literal, preventing expansion
of dollar signs and backticks in both the Add-Content and manual sourcing
instructions while preserving the existing labels.

Comment thread src/renderer/src/App.tsx
Comment on lines +361 to +363
...VIEW_KEYS.map((v, i) => [`${modKey}${i + 1}`, t(`sidebar.${v === 'screenshots' ? 'screens' : v}`)] as [string, string]),
[isMac ? '⌘⇧M' : 'Ctrl+Shift+M', t('dashboard.addMarker')] as [string, string],
[`${modKey}/`, t('dashboard.search')] as [string, string]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the marker shortcut tooltip platform-specific.

The dashboard now displays ⌘⇧M on macOS, but the marker button’s tooltip at Line 100 remains hardcoded to Ctrl+Shift+M. Reuse a shared markerShortcut value for both labels.

Proposed fix
+const markerShortcut = isMac ? '⌘⇧M' : 'Ctrl+Shift+M'
+
             {[
-              [isMac ? '⌘⇧M' : 'Ctrl+Shift+M', t('dashboard.addMarker')] as [string, string],
+              [markerShortcut, t('dashboard.addMarker')] as [string, string],
...
-            title="Ctrl+Shift+M"
+            title={markerShortcut}
🤖 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/App.tsx` around lines 361 - 363, Define a shared
markerShortcut value in the App component using ⌘⇧M on macOS and Ctrl+Shift+M
otherwise, then reuse it for both the marker shortcut entry in the dashboard
shortcut labels and the marker button tooltip. Remove the tooltip’s hardcoded
shortcut while preserving the existing translations.

guantouwu-chtsec and others added 2 commits July 29, 2026 13:28
- Fix titleBarStyle: use 'hidden' + titleBarOverlay on Windows so
  min/max/close controls remain usable (macOS keeps 'hiddenInset')
- Expose process.platform to renderer; platform-aware title bar
  padding and keyboard shortcut labels (Ctrl+ vs ⌘)
- Add PowerShell shell hook (shell-hook.ps1) that captures commands
  via prompt override + Get-History, fire-and-forget via runspaces
- Add PowerShell event sender (redlog-send.ps1) for scripted use
- Add WSL hooks: redlog-send.sh (auto-resolves Windows token path)
  and wsl-redlog-test.sh (diagnostics for WSL→Windows connectivity)
- Register PowerShell hook in hooks-manager with manual setup steps;
  fix bash hook availability on Windows (detects WSL/Git Bash)
- Add .gitattributes to enforce LF for shell/python scripts
- Add docs/windows-setup.md covering build, hooks, WSL, and isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… safe

When exposedIPs is configured and the current external IP does not
match, classify it as 'safe' instead of 'unknown'. This lets operators
blacklist their real IPs (home, office) so any other exit IP (VPN,
tunnel) is implicitly trusted — no need to track VPN IP ranges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@guan4tou2
guan4tou2 force-pushed the windows-support-v3 branch from 052be41 to 0e7d8d7 Compare July 29, 2026 05:30
@guan4tou2
guan4tou2 merged commit e19ea9f into main Jul 29, 2026
1 of 2 checks passed
@guan4tou2
guan4tou2 deleted the windows-support-v3 branch July 29, 2026 05:31
guan4tou2 added a commit that referenced this pull request Jul 30, 2026
… Integrations / Data

An audit flagged the 'data' Settings tab as a dumping ground — 10 unrelated
FieldGroups (screenshot quality, overlay HUD × 5 controls, clipboard, update
checks, browser panel, CDP, export JSON, scope-filtered export, integrity
anchors, profile sync). Reorganize into 8 focused tabs (was 7):

  general       — engagement / operator / language  (unchanged; +i18n Language)
  hud           — overlay (mark button, flash, scale, emphasize IP, dock)  [new]
  capture       — hooks + screenshot quality + clipboard                    [was 'hooks']
  network       — IP monitoring + VPN adapters      (unchanged)
  scope         — scope rules                       (unchanged)
  integrations  — MCP + operators + deconfliction + browser + CDP  [was 'team']
  data          — updates + export + scope export + integrity + profile sync (slim)
  plugins       — plugin registry                   (unchanged)

Data drops from 10 groups → 5. Each remaining tab is coherent (all groups
share a "why they exist" story).

Also fixed a P0 bug the audit surfaced (finding #3): four sibling checkboxes
in the overlay group each re-derived `showMarkButton: config.overlay?.
showMarkButton !== false` in their onChange, which silently re-flipped the
mark-button toggle whenever the user changed any other overlay setting.
Killed via perl replace across all 4 sites; spreading ...config.overlay
already carries the current value.

Also fixed P1 #20 (hardcoded English "Language" title) — moved to
`settings.language` i18n key.

Deferred audit findings (P0 bugs, still open): toast auto-dismiss timer
sharing across bursts (#6), didScrollToNow ref never resets on re-focus
(#7), ⌘1..9 shortcut order doesn't match sidebar order (#8), TargetView
dead scope_violation branch (#4), double marker-shortcut listener (#5),
native window.confirm() for operator delete (#2), alert() for CDP test
(#1). These get their own follow-up commits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2 added a commit that referenced this pull request Jul 30, 2026
#1 CDP "Test connection" used native alert() with hardcoded English —
    now uses toast with i18n keys (settings.cdpConnected / cdpNotConnected).
  • #2 Delete-operator used window.confirm() (every other destructive action
    uses ConfirmDialog) — now consistent + themable + non-blocking.
  • #4 TargetView filtered `agentType === 'scope_violation'`, but scope
    violations are stored as agentType='system' subtype='scope_violation'.
    Dead branch since the event schema landed; a target's scope hits never
    showed up. Fixed the filter.
  • #5 Marker shortcut fired twice (⌘/Ctrl+Shift+M): main-process
    globalShortcut handler + renderer keydown listener both ran when the
    window had focus, opening the dialog twice / racing. Renderer listener
    dropped; main-process handler stays.
  • #6 Toast auto-dismiss timer was shared across all toasts, keyed on the
    array. Every new push reset the 3s clock for the OLDEST toast — bursts
    of toasts kept each other alive indefinitely. Fixed: each toast carries
    its own createdAt, a 500ms tick prunes anything older than 3s.
  • #7 Timeline's `didScrollToNow` ref was set once and never reset. A
    second Loot→Timeline jump (after coming back from another view)
    silently short-circuited. Now resets on focusEventId / focusTs change.
  • #8 ⌘1..9 shortcuts followed a hardcoded VIEW_KEYS array that didn't
    match the sidebar's DEFAULT_ORDER (Timeline was slot #2 in the sidebar
    per v0.6.18 but ⌘2 opened Terminal). Extracted the order + storage into
    src/renderer/src/lib/sidebarOrder.ts; Sidebar persists via it,
    App.tsx's ⌘1..N handler reads fresh on every keypress, Dashboard
    cheatsheet subscribes to changes. Order now stays in sync even after a
    drag-reorder.

Also added: new lib exports STORAGE_KEY / DEFAULT_ORDER / loadSidebarOrder
/ saveSidebarOrder / onSidebarOrderChanged + a `redlog:sidebar-order-
changed` custom event for same-tab subscribers (native `storage` fires only
cross-tab, useless here for Electron single-window).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2 added a commit that referenced this pull request Jul 30, 2026
App-wide keyboard (audit #78):
  • ⌘/Ctrl+. — pause/resume recording (toast confirmation).

Terminal view (audit #78, in-view):
  • ⌘/Ctrl+T — new tab.
  • ⌘/Ctrl+W — close active tab (still confirms if the shell is alive).
  • ⌘/Ctrl+Shift+] / [ — next / previous tab.

Timeline (audit #4 + #78):
  • Alt/Option-click a lane chip = solo (hide every other populated lane);
    Alt-click a solo'd lane again = show all. Was 13 clicks to "show only
    shell", is now 1.
  • Show-all button appears next to the chips whenever any lane is hidden.
  • Escape closes the event detail panel (was mouse-only via × button).

HUD (audit #52):
  • Pin button (📌 → 📍) in the expanded HUD button row disables the 8s
    auto-collapse. Session-local; toast-free. Reviewer studying the topology
    chain can leave it up. Unpin returns to normal auto-collapse.

New i18n keys: timeline.showAll/showAllLanes/laneChipHint, overlay.pin/unpin,
terminal.searchNext/Prev/etc. Deduped a leftover terminal.newTab key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants