mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
Merge pull request #13466 from Kilo-Org/investigate-connection-failures-root-cause
fix(vscode): handle fragmented CLI startup output
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"kilo-code": patch
|
||||
---
|
||||
|
||||
Prevent intermittent server connection failures during VS Code startup.
|
||||
@@ -6,7 +6,7 @@ import * as path from "path"
|
||||
import * as vscode from "vscode"
|
||||
import { resolveLocalBwrapEnv, resolveTreeSitterEnv } from "./cli-resources"
|
||||
import { t } from "./i18n"
|
||||
import { parseServerPort } from "./server-utils"
|
||||
import { scanServerPort } from "./server-utils"
|
||||
|
||||
export interface ServerInstance {
|
||||
port: number
|
||||
@@ -15,6 +15,7 @@ export interface ServerInstance {
|
||||
}
|
||||
|
||||
const STARTUP_TIMEOUT_SECONDS = 30
|
||||
const STARTUP_OUTPUT_LIMIT = 1024
|
||||
|
||||
type WorkspaceFolderLike = { uri: { fsPath: string } }
|
||||
type ServerExitListener = (code: number | null, signal: NodeJS.Signals | null) => void
|
||||
@@ -162,13 +163,16 @@ export class ServerManager {
|
||||
console.log("[Kilo New] ServerManager: 📦 Process spawned with PID:", serverProcess.pid)
|
||||
|
||||
let resolved = false
|
||||
let output = ""
|
||||
const stderrLines: string[] = []
|
||||
|
||||
serverProcess.stdout?.on("data", (data: Buffer) => {
|
||||
const output = data.toString()
|
||||
console.log("[Kilo New] ServerManager: 📥 CLI Server stdout:", output)
|
||||
const chunk = data.toString()
|
||||
console.log("[Kilo New] ServerManager: 📥 CLI Server stdout:", chunk)
|
||||
|
||||
const port = parseServerPort(output)
|
||||
const state = scanServerPort(output, chunk, STARTUP_OUTPUT_LIMIT)
|
||||
output = state.output
|
||||
const port = state.port
|
||||
if (port !== null && !resolved) {
|
||||
resolved = true
|
||||
console.log("[Kilo New] ServerManager: 🎯 Port detected:", port)
|
||||
|
||||
@@ -3,8 +3,15 @@
|
||||
* Matches lines like: "kilo server listening on http://127.0.0.1:12345"
|
||||
* Returns the port number or null if not found.
|
||||
*/
|
||||
export function parseServerPort(output: string): number | null {
|
||||
const match = output.match(/listening on http:\/\/[\w.]+:(\d+)/)
|
||||
export function parseServerPort(output: string, complete = false): number | null {
|
||||
const match = output.match(
|
||||
complete ? /listening on http:\/\/[\w.]+:(\d+)\r?\n/ : /listening on http:\/\/[\w.]+:(\d+)/,
|
||||
)
|
||||
if (!match) return null
|
||||
return parseInt(match[1]!, 10)
|
||||
}
|
||||
|
||||
export function scanServerPort(output: string, chunk: string, limit: number) {
|
||||
const text = `${output}${chunk}`
|
||||
return { output: text.slice(-limit), port: parseServerPort(text, true) }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from "bun:test"
|
||||
import { parseServerPort } from "../../src/services/cli-backend/server-utils"
|
||||
import { parseServerPort, scanServerPort } from "../../src/services/cli-backend/server-utils"
|
||||
import {
|
||||
resolveServerCwd,
|
||||
resolveIndexingEnv,
|
||||
@@ -61,6 +61,51 @@ describe("parseServerPort", () => {
|
||||
const output = "listening on http://127.0.0.1:3000 and http://127.0.0.1:4000"
|
||||
expect(parseServerPort(output)).toBe(3000)
|
||||
})
|
||||
|
||||
it("waits for the complete startup line before resolving a split port", () => {
|
||||
const first = "kilo server listening on http://127.0.0.1:43"
|
||||
|
||||
expect(parseServerPort(first, true)).toBeNull()
|
||||
expect(parseServerPort(`${first}123\n`, true)).toBe(43123)
|
||||
})
|
||||
|
||||
it("detects a startup announcement split across stdout chunks", () => {
|
||||
const first = "kilo server listening on http://127.0."
|
||||
const second = "0.1:43123\n"
|
||||
|
||||
expect(parseServerPort(first, true)).toBeNull()
|
||||
expect(parseServerPort(`${first}${second}`, true)).toBe(43123)
|
||||
})
|
||||
|
||||
it("accepts complete Windows startup lines", () => {
|
||||
expect(parseServerPort("kilo server listening on http://127.0.0.1:43123\r\n", true)).toBe(43123)
|
||||
})
|
||||
})
|
||||
|
||||
describe("scanServerPort", () => {
|
||||
it("detects startup announcements split across stdout chunks", () => {
|
||||
const first = scanServerPort("", "kilo server listening on http://127.0.", 1024)
|
||||
const second = scanServerPort(first.output, "0.1:43123\n", 1024)
|
||||
|
||||
expect(first.port).toBeNull()
|
||||
expect(second.port).toBe(43123)
|
||||
})
|
||||
|
||||
it("waits for split port digits before resolving startup", () => {
|
||||
const first = scanServerPort("", "kilo server listening on http://127.0.0.1:43", 1024)
|
||||
const second = scanServerPort(first.output, "123\n", 1024)
|
||||
|
||||
expect(first.port).toBeNull()
|
||||
expect(second.port).toBe(43123)
|
||||
})
|
||||
|
||||
it("preserves startup announcements followed by oversized stdout chunks", () => {
|
||||
const chunk = `kilo server listening on http://127.0.0.1:43123\n${"x".repeat(1024)}`
|
||||
const state = scanServerPort("", chunk, 1024)
|
||||
|
||||
expect(state.port).toBe(43123)
|
||||
expect(state.output).toHaveLength(1024)
|
||||
})
|
||||
})
|
||||
|
||||
describe("cli tree-sitter resources", () => {
|
||||
|
||||
Reference in New Issue
Block a user