From f7ec958a69949a7f728d8b5452f99bab67f43e14 Mon Sep 17 00:00:00 2001 From: mkorwel Date: Fri, 13 Mar 2026 18:51:48 -0700 Subject: [PATCH] feat(deep-review): finalize orchestration tests and integrate into main test suite --- .gemini/skills/deep-review/scripts/review.ts | 30 +++++++++++-------- .../deep-review/tests/orchestration.test.ts | 11 ++++--- scripts/tests/vitest.config.ts | 5 +++- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/.gemini/skills/deep-review/scripts/review.ts b/.gemini/skills/deep-review/scripts/review.ts index 2fa2ae0d90..9a85080b95 100644 --- a/.gemini/skills/deep-review/scripts/review.ts +++ b/.gemini/skills/deep-review/scripts/review.ts @@ -76,21 +76,24 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p const localEnv = path.join(REPO_ROOT, '.env'); if (fs.existsSync(localEnv)) spawnSync('rsync', ['-avz', localEnv, `${remoteHost}:${remoteWorkDir}/.env`]); } +// 4. Construct Clean Command +const envLoader = 'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"'; +// Set FORCE_LOCAL_OPEN=1 to signal the worker to use OSC 1337 for links +const remoteWorker = `export FORCE_LOCAL_OPEN=1 && export GEMINI_CLI_HOME=${ISOLATED_GEMINI} && export GH_CONFIG_DIR=${ISOLATED_GH} && ./node_modules/.bin/tsx .gemini/skills/deep-review/scripts/entrypoint.ts ${prNumber} ${branchName} ${remotePolicyPath}`; - // 3. Construct Clean Command - const envLoader = 'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"'; - const entryCmd = `cd ${remoteWorkDir} && ${envLoader} && export GEMINI_CLI_HOME=${ISOLATED_GEMINI} && export GH_CONFIG_DIR=${ISOLATED_GH} && ./node_modules/.bin/tsx .gemini/skills/deep-review/scripts/entrypoint.ts ${prNumber} ${branchName} ${remotePolicyPath}`; - - const tmuxCmd = `$SHELL -ic ${q(entryCmd)}; exec $SHELL`; - const sshInternal = `tmux attach-session -t ${sessionName} 2>/dev/null || tmux new-session -s ${sessionName} -n ${q(branchName)} ${q(tmuxCmd)}`; - const sshCmd = `ssh -t ${remoteHost} ${q(sshInternal)}`; +const tmuxCmd = `cd ${remoteWorkDir} && ${envLoader} && ${remoteWorker}; exec $SHELL`; +const sshInternal = `tmux attach-session -t ${sessionName} 2>/dev/null || tmux new-session -s ${sessionName} -n ${q(branchName)} ${q(tmuxCmd)}`; +const sshCmd = `ssh -t ${remoteHost} ${q(sshInternal)}`; - // 4. Smart Context Execution - const isWithinGemini = !!env.GEMINI_SESSION_ID || !!env.GCLI_SESSION_ID; +// 5. Smart Context Execution +// Check if we are running inside a Gemini CLI session or a plain shell +const isWithinGemini = !!env.GEMINI_SESSION_ID || !!env.GCLI_SESSION_ID; +const forceBackground = args.includes('--background'); + +if (isWithinGemini || forceBackground) { + if (process.platform === 'darwin' && terminalType !== 'none' && !forceBackground) { + // macOS: Use Window Automation (Interactive Mode) - if (isWithinGemini) { - if (process.platform === 'darwin' && terminalType !== 'none') { - // macOS: Use Window Automation let appleScript = ''; if (terminalType === 'iterm2') { appleScript = `on run argv\n set theCommand to item 1 of argv\n tell application "iTerm"\n set newWindow to (create window with default profile)\n tell current session of newWindow\n write text theCommand\n end tell\n activate\n end tell\n end run`; @@ -110,7 +113,8 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p const logFile = path.join(REPO_ROOT, `.gemini/logs/review-${prNumber}/background.log`); fs.mkdirSync(path.dirname(logFile), { recursive: true }); - const backgroundCmd = `ssh ${remoteHost} ${q(entryCmd)} > ${q(logFile)} 2>&1 &`; + // Use tmuxCmd for background mode to ensure persistence even in background + const backgroundCmd = `ssh ${remoteHost} ${q(tmuxCmd)} > ${q(logFile)} 2>&1 &`; spawnSync(backgroundCmd, { shell: true }); console.log(`⏳ Remote worker started in background.`); diff --git a/.gemini/skills/deep-review/tests/orchestration.test.ts b/.gemini/skills/deep-review/tests/orchestration.test.ts index ac652aa6e3..f98e1e82ba 100644 --- a/.gemini/skills/deep-review/tests/orchestration.test.ts +++ b/.gemini/skills/deep-review/tests/orchestration.test.ts @@ -104,11 +104,14 @@ describe('Deep Review Orchestration', () => { await runOrchestrator(['123'], {}); // No session IDs in env const spawnCalls = vi.mocked(spawnSync).mock.calls; - // console.log('Terminal Calls:', spawnCalls.map(c => c[0])); const terminalCall = spawnCalls.find(call => { - const cmdStr = typeof call[0] === 'string' ? call[0] : (Array.isArray(call[1]) ? call[1].join(' ') : ''); - // The orchestrator constructs a complex command string for shell:true - return cmdStr.includes('ssh -t') && call[2]?.stdio === 'inherit'; + const cmdStr = typeof call[0] === 'string' ? call[0] : ''; + // In Direct Shell Mode, spawnSync(sshCmd, { stdio: 'inherit', ... }) + // Options are in the second argument (index 1) + const options = call[1] as any; + return cmdStr.includes('ssh -t test-host') && + cmdStr.includes('tmux attach-session') && + options?.stdio === 'inherit'; }); expect(terminalCall).toBeDefined(); }); diff --git a/scripts/tests/vitest.config.ts b/scripts/tests/vitest.config.ts index 9eb42595cf..1903738aa2 100644 --- a/scripts/tests/vitest.config.ts +++ b/scripts/tests/vitest.config.ts @@ -10,7 +10,10 @@ export default defineConfig({ test: { globals: true, environment: 'node', - include: ['scripts/tests/**/*.test.{js,ts}'], + include: [ + 'scripts/tests/**/*.test.{js,ts}', + '.gemini/skills/**/tests/*.test.ts', + ], setupFiles: ['scripts/tests/test-setup.ts'], coverage: { provider: 'v8',