Merge pull request #13474 from Kilo-Org/fix-prerelease-pty-smoke

fix(cli): stabilize packaged PTY smoke test
This commit is contained in:
Marius
2026-08-26 16:21:22 +02:00
committed by GitHub
3 changed files with 44 additions and 4 deletions
+16 -3
View File
@@ -3,6 +3,16 @@ import { KiloPtyTermination } from "./termination"
import { spawn } from "#pty"
const TIMEOUT = 15_000
const RENDER_TIMEOUT = 60_000
export function marker(output: string) {
const text = output
.replace(/\x1b\](?:[^\x07\x1b]|\x1b(?!\\))*(?:\x07|\x1b\\)/g, "")
.replace(/\x1b[P^_](?:[^\x1b]|\x1b(?!\\))*\x1b\\/g, "")
.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "")
.replace(/\x1b[@-_]/g, "")
return text.split(/\r?\n/).some((line) => line.trim() === "KILO_PTY_READY")
}
async function render() {
const proc = spawn(process.execPath, ["--pure"], {
@@ -34,7 +44,7 @@ async function render() {
state.exited = true
ready.reject(new Error(`TUI exited before rendering (code ${event.exitCode}): ${JSON.stringify(state.output)}`))
})
const timeout = AbortSignal.timeout(TIMEOUT)
const timeout = AbortSignal.timeout(RENDER_TIMEOUT)
try {
await Promise.race([
@@ -42,7 +52,10 @@ async function render() {
new Promise<never>((_, reject) =>
timeout.addEventListener(
"abort",
() => reject(new Error(`TUI produced no rendered frame within ${TIMEOUT}ms: ${JSON.stringify(state.output)}`)),
() =>
reject(
new Error(`TUI produced no rendered frame within ${RENDER_TIMEOUT}ms: ${JSON.stringify(state.output)}`),
),
{ once: true },
),
),
@@ -67,7 +80,7 @@ export async function smoke() {
const exited = Promise.withResolvers<number>()
const data = proc.onData((chunk) => {
state.output += chunk
if (/(?:^|[\r\n])KILO_PTY_READY(?:\r?\n|$)/.test(state.output)) output.resolve()
if (marker(state.output)) output.resolve()
})
const exit = proc.onExit((event) => {
state.exited = true
@@ -183,7 +183,13 @@ describe("durable PTY registry", () => {
const info = yield* Effect.scoped(
Effect.gen(function* () {
const pty = yield* Pty.Service
return yield* pty.create({ command: "/bin/sh", args: ["-c", "exit 7"], cwd: dir.path })
return yield* pty.create({ command: "/bin/sh", cwd: dir.path })
}).pipe(Effect.provide(locations.get(target))),
)
yield* Effect.scoped(
Effect.gen(function* () {
const pty = yield* Pty.Service
yield* pty.write(info.id, "exit 7\r")
}).pipe(Effect.provide(locations.get(target))),
)
const exited = yield* Queue.take(queue).pipe(Effect.timeout("5 seconds"))
@@ -0,0 +1,21 @@
import { describe, expect, test } from "bun:test"
import { marker } from "../../src/kilocode/pty/smoke"
describe("PTY smoke output", () => {
test("detects a marker after PowerShell formatting", () => {
const output =
"\x1b[93mecho KILO_PTY_READY\r\n\x1b[mKILO_PTY_READY\r\n\x1b]0;Administrator: PowerShell\x07PS> "
expect(marker(output)).toBe(true)
})
test("does not accept the echoed command", () => {
expect(marker("\x1b[93mecho KILO_PTY_READY\r\n\x1b[mPS> ")).toBe(false)
})
test("detects a marker around OSC and DCS sequences", () => {
const output = "\x1b]133;A\x07\x1bP+q4d73\x1b\\KILO_PTY_READY\r\n"
expect(marker(output)).toBe(true)
})
})