Restore interactive server terminal drawer

This commit is contained in:
npc0-hue
2026-08-10 23:43:17 +08:00
parent 1207ba6c5b
commit 0154f42485
7 changed files with 410 additions and 83 deletions
+7
View File
@@ -771,6 +771,13 @@ describe("PlatformApiClient AI providers", () => {
});
});
it("builds encoded server log event stream URLs for the terminal drawer", () => {
const client = new PlatformApiClient("/api/v1");
expect(client.serverLogEventsUrl("server/scum 1", { historyLimit: 500 })).toBe("/api/v1/server-instances/server%2Fscum%201/logs/events?historyLimit=500");
expect(client.serverLogEventsUrl("server-1")).toBe("/api/v1/server-instances/server-1/logs/events");
});
it("surfaces password confirmation denials without exposing generic forbidden text", async () => {
vi.stubGlobal("fetch", vi.fn(async () => new Response(JSON.stringify({
code: "forbidden",
+12
View File
@@ -56,6 +56,7 @@ import type {
LlmConfigSuggestionResponse,
LogStreamCursorRequest,
LogStreamCursorResponse,
LogStreamEventOptions,
LogStreamListResponse,
LoginRequest,
MarketplacePluginFilterRequest,
@@ -637,6 +638,17 @@ export class PlatformApiClient {
return this.request<LogStreamListResponse>("/log-streams");
}
openServerLogEvents(id: string, options: LogStreamEventOptions = {}): EventSource {
return new EventSource(this.serverLogEventsUrl(id, options), { withCredentials: true });
}
serverLogEventsUrl(id: string, options: LogStreamEventOptions = {}): string {
const params = new URLSearchParams();
if (options.historyLimit !== undefined) params.set("historyLimit", String(options.historyLimit));
const query = params.toString();
return `${this.baseUrl}/server-instances/${encodeURIComponent(id)}/logs/events${query ? `?${query}` : ""}`;
}
async queryLogStream(request: LogStreamCursorRequest): Promise<LogStreamCursorResponse> {
return this.request<LogStreamCursorResponse>("/log-streams/query", { method: "POST", body: request });
}