Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions .aiox-core/core/orchestration/workflow-executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

const fs = require('fs').promises;
const fsSync = require('fs');
const os = require('os');
const path = require('path');
const yaml = require('js-yaml');

Expand Down Expand Up @@ -778,13 +779,29 @@ class WorkflowExecutor {
const { promisify } = require('util');
const execAsync = promisify(exec);

// Build command based on installation mode
// Build command for current platform.
// - Explicit installation_mode: 'wsl' | 'native' wins (lets ops override).
// - Default: Windows hosts wrap via WSL, macOS/Linux run the binary directly.
// - cli_path defaults to ~/.local/bin/coderabbit (matches the CodeRabbit CLI installer default).
// We expand leading "~" with os.homedir() defensively — `child_process.exec`
// under a shell expands it, but the native code path goes through `execAsync`
// which calls /bin/sh -c, and on Windows the host shell behavior is less
// predictable. Programmatic expansion removes the ambiguity.
const rawCliPath = coderabbitConfig.cli_path || '~/.local/bin/coderabbit';
const cliPath = rawCliPath.startsWith('~')
? path.join(os.homedir(), rawCliPath.slice(1))
: rawCliPath;
const mode =
coderabbitConfig.installation_mode ||
(process.platform === 'win32' ? 'wsl' : 'native');
let command;
if (coderabbitConfig.installation_mode === 'wsl') {
const wslPath = this.projectRoot.replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`).replace(/\\/g, '/');
command = `wsl bash -c 'cd "${wslPath}" && ~/.local/bin/coderabbit --prompt-only -t uncommitted 2>&1'`;
if (mode === 'wsl') {
const wslPath = this.projectRoot
.replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`)
.replace(/\\/g, '/');
command = `wsl bash -c 'cd "${wslPath}" && ${cliPath} --prompt-only -t uncommitted 2>&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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing WSL availability check on Windows.

When mode === 'wsl', the code assumes WSL is installed and accessible. If WSL is not available on a Windows system, the error message will be generic ("command not found" at line 821) rather than platform-specific guidance.

Consider adding an explicit WSL availability check on Windows hosts, or enhance the error message to suggest WSL installation when the command fails on win32.

💡 Example WSL availability check
     if (mode === 'wsl') {
+      // Quick check if WSL is available on Windows
+      if (process.platform === 'win32') {
+        try {
+          require('child_process').execSync('wsl --status', { stdio: 'ignore' });
+        } catch {
+          return {
+            success: false,
+            error: 'WSL not available. Install WSL or set installation_mode to "native".',
+            issues: [],
+          };
+        }
+      }
       const wslPath = this.projectRoot
         .replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`)
         .replace(/\\/g, '/');
📝 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 (mode === 'wsl') {
const wslPath = this.projectRoot
.replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`)
.replace(/\\/g, '/');
command = `wsl bash -c 'cd "${wslPath}" && ${cliPath} --prompt-only -t uncommitted 2>&1'`;
if (mode === 'wsl') {
// Quick check if WSL is available on Windows
if (process.platform === 'win32') {
try {
require('child_process').execSync('wsl --status', { stdio: 'ignore' });
} catch {
return {
success: false,
error: 'WSL not available. Install WSL or set installation_mode to "native".',
issues: [],
};
}
}
const wslPath = this.projectRoot
.replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`)
.replace(/\\/g, '/');
command = `wsl bash -c 'cd "${wslPath}" && ${cliPath} --prompt-only -t uncommitted 2>&1'`;
🤖 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 @.aiox-core/core/orchestration/workflow-executor.js around lines 790 - 794,
In the mode === 'wsl' branch (where wslPath, command and cliPath are set in the
workflow-executor implementation), add an explicit WSL availability check when
running on Windows (process.platform === 'win32') before constructing/executing
the wsl command: synchronously probe for WSL (e.g., spawnSync('wsl', ['-l']) or
check existence of wsl.exe) and if the check fails throw or return a clear,
platform-specific error suggesting enabling/installing WSL and Windows Subsystem
for Linux components instead of proceeding to run the command; additionally,
when catching failures from executing command, if process.platform === 'win32'
augment the error message to include the same WSL installation guidance so
callers see actionable advice.

} else {
command = 'coderabbit --prompt-only -t uncommitted';
command = `${cliPath} --prompt-only -t uncommitted`;
}

if (this.options.debug) {
Expand Down
33 changes: 29 additions & 4 deletions .aiox-core/core/quality-gates/layer2-pr-automation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

const { spawn } = require('child_process');
const fs = require('fs').promises;
const os = require('os');
const path = require('path');
const { BaseLayer } = require('./base-layer');

Expand Down Expand Up @@ -96,10 +97,34 @@ class Layer2PRAutomation extends BaseLayer {
}

try {
// Check if CodeRabbit is available
const command =
this.coderabbit.command ||
"wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t uncommitted'";
// Build command for current platform when no explicit override is present.
// - this.coderabbit.command: explicit string wins (backward compat with old configs).
// - this.coderabbit.installation_mode: 'wsl' | 'native' lets ops override platform detection.
// - Default: Windows hosts wrap via WSL, macOS/Linux run the binary directly.
// - Tilde and ${PROJECT_ROOT} are resolved programmatically — `child_process.spawn`
// with `shell: true` does shell expansion, but we cannot rely on PROJECT_ROOT
// being set in the env at call sites, so substitute it here.
let command;
if (this.coderabbit.command) {
command = this.coderabbit.command;
} else {
const rawCliPath = this.coderabbit.cli_path || '~/.local/bin/coderabbit';
const cliPath = rawCliPath.startsWith('~')
? path.join(os.homedir(), rawCliPath.slice(1))
: rawCliPath;
const mode =
this.coderabbit.installation_mode ||
(process.platform === 'win32' ? 'wsl' : 'native');
if (mode === 'wsl') {
const projectRoot = this.coderabbit.projectRoot || process.cwd();
const wslProjectPath = projectRoot
.replace(/\\/g, '/')
.replace(/^([A-Z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
command = `wsl bash -c 'cd "${wslProjectPath}" && ${cliPath} --prompt-only -t uncommitted'`;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
} else {
command = `${cliPath} --prompt-only -t uncommitted`;
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const result = await this.runCommand(command, timeout);

Expand Down
11 changes: 10 additions & 1 deletion .aiox-core/core/quality-gates/quality-gate-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ layer2:
enabled: true
coderabbit:
enabled: true
command: "wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t uncommitted'"
# Cross-platform CodeRabbit CLI invocation (Issue #731).
# Runtime resolves the command from cli_path + platform detection:
# - macOS/Linux: run cli_path directly from project root.
# - Windows: wrap with 'wsl bash -c' and rewrite project paths to /mnt/<drive>/...
# Set installation_mode explicitly ('wsl' | 'native') to override platform detection.
# Set command: "<raw shell string>" to bypass detection entirely (back-compat).
cli_path: ~/.local/bin/coderabbit
platform_notes:
macos_linux: "Run binary directly from project root (PATH or cli_path)."
windows: "Wrap with 'wsl bash -c' and use /mnt/<drive>/... project paths."
timeout: 900000 # 15 minutes
blockOn:
- CRITICAL
Expand Down
Loading
Loading