From e332b9f1d5f66f4f5c86da8774c73e393a3b5893 Mon Sep 17 00:00:00 2001 From: Martin Laporte Date: Mon, 13 Apr 2026 08:45:39 +0200 Subject: [PATCH 1/2] Make bunx available in the sandbox --- src/cli/default-dockerfile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cli/default-dockerfile.ts b/src/cli/default-dockerfile.ts index 4d26fb9..76239f3 100644 --- a/src/cli/default-dockerfile.ts +++ b/src/cli/default-dockerfile.ts @@ -44,7 +44,8 @@ RUN curl -fsSL https://gh.io/copilot-install | bash # Bun RUN curl -fsSL https://bun.sh/install | bash \ - && ln -sf /root/.bun/bin/bun /usr/local/bin/bun + && ln -sf /root/.bun/bin/bun /usr/local/bin/bun \ + && ln -sf /root/.bun/bin/bunx /usr/local/bin/bunx # uv (Python package manager) RUN curl -LsSf https://astral.sh/uv/install.sh | sh \ From 786cc309b233e8e8d94f1a6a1cdaccdadf3a8ea4 Mon Sep 17 00:00:00 2001 From: Martin Laporte Date: Mon, 13 Apr 2026 08:50:28 +0200 Subject: [PATCH 2/2] fix: auto-start gpg-agent when socket is missing at sandbox start --- src/cli/sandbox.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cli/sandbox.ts b/src/cli/sandbox.ts index 92a39af..9afb306 100644 --- a/src/cli/sandbox.ts +++ b/src/cli/sandbox.ts @@ -877,6 +877,8 @@ export const __test__ = { } export function resolveGpgSocketInfo(containerHome: string): GpgSocketInfo | null { + let agentStartAttempted = false + for (const dir of ['agent-extra-socket', 'agent-socket'] as const) { try { const result = spawnSync('gpgconf', ['--list-dirs', dir], { @@ -885,7 +887,27 @@ export function resolveGpgSocketInfo(containerHome: string): GpgSocketInfo | nul stdio: ['ignore', 'pipe', 'ignore'], }) const hostSocket = result.stdout?.trim() - if (result.status !== 0 || !hostSocket || !fs.existsSync(hostSocket)) continue + if (result.status !== 0 || !hostSocket) continue + + if (!fs.existsSync(hostSocket)) { + // Socket path is known but agent isn't running yet — start it once. + if (!agentStartAttempted) { + agentStartAttempted = true + spawnSync('gpg-agent', ['--daemon'], { + encoding: 'utf-8', + timeout: 5_000, + stdio: ['ignore', 'ignore', 'ignore'], + }) + process.stderr.write('pippin: started gpg-agent\n') + } + // Give the agent a moment to create its socket, then re-check. + // Use a tight retry loop (up to ~500 ms) to stay synchronous. + const deadline = Date.now() + 500 + while (!fs.existsSync(hostSocket) && Date.now() < deadline) { + Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50) + } + if (!fs.existsSync(hostSocket)) continue + } return { hostSocket,