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
16 changes: 8 additions & 8 deletions packages/altimate-code/src/bridge/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export async function ensureUv(): Promise<void> {
// Extract: tar.gz on unix, zip on windows
if (asset.endsWith(".tar.gz")) {
// Use tar to extract, the binary is inside a directory named like "uv-aarch64-apple-darwin"
execFileSync("tar", ["-xzf", tmpFile, "-C", path.join(dir, "bin")])
execFileSync("tar", ["-xzf", tmpFile, "-C", path.join(dir, "bin")], { stdio: "pipe" })
// The extracted dir has the same name as the asset minus .tar.gz
const extractedDir = path.join(dir, "bin", asset.replace(".tar.gz", ""))
// Move uv binary from extracted dir to engine/bin/uv
Expand All @@ -126,7 +126,7 @@ export async function ensureUv(): Promise<void> {
execFileSync("powershell", [
"-Command",
`Expand-Archive -Path '${tmpFile}' -DestinationPath '${path.join(dir, "bin")}' -Force`,
])
], { stdio: "pipe" })
const extractedDir = path.join(dir, "bin", asset.replace(".zip", ""))
await fs.rename(path.join(extractedDir, "uv.exe"), uv)
await fs.rm(extractedDir, { recursive: true, force: true })
Expand Down Expand Up @@ -172,14 +172,14 @@ async function ensureEngineImpl(): Promise<void> {
if (!existsSync(venvDir)) {
UI.println(`${UI.Style.TEXT_DIM}Creating Python environment...${UI.Style.TEXT_NORMAL}`)
try {
execFileSync(uv, ["venv", "--python", "3.12", venvDir])
execFileSync(uv, ["venv", "--python", "3.12", venvDir], { stdio: "pipe" })
} catch (e: any) {
Telemetry.track({
type: "engine_error",
timestamp: Date.now(),
session_id: Telemetry.getContext().sessionId,
phase: "venv_create",
error_message: (e?.message ?? String(e)).slice(0, 500),
error_message: (e?.stderr?.toString() || e?.message ?? String(e)).slice(0, 500),
})
throw e
}
Expand All @@ -189,22 +189,22 @@ async function ensureEngineImpl(): Promise<void> {
const pythonPath = enginePythonPath()
UI.println(`${UI.Style.TEXT_DIM}Installing altimate-engine ${ALTIMATE_ENGINE_VERSION}...${UI.Style.TEXT_NORMAL}`)
try {
execFileSync(uv, ["pip", "install", "--python", pythonPath, `altimate-engine==${ALTIMATE_ENGINE_VERSION}`])
execFileSync(uv, ["pip", "install", "--python", pythonPath, `altimate-engine==${ALTIMATE_ENGINE_VERSION}`], { stdio: "pipe" })
} catch (e: any) {
Telemetry.track({
type: "engine_error",
timestamp: Date.now(),
session_id: Telemetry.getContext().sessionId,
phase: "pip_install",
error_message: (e?.message ?? String(e)).slice(0, 500),
error_message: (e?.stderr?.toString() || e?.message ?? String(e)).slice(0, 500),
})
throw e
}

// Get python version
const pyVersion = execFileSync(pythonPath, ["--version"]).toString().trim()
const pyVersion = execFileSync(pythonPath, ["--version"], { stdio: "pipe" }).toString().trim()
// Get uv version
const uvVersion = execFileSync(uv, ["--version"]).toString().trim()
const uvVersion = execFileSync(uv, ["--version"], { stdio: "pipe" }).toString().trim()

await writeManifest({
engine_version: ALTIMATE_ENGINE_VERSION,
Expand Down
2 changes: 1 addition & 1 deletion packages/altimate-code/src/cli/cmd/tui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ function App() {
title: "Open docs",
value: "docs.open",
onSelect: () => {
open("https://altimate-code.dev/docs").catch(() => {})
open("https://crispy-adventure-6lj1ey3.pages.github.io/").catch(() => {})
dialog.clear()
},
category: "System",
Expand Down
129 changes: 129 additions & 0 deletions packages/altimate-code/test/bridge/engine.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**
* E2E tests verifying that execFileSync with { stdio: "pipe" } prevents
* subprocess output from leaking to the parent's stdout/stderr.
*
* These are real tests — they spawn actual child processes running real
* commands and verify the captured output is clean.
*/

import { describe, expect, test } from "bun:test"
import { execFileSync, spawnSync } from "child_process"
import path from "path"
import os from "os"
import fsp from "fs/promises"

describe("execFileSync stdio piping behavior", () => {
test("stdio: 'pipe' prevents subprocess stdout from reaching parent", () => {
// Run a child process that calls execFileSync with stdio: "pipe"
// and verify the parent sees nothing on stdout/stderr
const result = spawnSync("bun", ["-e", `
const { execFileSync } = require("child_process");
execFileSync("echo", ["THIS_SHOULD_NOT_LEAK"], { stdio: "pipe" });
execFileSync("echo", ["ALSO_SHOULD_NOT_LEAK"], { stdio: "pipe" });
`], { encoding: "utf-8" })

expect(result.stdout).not.toContain("THIS_SHOULD_NOT_LEAK")
expect(result.stdout).not.toContain("ALSO_SHOULD_NOT_LEAK")
expect(result.stderr).not.toContain("THIS_SHOULD_NOT_LEAK")
expect(result.stderr).not.toContain("ALSO_SHOULD_NOT_LEAK")
})

test("without stdio: 'pipe', subprocess output DOES leak to parent", () => {
// Control test: prove that without stdio: "pipe", output leaks through
const result = spawnSync("bun", ["-e", `
const { execFileSync } = require("child_process");
execFileSync("echo", ["CONTROL_LEAKED"], { stdio: "inherit" });
`], { encoding: "utf-8" })

// With stdio: "inherit", the child's subprocess output goes to the
// child's stdout, which the parent captures
expect(result.stdout).toContain("CONTROL_LEAKED")
})

test("stdio: 'pipe' still captures the return value", () => {
// Verify that piped output is available as the return value
const output = execFileSync("echo", ["captured_value"], { stdio: "pipe" })
expect(output.toString().trim()).toBe("captured_value")
})
})

describe("engine.ts subprocess noise suppression", () => {
test("commands matching engine.ts patterns don't leak output when piped", () => {
// Run a child process that mimics the exact execFileSync patterns in
// engine.ts: version checks, tar, and noisy commands — all with
// stdio: "pipe". Verify no output leaks.
const script = `
const { execFileSync } = require("child_process");

// Mimics: execFileSync(pythonPath, ["--version"], { stdio: "pipe" })
try { execFileSync("python3", ["--version"], { stdio: "pipe" }); } catch {}

// Mimics: execFileSync("tar", ["--version"], { stdio: "pipe" })
try { execFileSync("tar", ["--version"], { stdio: "pipe" }); } catch {}

// Mimics: execFileSync(uv, ["--version"], { stdio: "pipe" })
// Use a command that prints to both stdout and stderr
try { execFileSync("ls", ["--version"], { stdio: "pipe" }); } catch {}

// Simulate noisy pip-like output
try { execFileSync("echo", ["Collecting altimate-engine==0.1.0\\nInstalling collected packages\\nSuccessfully installed"], { stdio: "pipe" }); } catch {}
`
const result = spawnSync("bun", ["-e", script], { encoding: "utf-8" })

// None of the subprocess output should appear in the parent's streams
expect(result.stdout).not.toContain("Python")
expect(result.stdout).not.toContain("tar")
expect(result.stdout).not.toContain("Collecting")
expect(result.stdout).not.toContain("Installing")
expect(result.stderr).not.toContain("Python")
expect(result.stderr).not.toContain("Collecting")
})

test("same commands WITHOUT piping DO leak output (control)", () => {
// Control: verify the same commands actually produce output when not piped
const result = spawnSync("bun", ["-e", `
const { execFileSync } = require("child_process");
try { execFileSync("python3", ["--version"], { stdio: "inherit" }); } catch {}
`], { encoding: "utf-8" })

expect(result.stdout).toContain("Python")
})

test("engine.ts uses stdio: 'pipe' on all execFileSync calls", async () => {
// Read the actual source and verify every execFileSync call site
// includes { stdio: "pipe" } — this ensures the behavior tested above
// is actually applied in the production code
const engineSrc = path.resolve(
__dirname,
"../../src/bridge/engine.ts",
)
const source = await fsp.readFile(engineSrc, "utf-8")
const lines = source.split("\n")

// Find every execFileSync call and extract the full multi-line expression
const callSites: { line: number; text: string }[] = []
for (let i = 0; i < lines.length; i++) {
if (!lines[i].includes("execFileSync(")) continue

let text = ""
let depth = 0
for (let j = i; j < lines.length; j++) {
text += lines[j] + "\n"
for (const ch of lines[j]) {
if (ch === "(") depth++
if (ch === ")") depth--
}
if (depth <= 0) break
}
callSites.push({ line: i + 1, text })
}

// engine.ts has 6 execFileSync calls:
// tar, powershell, uv venv, uv pip install, python --version, uv --version
expect(callSites.length).toBeGreaterThanOrEqual(6)

for (const site of callSites) {
expect(site.text).toContain('stdio: "pipe"')
}
})
})
Loading