From cd1699fcdafaa422be9fa88e8d641f2b5e40abfe Mon Sep 17 00:00:00 2001 From: mkorwel Date: Fri, 13 Mar 2026 19:56:52 -0700 Subject: [PATCH] feat(offload): remove browser opener and make review-pr actionable --- .gemini/settings.json | 12 ++++++++++- .gemini/skills/offload/policy.toml | 5 ++++- .../skills/offload/scripts/orchestrator.ts | 3 +-- .gemini/skills/offload/scripts/setup.ts | 21 ++++++++++++------- .gemini/skills/review-pr/SKILL.md | 10 ++++++++- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/.gemini/settings.json b/.gemini/settings.json index 1a4c889066..77c4dab255 100644 --- a/.gemini/settings.json +++ b/.gemini/settings.json @@ -6,5 +6,15 @@ }, "general": { "devtools": true + }, + "maintainer": { + "deepReview": { + "remoteHost": "cli", + "remoteWorkDir": "~/.offload/workspace", + "terminalType": "iterm2", + "syncAuth": true, + "geminiSetup": "isolated", + "ghSetup": "isolated" + } } -} +} \ No newline at end of file diff --git a/.gemini/skills/offload/policy.toml b/.gemini/skills/offload/policy.toml index e0c4e8f54a..6d29bb9441 100644 --- a/.gemini/skills/offload/policy.toml +++ b/.gemini/skills/offload/policy.toml @@ -58,6 +58,7 @@ name = "pr-address-comments" toolName = "run_shell_command" commandPrefix = [ "git checkout", + "git merge", "git blame", "git show", "git grep", @@ -82,10 +83,12 @@ commandPrefix = [ decision = "allow" priority = 100 -# GitHub CLI (Read-only) +# GitHub CLI (State Changing & Read-only) [[rule]] toolName = "run_shell_command" commandPrefix = [ + "gh pr review", + "gh pr comment", "gh workflow list", "gh auth status", "gh checkout view", diff --git a/.gemini/skills/offload/scripts/orchestrator.ts b/.gemini/skills/offload/scripts/orchestrator.ts index f48ebab184..9b8cc23d7c 100644 --- a/.gemini/skills/offload/scripts/orchestrator.ts +++ b/.gemini/skills/offload/scripts/orchestrator.ts @@ -79,8 +79,7 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p // 3. 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/offload/scripts/entrypoint.ts ${prNumber} ${branchName} ${remotePolicyPath} ${action}`; + const remoteWorker = `export GEMINI_CLI_HOME=${ISOLATED_GEMINI} && export GH_CONFIG_DIR=${ISOLATED_GH} && ./node_modules/.bin/tsx .gemini/skills/offload/scripts/entrypoint.ts ${prNumber} ${branchName} ${remotePolicyPath} ${action}`; 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)}`; diff --git a/.gemini/skills/offload/scripts/setup.ts b/.gemini/skills/offload/scripts/setup.ts index 3b2248be2b..13f3c87de0 100644 --- a/.gemini/skills/offload/scripts/setup.ts +++ b/.gemini/skills/offload/scripts/setup.ts @@ -33,10 +33,11 @@ async function confirm(question: string): Promise { } export async function runSetup(env: NodeJS.ProcessEnv = process.env) { - console.log('\n🌟 Initializing Deep Review Skill Settings...'); - + console.log('\n🌟 Initializing Offload Skill Settings...'); + + const OFFLOAD_BASE = '~/.offload'; const remoteHost = await prompt('Remote SSH Host', 'cli'); - const remoteWorkDir = await prompt('Remote Work Directory', '~/gcli/deepreview'); + const remoteWorkDir = await prompt('Remote Work Directory', `${OFFLOAD_BASE}/workspace`); console.log(`šŸ” Checking state of ${remoteHost}...`); @@ -48,8 +49,8 @@ export async function runSetup(env: NodeJS.ProcessEnv = process.env) { const ghChoice = await prompt('GitHub CLI Setup: Use [p]re-existing instance or [i]solated sandbox instance? (Isolated is recommended)', 'i'); const ghSetup = ghChoice.toLowerCase() === 'p' ? 'preexisting' : 'isolated'; - const ISOLATED_GEMINI_CONFIG = '~/.offload/gemini-cli-config'; - const ISOLATED_GH_CONFIG = '~/.offload/gh-cli-config'; + const ISOLATED_GEMINI_CONFIG = `${OFFLOAD_BASE}/gemini-cli-config`; + const ISOLATED_GH_CONFIG = `${OFFLOAD_BASE}/gh-cli-config`; console.log(`šŸ” Checking state of ${remoteHost}...`); // Use a login shell to ensure the same PATH as the interactive user @@ -102,12 +103,16 @@ export async function runSetup(env: NodeJS.ProcessEnv = process.env) { const globalGHAuth = spawnSync('ssh', [remoteHost, 'sh -lc "gh auth status"'], { stdio: 'pipe' }); if (globalGHAuth.status === 0) { if (await confirm(' Global GH auth found. Sync it to isolated instance?')) { - spawnSync('ssh', [remoteHost, `cp -r ~/.config/gh/* ${ISOLATED_GH_CONFIG}/`]); - console.log(' āœ… GH Auth synced.'); + spawnSync('ssh', [remoteHost, `mkdir -p ${ISOLATED_GH_CONFIG} && cp -r ~/.config/gh/* ${ISOLATED_GH_CONFIG}/`]); + const verifySync = spawnSync('ssh', [remoteHost, `sh -lc "export GH_CONFIG_DIR=${ISOLATED_GH_CONFIG} && gh auth status"`], { stdio: 'pipe' }); + if (verifySync.status === 0) { + console.log(' āœ… GitHub CLI successfully authenticated via sync.'); + return; // Skip the "may need to login" message + } } } } - if (!isGHAuthRemote) console.log(' You may need to run "gh auth login" on the remote machine later.'); + console.log(' āš ļø GitHub CLI is not yet authenticated. You may need to run "gh auth login" on the remote machine later.'); } // Gemini Auth Check diff --git a/.gemini/skills/review-pr/SKILL.md b/.gemini/skills/review-pr/SKILL.md index ff825b82b9..a6d82bffa2 100644 --- a/.gemini/skills/review-pr/SKILL.md +++ b/.gemini/skills/review-pr/SKILL.md @@ -46,12 +46,20 @@ The agent must follow these steps to conduct the review: ## Final Assessment -Provide a final recommendation with three sections: +Provide a final recommendation with four sections: 1. **Summary**: High-level verdict (Approve / Needs Work / Reject). 2. **Verified Behavior**: Describe the scripts/commands you ran to prove the feature works. 3. **Findings**: List Critical issues, Improvements, and Nitpicks. +4. **Actionable URL**: Explicitly print the PR URL: `gh pr view --web`. + +### Approval Protocol + +After presenting the synthesis, the agent MUST determine the all-up recommendation and ask the user for confirmation: + +* "Based on the verification, I recommend **[APPROVE / COMMENT / REJECT]**. Would you like me to post this review to GitHub?" +* If the user agrees, execute the appropriate `gh pr review` command (e.g., `gh pr review --approve --body ""`). ## Best Practices - **Be Skeptical**: Just because CI is green doesn't mean the feature is complete. Look for missing edge cases.