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
5 changes: 5 additions & 0 deletions packages/gui-extensions/src/wsl/runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ test("parseDiscoveredCli returns the discovered path, not a login-shell banner l
expect(parseDiscoveredCli("")).toBeNull()
expect(parseDiscoveredCli("Welcome to Ubuntu 24.04 LTS\n")).toBeNull()
expect(parseDiscoveredCli("opencode\n")).toBeNull()
// A banner line can itself be an absolute path to an `opencode` binary; the script's own
// line comes after any banner, so the last path-shaped line is the discovered one.
expect(parseDiscoveredCli("/opt/old-opencode/bin/opencode\n/home/user/.opencode/bin/opencode\n")).toBe(
"/home/user/.opencode/bin/opencode",
)
})

// Runs the real discoverScript through `sh` against a fake installed CLI,
Expand Down
8 changes: 5 additions & 3 deletions packages/gui-extensions/src/wsl/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@ export function parseProbeAnswer(output: string) {

export function parseDiscoveredCli(output: string) {
// Discovery runs in a login shell (`sh -lc`), so a banner, MOTD or profile echo can precede
// the discovered path on stdout. The script prints only the CLI's absolute path, so take the
// line that is an absolute path to an `opencode` binary instead of the first line.
// the discovered path on stdout, and a banner line can itself be an absolute path to an
// `opencode` binary. The script prints only the CLI's absolute path, after any banner, so
// take the last line that is an absolute path to an `opencode` binary instead of the first
// matching line — the same last-candidate rule parseVersion and parseProbeAnswer follow.
return (
output
.split(/\r?\n/g)
.map((line) => line.trim())
.find((line) => line.startsWith("/") && line.endsWith("/opencode")) ?? null
.findLast((line) => line.startsWith("/") && line.endsWith("/opencode")) ?? null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Frame discovery output instead of trusting the last match

When a login profile registers an EXIT trap or starts a background job that later prints a path ending in /opencode, that output arrives after discoverScript() prints the real CLI path, so findLast now returns the profile's path and resolveCli attempts to launch the wrong executable. The previous find selected the real path in this ordering; frame the discovery result with unique markers as versionScript already does, and cover trailing profile output in the parser test.

AGENTS.md reference: packages/gui-extensions/AGENTS.md:L100-L100

Useful? React with 👍 / 👎.

)
}

Expand Down