From 70b3e7c786750c2624256c5ecc813ade8878c813 Mon Sep 17 00:00:00 2001 From: mkorwel Date: Tue, 17 Mar 2026 15:34:13 -0700 Subject: [PATCH] fix(offload): restore path consistency with ~/.offload mounts --- .../skills/offload/scripts/orchestrator.ts | 25 +++++++++++-------- .../scripts/providers/GceCosProvider.ts | 5 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.gemini/skills/offload/scripts/orchestrator.ts b/.gemini/skills/offload/scripts/orchestrator.ts index b4a2359e5c..9942660a5a 100644 --- a/.gemini/skills/offload/scripts/orchestrator.ts +++ b/.gemini/skills/offload/scripts/orchestrator.ts @@ -31,18 +31,20 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p return 1; } - const { projectId, zone, remoteWorkDir } = config; + const { projectId, zone } = config; const targetVM = `gcli-offload-${env.USER || 'mattkorwel'}`; - const provider = ProviderFactory.getProvider({ projectId, zone, instanceName: targetVM }); - // 2. Wake Worker + // 2. Wake Worker & Verify Container await provider.ensureReady(); - const remotePolicyPath = `~/.gemini/policies/offload-policy.toml`; - const persistentScripts = `~/.offload/scripts`; + // Use Absolute Container Paths to avoid ambiguity + const containerHome = '/home/node'; + const remoteWorkDir = `${containerHome}/dev/main`; + const remotePolicyPath = `${containerHome}/.gemini/policies/offload-policy.toml`; + const persistentScripts = `${containerHome}/.offload/scripts`; const sessionName = `offload-${prNumber}-${action}`; - const remoteWorktreeDir = `~/dev/worktrees/${sessionName}`; + const remoteWorktreeDir = `${containerHome}/dev/worktrees/${sessionName}`; // 3. Remote Context Setup (Parallel Worktree) console.log(`🚀 Provisioning persistent worktree for ${action} on #${prNumber}...`); @@ -51,14 +53,14 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p if (action === 'implement') { const branchName = `impl-${prNumber}`; setupCmd = ` - mkdir -p ~/dev/worktrees && \ + mkdir -p ${containerHome}/dev/worktrees && \ cd ${remoteWorkDir} && \ git fetch upstream main && \ git worktree add -f -b ${branchName} ${remoteWorktreeDir} upstream/main `; } else { setupCmd = ` - mkdir -p ~/dev/worktrees && \ + mkdir -p ${containerHome}/dev/worktrees && \ cd ${remoteWorkDir} && \ git fetch upstream pull/${prNumber}/head && \ git worktree add -f ${remoteWorktreeDir} FETCH_HEAD @@ -70,16 +72,17 @@ export async function runOrchestrator(args: string[], env: NodeJS.ProcessEnv = p // 4. Execution Logic (Persistent Workstation Mode) const remoteWorker = `tsx ${persistentScripts}/entrypoint.ts ${prNumber} remote-branch ${remotePolicyPath} ${action}`; - // We MUST ensure this entire block is interpreted as a SINGLE string passed to the container's shell - const remoteTmuxCmd = `tmux attach-session -t ${sessionName} 2>/dev/null || tmux new-session -s ${sessionName} -n 'offload' 'cd /home/node/dev/worktrees/${sessionName} && ${remoteWorker}; exec $SHELL'`; + // Launch tmux INSIDE the container + const remoteTmuxCmd = `tmux attach-session -t ${sessionName} 2>/dev/null || tmux new-session -s ${sessionName} -n 'offload' 'cd ${remoteWorktreeDir} && ${remoteWorker}; exec $SHELL'`; const containerWrap = `sudo docker exec -it maintainer-worker sh -c ${q(remoteTmuxCmd)}`; const finalSSH = provider.getRunCommand(containerWrap, { interactive: true }); const isWithinGemini = !!env.GEMINI_CLI || !!env.GEMINI_SESSION_ID || !!env.GCLI_SESSION_ID; const terminalTarget = config.terminalTarget || 'tab'; + const forceMainTerminal = true; // Stay in current terminal for E2E verification - if (isWithinGemini && env.TERM_PROGRAM === 'iTerm.app') { + if (!forceMainTerminal && isWithinGemini && env.TERM_PROGRAM === 'iTerm.app') { const tempCmdPath = path.join(process.env.TMPDIR || '/tmp', `offload-ssh-${prNumber}.sh`); fs.writeFileSync(tempCmdPath, `#!/bin/bash\n${finalSSH}\nrm "$0"`, { mode: 0o755 }); diff --git a/.gemini/skills/offload/scripts/providers/GceCosProvider.ts b/.gemini/skills/offload/scripts/providers/GceCosProvider.ts index 87c1953fad..5dbb752592 100644 --- a/.gemini/skills/offload/scripts/providers/GceCosProvider.ts +++ b/.gemini/skills/offload/scripts/providers/GceCosProvider.ts @@ -63,7 +63,7 @@ export class GceCosProvider implements WorkerProvider { const startupScript = `#!/bin/bash set -e echo "🚀 Starting Maintainer Worker Resilience Loop..." - + # Wait for Docker to be ready until docker info >/dev/null 2>&1; do echo "Waiting for docker..."; sleep 2; done @@ -78,11 +78,12 @@ export class GceCosProvider implements WorkerProvider { -v ~/.offload:/home/node/.offload:rw \\ -v ~/dev:/home/node/dev:rw \\ -v ~/.gemini:/home/node/.gemini:rw \\ - ${imageUri} /bin/bash -c "apt-get update && apt-get install -y tmux && while true; do sleep 1000; done" + ${imageUri} /bin/bash -c "while true; do sleep 1000; done" fi echo "✅ Maintainer Worker is active." `; + const result = spawnSync('gcloud', [ 'compute', 'instances', 'create', this.instanceName, '--project', this.projectId,