Skip to content

Bridge sidecar proxy and align sandbox runtime paths - #288

Merged
Moskize91 merged 1 commit into
mainfrom
codex/sidecar-system-proxy
Jul 29, 2026
Merged

Bridge sidecar proxy and align sandbox runtime paths#288
Moskize91 merged 1 commit into
mainfrom
codex/sidecar-system-proxy

Conversation

@Moskize91

Copy link
Copy Markdown
Contributor

Summary

  • bridge system proxy settings into the OpenCode sidecar environment
  • allow Wanta-managed WikiGraph commands to run inside Command Sandbox with the correct runtime and knowledge-state access
  • centralize dev/packaged Wanta runtime layout roots so sandbox permissions match Electron runtime structure

Verification

  • corepack pnpm exec vitest run electron/agent/sidecar.test.ts electron/agent/event-translator.test.ts
  • corepack pnpm exec vitest run electron/agent/runtime-layout.test.ts electron/agent/manager.test.ts electron/agent/wikigraph-bin.test.ts electron/knowledge/runner.test.ts electron/chat/context-system.test.ts
  • corepack pnpm run ts-check
  • corepack pnpm run dev:worktree, with sandbox wg --help runtime check

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 55 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e5822cdd-3443-4b19-9bf1-24f31d8a71d6

📥 Commits

Reviewing files that changed from the base of the PR and between 5aae064 and 0686b21.

📒 Files selected for processing (3)
  • electron/agent/event-translator.ts
  • electron/agent/sidecar.test.ts
  • electron/agent/sidecar.ts

Walkthrough

Adds runtime layout resolution for Electron-managed command-sandbox paths, including packaged and development environments. Passes the resolved layout into AgentManager, which conditionally grants wiki-graph state write access to knowledge-base sessions. Adds macOS and Windows system proxy parsing, merges proxy variables into sidecar environments, and logs redacted network summaries. Non-aborted OpenCode session errors now emit diagnostic context before producing the existing agent error event.

Sequence Diagram(s)

