mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix: connect resumed native terminals reliably (#107688)
* fix: render resumed paired-node terminals * fix(control-ui): connect native catalog terminals reliably * chore: keep release notes in PR body * fix(control-ui): require terminal reconnect cancellation * fix(gateway): cancel timed-out terminal opens safely * fix(control-ui): recover stalled terminal opens * chore(ui): refresh i18n fallback baseline * fix: preserve login shell path for resumed terminals * refactor(plugin-sdk): avoid extra resolver export * fix(gateway): normalize terminal open failures * test(control-ui): split terminal readiness coverage * docs: explain catalog terminal PATH restoration * fix(control-ui): complete terminal readiness release gates * fix(ci): remove unused shell resolver exports * chore(plugin-sdk): refresh API baseline after rebase
This commit is contained in:
committed by
GitHub
parent
576c209110
commit
57d926b4fd
@@ -1,6 +1,7 @@
|
||||
import { accessSync, constants, statSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { resolveExecutableFromPathEnv } from "openclaw/plugin-sdk/node-host";
|
||||
import type {
|
||||
OpenClawPluginApi,
|
||||
OpenClawPluginNodeHostCommand,
|
||||
@@ -317,7 +318,12 @@ async function listOpenCodeHosts(
|
||||
const requested = query.hostIds ? new Set(query.hostIds) : undefined;
|
||||
const searchTerm = query.search?.trim().slice(0, MAX_SEARCH_LENGTH) || undefined;
|
||||
const hosts: SessionCatalogHost[] = [];
|
||||
if ((!requested || requested.has(LOCAL_HOST_ID)) && executableOnPath("opencode", process.env)) {
|
||||
if (
|
||||
(!requested || requested.has(LOCAL_HOST_ID)) &&
|
||||
resolveExecutableFromPathEnv("opencode", process.env.PATH ?? "", process.env, {
|
||||
fallbackToLoginShell: true,
|
||||
})
|
||||
) {
|
||||
try {
|
||||
hosts.push({
|
||||
hostId: LOCAL_HOST_ID,
|
||||
|
||||
@@ -112,14 +112,20 @@ export async function openOpenCodeCatalogTerminal(
|
||||
const title = `opencode --session ${params.threadId.slice(0, 12)}…`;
|
||||
if (params.hostId === OPENCODE_LOCAL_SESSION_HOST_ID) {
|
||||
const record = await requireLocalOpenCodeSession(params.threadId);
|
||||
const executable = resolveExecutableFromPathEnv("opencode", process.env.PATH ?? "");
|
||||
if (!executable) {
|
||||
const resolution = resolveExecutableFromPathEnv(
|
||||
"opencode",
|
||||
process.env.PATH ?? "",
|
||||
process.env,
|
||||
{ fallbackToLoginShell: true, withPathEnv: true },
|
||||
);
|
||||
if (!resolution) {
|
||||
throw new Error("OpenCode CLI is unavailable");
|
||||
}
|
||||
return {
|
||||
kind: "local",
|
||||
argv: [executable, "--session", params.threadId],
|
||||
argv: [resolution.executable, "--session", params.threadId],
|
||||
...(record.cwd ? { cwd: record.cwd } : {}),
|
||||
...(resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {}),
|
||||
title,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,19 @@ const nodeHostMocks = vi.hoisted(() => ({
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/node-host", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/node-host")>();
|
||||
return { ...actual, runNodePtyCommand: nodeHostMocks.runNodePtyCommand };
|
||||
return {
|
||||
...actual,
|
||||
runNodePtyCommand: nodeHostMocks.runNodePtyCommand,
|
||||
resolveExecutableFromPathEnv: (
|
||||
command: string,
|
||||
pathEnv: string,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
options?: { withPathEnv?: boolean },
|
||||
) =>
|
||||
options?.withPathEnv
|
||||
? actual.resolveExecutableFromPathEnv(command, pathEnv, env, { withPathEnv: true })
|
||||
: actual.resolveExecutableFromPathEnv(command, pathEnv, env),
|
||||
};
|
||||
});
|
||||
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user