feat: add provider ssh bridge

This commit is contained in:
Codex
2026-05-05 01:24:32 +00:00
parent 2d6829ed44
commit f6d0bd1e3b
18 changed files with 1014 additions and 34 deletions
+42 -5
View File
@@ -1,6 +1,13 @@
import { runCommand } from "./command";
import { type UniDeskConfig, repoRoot } from "./config";
export const dispatchCommands = ["docker.ps", "provider.upgrade", "host.ssh", "echo"] as const;
export type DebugDispatchCommand = typeof dispatchCommands[number];
export function isDebugDispatchCommand(value: unknown): value is DebugDispatchCommand {
return dispatchCommands.includes(value as DebugDispatchCommand);
}
async function readJson(url: string, init?: RequestInit): Promise<unknown> {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);
@@ -134,9 +141,39 @@ export async function debugHealth(config: UniDeskConfig): Promise<unknown> {
};
}
export async function debugDispatch(config: UniDeskConfig, providerId: string, command: "docker.ps" | "provider.upgrade" | "echo"): Promise<unknown> {
return coreInternalFetch("/api/dispatch", {
method: "POST",
body: { providerId, command, payload: command === "provider.upgrade" ? { source: "cli-debug", mode: "plan" } : { source: "cli-debug" } },
});
async function waitForTask(taskId: string, timeoutMs: number): Promise<unknown> {
const started = Date.now();
let latest: unknown = null;
while (Date.now() - started < timeoutMs) {
latest = coreInternalFetch("/api/tasks?limit=100");
const tasks = (latest as { body?: { tasks?: Array<{ id?: string; status?: string; result?: unknown }> } }).body?.tasks ?? [];
const task = tasks.find((item) => item.id === taskId);
if (task?.status === "succeeded" || task?.status === "failed") return { ok: true, task };
await Bun.sleep(500);
}
return { ok: false, timeoutMs, latest };
}
export async function debugTask(_config: UniDeskConfig, taskId: string): Promise<unknown> {
const tasksResponse = coreInternalFetch("/api/tasks?limit=100");
const tasks = (tasksResponse as { body?: { tasks?: Array<{ id?: string }> } }).body?.tasks ?? [];
const task = taskId === "latest" ? tasks[0] : tasks.find((item) => item.id === taskId);
return { tasksResponse, taskId, task: task ?? null };
}
export async function debugDispatch(
config: UniDeskConfig,
providerId: string,
command: DebugDispatchCommand,
payload?: Record<string, unknown>,
waitMs = 0,
): Promise<unknown> {
const dispatchPayload = payload ?? (command === "provider.upgrade" ? { source: "cli-debug", mode: "plan" } : { source: "cli-debug" });
const dispatch = coreInternalFetch("/api/dispatch", {
method: "POST",
body: { providerId, command, payload: dispatchPayload },
});
const taskId = (dispatch as { body?: { taskId?: string } }).body?.taskId ?? "";
const wait = waitMs > 0 && taskId.length > 0 ? await waitForTask(taskId, waitMs) : null;
return { dispatch, wait };
}