Files
openclaw-zero-token/commands/gateway-status/discovery.ts
sjhu 571e14a236 feat: upgrade to upstream v2026.3.28
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
2026-03-30 17:58:12 +08:00

103 lines
2.8 KiB
TypeScript

import type { GatewayBonjourBeacon } from "../../infra/bonjour-discovery.js";
import {
buildGatewayDiscoveryTarget,
serializeGatewayDiscoveryBeacon,
} from "../../infra/gateway-discovery-targets.js";
export function inferSshTargetFromRemoteUrl(rawUrl?: string | null): string | null {
if (typeof rawUrl !== "string") {
return null;
}
const trimmed = rawUrl.trim();
if (!trimmed) {
return null;
}
let host: string | null = null;
try {
host = new URL(trimmed).hostname || null;
} catch {
return null;
}
if (!host) {
return null;
}
const user = process.env.USER?.trim() || "";
return user ? `${user}@${host}` : host;
}
export function buildSshTarget(input: {
user?: string;
host?: string;
port?: number;
}): string | null {
const host = input.host?.trim() ?? "";
if (!host) {
return null;
}
const user = input.user?.trim() ?? "";
const base = user ? `${user}@${host}` : host;
const port = input.port ?? 22;
if (port && port !== 22) {
return `${base}:${port}`;
}
return base;
}
export async function resolveSshTarget(params: {
rawTarget: string;
identity: string | null;
overallTimeoutMs: number;
loadSshConfigModule: () => Promise<typeof import("../../infra/ssh-config.js")>;
loadSshTunnelModule: () => Promise<typeof import("../../infra/ssh-tunnel.js")>;
}): Promise<{ target: string; identity?: string } | null> {
const [{ resolveSshConfig }, { parseSshTarget }] = await Promise.all([
params.loadSshConfigModule(),
params.loadSshTunnelModule(),
]);
const parsed = parseSshTarget(params.rawTarget);
if (!parsed) {
return null;
}
const config = await resolveSshConfig(parsed, {
identity: params.identity ?? undefined,
timeoutMs: Math.min(800, params.overallTimeoutMs),
});
if (!config) {
return { target: params.rawTarget, identity: params.identity ?? undefined };
}
const target = buildSshTarget({
user: config.user ?? parsed.user,
host: config.host ?? parsed.host,
port: config.port ?? parsed.port,
});
if (!target) {
return { target: params.rawTarget, identity: params.identity ?? undefined };
}
const identityFile =
params.identity ??
config.identityFiles.find((entry) => entry.trim().length > 0)?.trim() ??
undefined;
return { target, identity: identityFile };
}
export function pickAutoSshTargetFromDiscovery(params: {
discovery: GatewayBonjourBeacon[];
parseSshTarget: (target: string) => unknown;
sshUser?: string | null;
}): string | null {
for (const beacon of params.discovery) {
const sshTarget = buildGatewayDiscoveryTarget(beacon, {
sshUser: params.sshUser ?? undefined,
}).sshTarget;
if (!sshTarget) {
continue;
}
if (params.parseSshTarget(sshTarget)) {
return sshTarget;
}
}
return null;
}
export { serializeGatewayDiscoveryBeacon };