sequenceDiagram
  participant ElectronMain
  participant AgentManager
  participant CommandSandbox
  participant OpencodeSidecar
  participant SystemProxy
  ElectronMain->>AgentManager: provide runtime layout
  AgentManager->>CommandSandbox: write session policy with conditional runtime paths
  OpencodeSidecar->>SystemProxy: query host proxy configuration
  SystemProxy-->>OpencodeSidecar: return proxy environment and summary
  OpencodeSidecar->>OpencodeSidecar: merge missing proxy variables
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title is relevant, but it does not follow the required <type>(<scope>): <subject> format. Rename it to something like feat(sidecar): bridge proxy settings and align sandbox runtime paths.},{
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/sidecar-system-proxy

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

@Moskize91
Moskize91 force-pushed the codex/sidecar-system-proxy branch from 5aae064 to 0686b21 Compare July 29, 2026 05:53

@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: 3

🧹 Nitpick comments (4)
electron/agent/sidecar.test.ts (2)

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

Add a SOCKS-only macOS case.

The fixture enables all three proxies, so the httpsProxy ?? httpProxy ?? socksProxy fallback in parseMacSystemProxy is never exercised for the SOCKS branch (socks5:// URL). A case with only SOCKSEnable : 1 would lock that behavior in.

🤖 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 `@electron/agent/sidecar.test.ts` around lines 145 - 217, Add a SOCKS-only test
case in the “macOS system proxy environment” suite using a fixture with only
SOCKSEnable enabled and the SOCKS host/port configured. Assert that
parseMacSystemProxy returns the expected socks5:// proxy environment, including
the SOCKS-derived ALL_PROXY value, so the socksProxy fallback path is covered.

219-275: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider a credentialed ProxyServer case.

Adding a fixture like user:secret@127.0.0.1:7897 would cover the redaction path in the summary, which is where the leak flagged in electron/agent/sidecar.ts (Line 109) surfaces.

🤖 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 `@electron/agent/sidecar.test.ts` around lines 219 - 275, Add a credentialed
ProxyServer fixture to the Windows system proxy tests around
parseWindowsSystemProxy, using a user/password proxy URL and asserting that
summary.ProxyServer redacts the credentials while the generated environment
retains the usable proxy value. Ensure the test covers the redaction path in
parseWindowsSystemProxy without changing unrelated proxy behavior.
electron/agent/sidecar.ts (2)

194-201: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Key lookups are case-sensitive while the line match is not.

The regex matches value names case-insensitively but stores match[1] verbatim, so values.get("ProxyEnable") misses any output whose casing differs. Normalize the key when storing.

♻️ Suggested tweak
-    if (match?.[1] && match[2]) {
-      values.set(match[1], match[2])
-    }
+    if (match?.[1] && match[2]) {
+      const key = ["ProxyEnable", "ProxyServer", "ProxyOverride", "AutoConfigURL"].find(
+        (name) => name.toLowerCase() === match[1].toLowerCase(),
+      )
+      if (key) values.set(key, match[2])
+    }
🤖 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 `@electron/agent/sidecar.ts` around lines 194 - 201, Normalize the captured
registry value name before storing it in the values map within
parseWindowsSystemProxy, so case-variant matches resolve through the existing
canonical lookups such as values.get("ProxyEnable"). Preserve the current
parsing and value handling.

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

Failure path silently yields no proxy diagnostics distinction.

systemProxy() returning { env: {}, summary: { error } } is fine for mergeSystemProxyEnvironment (no-op), and the 1s timeout bounds startup. Consider logging at warn level rather than only embedding the message in the trace-level network summary, so proxy-detection failures are visible when users report connectivity issues.

🤖 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 `@electron/agent/sidecar.ts` around lines 344 - 365, Update the catch path in
systemProxy to emit a warn-level log containing the proxy-detection error and
relevant context before returning the existing { env: {}, summary: { error } }
fallback. Preserve the current fallback shape and timeout behavior.
🤖 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 `@electron/agent/event-translator.ts`:
- Around line 408-417: Update the opencode session error logging call in the
event translator to remove the raw p.error object from the diagnostic payload.
Retain only the necessary structured fields, such as the sanitized error message
and sessionId, while preserving the existing error severity and diagnostic event
context.

In `@electron/agent/manager.ts`:
- Line 71: Update the sandbox-enabled manager configuration around runtimeLayout
and commandSandboxCliPath so callers cannot lose access to the command CLI and
process.execPath roots when runtimeLayout is absent. Either require
runtimeLayout whenever sandboxing is enabled, or preserve the prior runtime
roots as an explicit fallback, and add a regression test covering a
sandbox-enabled manager without runtimeLayout.

In `@electron/agent/sidecar.ts`:
- Around line 109-118: Update redactProxyValue so the parsed-URL path only
returns the URL when url.host is non-empty; otherwise use the existing regex
fallback to redact credentials in scheme-less proxy values. Preserve the current
behavior for valid URLs with a host and malformed values.

---

Nitpick comments:
In `@electron/agent/sidecar.test.ts`:
- Around line 145-217: Add a SOCKS-only test case in the “macOS system proxy
environment” suite using a fixture with only SOCKSEnable enabled and the SOCKS
host/port configured. Assert that parseMacSystemProxy returns the expected
socks5:// proxy environment, including the SOCKS-derived ALL_PROXY value, so the
socksProxy fallback path is covered.
- Around line 219-275: Add a credentialed ProxyServer fixture to the Windows
system proxy tests around parseWindowsSystemProxy, using a user/password proxy
URL and asserting that summary.ProxyServer redacts the credentials while the
generated environment retains the usable proxy value. Ensure the test covers the
redaction path in parseWindowsSystemProxy without changing unrelated proxy
behavior.

In `@electron/agent/sidecar.ts`:
- Around line 194-201: Normalize the captured registry value name before storing
it in the values map within parseWindowsSystemProxy, so case-variant matches
resolve through the existing canonical lookups such as
values.get("ProxyEnable"). Preserve the current parsing and value handling.
- Around line 344-365: Update the catch path in systemProxy to emit a warn-level
log containing the proxy-detection error and relevant context before returning
the existing { env: {}, summary: { error } } fallback. Preserve the current
fallback shape and timeout 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 96a424f3-befc-45d8-a090-422aaf259609

📥 Commits

Reviewing files that changed from the base of the PR and between fc6d49a and 5aae064.

📒 Files selected for processing (8)
  • electron/agent/event-translator.ts
  • electron/agent/manager.test.ts
  • electron/agent/manager.ts
  • electron/agent/runtime-layout.test.ts
  • electron/agent/runtime-layout.ts
  • electron/agent/sidecar.test.ts
  • electron/agent/sidecar.ts
  • electron/main.ts

Comment on lines +408 to +417
logDiagnostic(
"opencode-event-stream",
"opencode session error",
{
error: p.error,
message: errorMessage(p.error),
sessionId: p.sessionID,
},
"error",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -t f 'diagnostics-log.ts' -x cat -n {}

Repository: oomol-lab/wanta

Length of output: 8862


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== event-translator excerpt =="
sed -n '380,435p' electron/agent/event-translator.ts

echo
echo "== diagnostics-log serializer excerpt =="
sed -n '1,260p' electron/agent/diagnostics-log.ts

Repository: oomol-lab/wanta

Length of output: 1750


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== diagnostics-related files =="
fd -t f 'diagnostics-log.ts' -t f 'diagnostics*.ts' -t f 'log*.ts' electron

echo
echo "== errorMessage references =="
rg -n "function errorMessage|const errorMessage|errorMessage\(" electron/agent electron -g '!**/dist/**' -g '!**/build/**'

echo
echo "== opencode session error context =="
rg -n "session.error|opencode session error|agentError" electron/agent -g '!**/dist/**' -g '!**/build/**'

Repository: oomol-lab/wanta

Length of output: 3589


Avoid logging the raw OpenCode error object in electron/agent/event-translator.ts. The diagnostics logger recursively serializes object fields (including nested Error.stack/cause) and only truncates strings, so upstream response contents can still leak; log only the structured fields you need.

🤖 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 `@electron/agent/event-translator.ts` around lines 408 - 417, Update the
opencode session error logging call in the event translator to remove the raw
p.error object from the diagnostic payload. Retain only the necessary structured
fields, such as the sanitized error message and sessionId, while preserving the
existing error severity and diagnostic event context.

Comment thread electron/agent/manager.ts Outdated
bundledToolRuntimePath?: string
/** App 私有根目录(userData 下):workspace / oo-store / isolation 都在其下。 */
rootDir: string
runtimeLayout?: WantaRuntimeLayout

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

Preserve runtime read roots when the optional layout is absent.

A caller with commandSandboxCliPath but no runtimeLayout now grants only the generated shell directory and PATH entries; it no longer grants the command CLI or process.execPath roots. The sandbox wrapper can therefore be denied access to its own managed runtime. Require runtimeLayout for sandbox-enabled managers, or retain the previous roots as a fallback and add a regression test.

Proposed fallback
 this.commandSandboxRuntimeReadPaths = [
   workspaceDir,
   path.dirname(shellPath),
-  ...(this.options.runtimeLayout?.managedRuntimeReadPaths ?? []),
+  ...(this.options.runtimeLayout?.managedRuntimeReadPaths ?? [
+    path.dirname(cliPath),
+    path.dirname(process.execPath),
+  ]),
   ...baseCommandPath.split(path.delimiter),
 ]

Also applies to: 629-635

🤖 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 `@electron/agent/manager.ts` at line 71, Update the sandbox-enabled manager
configuration around runtimeLayout and commandSandboxCliPath so callers cannot
lose access to the command CLI and process.execPath roots when runtimeLayout is
absent. Either require runtimeLayout whenever sandboxing is enabled, or preserve
the prior runtime roots as an explicit fallback, and add a regression test
covering a sandbox-enabled manager without runtimeLayout.

Comment thread electron/agent/sidecar.ts
Comment on lines +109 to +118
function redactProxyValue(value: string): string {
try {
const url = new URL(value)
url.username = url.username ? "[redacted]" : ""
url.password = url.password ? "[redacted]" : ""
return url.toString()
} catch {
return value.replace(/\/\/[^/@\s]+@/u, "//[redacted]@")
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node -e '
const v = "user:pass@proxy.example:8080";
const u = new URL(v);
u.username = "[redacted]"; u.password = "[redacted]";
console.log("parsed:", u.protocol, JSON.stringify(u.host), "->", u.toString());
'

Repository: oomol-lab/wanta

Length of output: 202


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== sidecar.ts outline =="
ast-grep outline electron/agent/sidecar.ts --view expanded || true

echo
echo "== relevant section =="
sed -n '90,140p' electron/agent/sidecar.ts

echo
echo "== search for proxy value sources/usages =="
rg -n "ProxyServer|redactProxyValue|proxy" electron/agent -g '!**/dist/**' -g '!**/build/**' || true

Repository: oomol-lab/wanta

Length of output: 11016


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '194,310p' electron/agent/sidecar.ts

echo
echo "== tests around Windows proxy redaction =="
sed -n '219,320p' electron/agent/sidecar.test.ts

echo
echo "== focused search for redactProxyValue test coverage =="
rg -n "redactProxyValue|redactWindowsProxyServer|AutoConfigURL|ProxyServer" electron/agent/sidecar.test.ts

Repository: oomol-lab/wanta

Length of output: 7730


Redact scheme-less proxy credentials when the parsed URL has no host.

new URL("user:pass@proxy.example:8080") stays opaque (host === ""), so the username/password assignments do nothing and the credentials reach the summary unchanged. Fall back to the regex redaction whenever url.host is empty.

🤖 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 `@electron/agent/sidecar.ts` around lines 109 - 118, Update redactProxyValue so
the parsed-URL path only returns the URL when url.host is non-empty; otherwise
use the existing regex fallback to redact credentials in scheme-less proxy
values. Preserve the current behavior for valid URLs with a host and malformed
values.

@Moskize91
Moskize91 merged commit 835d721 into main Jul 29, 2026
3 checks passed
@Moskize91
Moskize91 deleted the codex/sidecar-system-proxy branch July 29, 2026 05:55
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