Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 23 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,30 @@ 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).
// - Tilde handling differs per mode: native expands via os.homedir() so the
// resolved absolute path is shell-agnostic; WSL mode keeps the literal `~`
// so the WSL distribution's own bash expands it (the host's HOME would point
// at a Windows path that WSL cannot resolve).
const rawCliPath = coderabbitConfig.cli_path || '~/.local/bin/coderabbit';
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-Za-z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`)
.replace(/\\/g, '/');
// Keep literal `~` — WSL bash expands it to the WSL user's HOME.
command = `wsl bash -c 'cd "${wslPath}" && ${rawCliPath} --prompt-only -t uncommitted 2>&1'`;
} else {
command = 'coderabbit --prompt-only -t uncommitted';
const cliPath = rawCliPath.startsWith('~')
? path.join(os.homedir(), rawCliPath.slice(1))
: rawCliPath;
command = `${cliPath} --prompt-only -t uncommitted`;
}

if (this.options.debug) {
Expand Down
38 changes: 34 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,39 @@ 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.
// - ${PROJECT_ROOT} is 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.
// - Tilde handling differs per mode: native expands via os.homedir() so the
// resolved absolute path is shell-agnostic; WSL mode keeps the literal `~`
// so the WSL distribution's own bash expands it (the host's HOME would point
// at a Windows path that WSL cannot resolve).
let command;
if (this.coderabbit.command) {
command = this.coderabbit.command;
} else {
const rawCliPath = this.coderabbit.cli_path || '~/.local/bin/coderabbit';
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-Za-z]):/, (_, drive) => `/mnt/${drive.toLowerCase()}`);
// Keep literal `~` — WSL bash expands it to the WSL user's HOME.
command = `wsl bash -c 'cd "${wslProjectPath}" && ${rawCliPath} --prompt-only -t uncommitted'`;
} else {
const cliPath = rawCliPath.startsWith('~')
? path.join(os.homedir(), rawCliPath.slice(1))
: rawCliPath;
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