@rynx-ai/server 0.1.0 → 0.1.10-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-surface-control-queue.d.ts +42 -0
- package/dist/browser-surface-control-queue.js +187 -0
- package/dist/browser-surface-ws.d.ts +16 -0
- package/dist/browser-surface-ws.js +356 -0
- package/dist/control-api.d.ts +76 -4
- package/dist/control-api.js +3014 -133
- package/dist/control-web/assets/highlighted-body-OFNGDK62-DHu2g-rk.js +1 -0
- package/dist/control-web/assets/index-B6Pb5j9M.js +666 -0
- package/dist/control-web/assets/index-BU-_Qud_.css +32 -0
- package/dist/control-web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/control-web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/control-web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/control-web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/control-web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/control-web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/control-web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/control-web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-CSYzOmBR.js +131 -0
- package/dist/control-web/assets/rynx-wordmark-LL1QRYHD.png +0 -0
- package/dist/control-web/favicon.png +0 -0
- package/dist/control-web/favicon.svg +38 -0
- package/dist/control-web/index.html +16 -0
- package/dist/control-web-dist.d.ts +1 -1
- package/dist/control-web-dist.js +19 -14
- package/dist/desktop-browser-host.d.ts +170 -0
- package/dist/desktop-browser-host.js +1018 -0
- package/dist/direct-runtime-browser-inspect-server.d.ts +72 -0
- package/dist/direct-runtime-browser-inspect-server.js +749 -0
- package/dist/direct-runtime-browser-surface-server.d.ts +74 -0
- package/dist/direct-runtime-browser-surface-server.js +821 -0
- package/dist/direct-runtime-server.d.ts +143 -0
- package/dist/direct-runtime-server.js +1959 -0
- package/dist/emulator-surface-ws.d.ts +8 -0
- package/dist/emulator-surface-ws.js +198 -0
- package/dist/machine-session-service.d.ts +265 -0
- package/dist/machine-session-service.js +822 -0
- package/dist/provider-cli-host.d.ts +10 -0
- package/dist/provider-cli-host.js +1 -0
- package/dist/remote-runtime-dispatcher.d.ts +94 -0
- package/dist/remote-runtime-dispatcher.js +403 -0
- package/dist/remote-runtime-session-projection.d.ts +19 -0
- package/dist/remote-runtime-session-projection.js +566 -0
- package/dist/remote-runtime.d.ts +22 -0
- package/dist/remote-runtime.js +32 -0
- package/dist/runtime-web-auth.d.ts +26 -0
- package/dist/runtime-web-auth.js +132 -0
- package/dist/server.d.ts +364 -12
- package/dist/server.js +341 -100
- package/dist/session-browser-service.d.ts +248 -0
- package/dist/session-browser-service.js +772 -0
- package/dist/session-browser-surface-coordinator.d.ts +24 -0
- package/dist/session-browser-surface-coordinator.js +669 -0
- package/dist/session-emulator-service.d.ts +167 -0
- package/dist/session-emulator-service.js +464 -0
- package/dist/session-runtime-index.d.ts +23 -0
- package/dist/session-runtime-index.js +96 -0
- package/dist/session-terminal-host.d.ts +51 -0
- package/dist/session-terminal-host.js +270 -0
- package/dist/terminal-ws.d.ts +12 -20
- package/dist/terminal-ws.js +421 -97
- package/package.json +14 -7
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { isIP } from "node:net";
|
|
3
|
+
export const RUNTIME_WEB_CAPABILITY_HEADER = "x-rynx-runtime-capability";
|
|
4
|
+
export const RUNTIME_WEB_CAPABILITY_QUERY = "capability";
|
|
5
|
+
/**
|
|
6
|
+
* Process-lifetime CSRF capability shared by the Runtime HTTP BFF and its
|
|
7
|
+
* browser WebSocket upgrades. It is not a daemon-management credential.
|
|
8
|
+
*/
|
|
9
|
+
export const RUNTIME_WEB_CAPABILITY = randomBytes(32).toString("base64url");
|
|
10
|
+
export function runtimeWebAccessPolicyForBindHost(bindHost) {
|
|
11
|
+
const normalized = normalizeAddress(bindHost.trim().replace(/^\[|\]$/g, ""))?.toLowerCase();
|
|
12
|
+
return {
|
|
13
|
+
mode: normalized === "127.0.0.1" || normalized === "::1" || normalized === "localhost"
|
|
14
|
+
? "loopback"
|
|
15
|
+
: "host",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Authorize a browser request before any Runtime lease or terminal is opened.
|
|
20
|
+
* Socket address and the original Host header are both checked to resist DNS
|
|
21
|
+
* rebinding; mutation metadata and the capability provide the CSRF fence.
|
|
22
|
+
*/
|
|
23
|
+
export function authorizeRuntimeWebRequest(request, options = {}) {
|
|
24
|
+
const access = options.access ?? { mode: "loopback" };
|
|
25
|
+
if (access.mode === "loopback" && !isLoopbackAddress(request.socket.remoteAddress)) {
|
|
26
|
+
return { status: 403, error: "loopback_only" };
|
|
27
|
+
}
|
|
28
|
+
const host = originalHostHeader(request);
|
|
29
|
+
if (!host || !isAllowedHostAuthority(request, host, access)) {
|
|
30
|
+
return { status: 403, error: "invalid_host" };
|
|
31
|
+
}
|
|
32
|
+
if (!options.mutation)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (!isSameOriginBrowserMutation(request, host)) {
|
|
35
|
+
return { status: 403, error: "cross_origin" };
|
|
36
|
+
}
|
|
37
|
+
if (!safeTokenEquals(options.capability ?? "", RUNTIME_WEB_CAPABILITY)) {
|
|
38
|
+
return { status: 401, error: "invalid_runtime_capability" };
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
function isLoopbackAddress(value) {
|
|
43
|
+
const normalized = normalizeAddress(value);
|
|
44
|
+
return normalized === "127.0.0.1" || normalized === "::1";
|
|
45
|
+
}
|
|
46
|
+
function normalizeAddress(value) {
|
|
47
|
+
return value?.startsWith("::ffff:") ? value.slice("::ffff:".length) : value;
|
|
48
|
+
}
|
|
49
|
+
/** Read the HTTP/1 Host header exactly as received; duplicate Hosts fail closed. */
|
|
50
|
+
function originalHostHeader(request) {
|
|
51
|
+
let host;
|
|
52
|
+
const raw = request.rawHeaders;
|
|
53
|
+
for (let index = 0; index < raw.length; index += 2) {
|
|
54
|
+
if (raw[index]?.toLowerCase() !== "host")
|
|
55
|
+
continue;
|
|
56
|
+
if (host !== undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
host = raw[index + 1];
|
|
59
|
+
}
|
|
60
|
+
return host;
|
|
61
|
+
}
|
|
62
|
+
function isAllowedHostAuthority(request, host, access) {
|
|
63
|
+
if (isLoopbackHostAuthority(host)) {
|
|
64
|
+
return isLoopbackAddress(request.socket.remoteAddress);
|
|
65
|
+
}
|
|
66
|
+
if (access.mode !== "host")
|
|
67
|
+
return false;
|
|
68
|
+
const hostAddress = ipHostAuthorityAddress(host);
|
|
69
|
+
const localAddress = normalizeAddress(request.socket.localAddress);
|
|
70
|
+
return hostAddress !== undefined && localAddress !== undefined &&
|
|
71
|
+
hostAddress.toLowerCase() === localAddress.toLowerCase();
|
|
72
|
+
}
|
|
73
|
+
function isLoopbackHostAuthority(value) {
|
|
74
|
+
if (value.length === 0 || value !== value.trim())
|
|
75
|
+
return false;
|
|
76
|
+
const match = /^(?:localhost|127\.0\.0\.1|\[::1\])(?::(\d{1,5}))?$/i.exec(value);
|
|
77
|
+
if (!match)
|
|
78
|
+
return false;
|
|
79
|
+
if (match[1] === undefined)
|
|
80
|
+
return true;
|
|
81
|
+
const port = Number(match[1]);
|
|
82
|
+
return Number.isInteger(port) && port >= 1 && port <= 65_535;
|
|
83
|
+
}
|
|
84
|
+
function ipHostAuthorityAddress(value) {
|
|
85
|
+
if (value.length === 0 || value !== value.trim())
|
|
86
|
+
return undefined;
|
|
87
|
+
const match = /^(?:([0-9.]+)|\[([0-9a-f:.]+)\])(?::(\d{1,5}))?$/i.exec(value);
|
|
88
|
+
if (!match)
|
|
89
|
+
return undefined;
|
|
90
|
+
const address = match[1] ?? match[2];
|
|
91
|
+
if (isIP(address) === 0)
|
|
92
|
+
return undefined;
|
|
93
|
+
if (match[3] !== undefined) {
|
|
94
|
+
const port = Number(match[3]);
|
|
95
|
+
if (!Number.isInteger(port) || port < 1 || port > 65_535)
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return address;
|
|
99
|
+
}
|
|
100
|
+
function isSameOriginBrowserMutation(request, host) {
|
|
101
|
+
const fetchSite = singleHeader(request.headers["sec-fetch-site"]).trim().toLowerCase();
|
|
102
|
+
if (fetchSite && fetchSite !== "same-origin")
|
|
103
|
+
return false;
|
|
104
|
+
const origin = singleHeader(request.headers.origin).trim();
|
|
105
|
+
if (origin) {
|
|
106
|
+
try {
|
|
107
|
+
const parsed = new URL(origin);
|
|
108
|
+
const directScheme = request.socket.encrypted ? "https" : "http";
|
|
109
|
+
const expected = new URL(`${directScheme}://${host}`);
|
|
110
|
+
if (parsed.username ||
|
|
111
|
+
parsed.password ||
|
|
112
|
+
parsed.pathname !== "/" ||
|
|
113
|
+
parsed.search ||
|
|
114
|
+
parsed.hash ||
|
|
115
|
+
parsed.origin !== expected.origin) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return fetchSite === "same-origin" || origin.length > 0;
|
|
124
|
+
}
|
|
125
|
+
function singleHeader(value) {
|
|
126
|
+
return typeof value === "string" ? value : "";
|
|
127
|
+
}
|
|
128
|
+
function safeTokenEquals(actual, expected) {
|
|
129
|
+
const left = Buffer.from(actual, "utf8");
|
|
130
|
+
const right = Buffer.from(expected, "utf8");
|
|
131
|
+
return left.byteLength === right.byteLength && timingSafeEqual(left, right);
|
|
132
|
+
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,11 +1,53 @@
|
|
|
1
|
+
import type { Server as HttpServer } from "node:http";
|
|
1
2
|
import Koa from "koa";
|
|
2
|
-
import { ConversationRuntime, type
|
|
3
|
-
import {
|
|
3
|
+
import { ConversationRuntime, type AgentCapabilities, type AgentSessionStore, type AppConfig, type ChannelInstanceDescriptor, type SessionEvent, type SessionBus, type SessionLogStore, type SessionRegistry } from "@rynx-ai/core";
|
|
4
|
+
import type { SessionInteractionResolution } from "@rynx-ai/protocol";
|
|
5
|
+
import type { ControlRuntimeShareAddress, DaemonBrowserArtifactCleanResult, DaemonBrowserArtifactInstallInput, DaemonBrowserArtifactInstallResult, DaemonBrowserArtifactUpdateInput, DaemonBrowserArtifactVersionResult, DaemonCleanupSessionsInput, DaemonCleanupSessionsResult, DaemonChromeInspectionConfigureInput, DaemonChromeInspectionStatus, DaemonShutdownIfIdleResult } from "@rynx-ai/protocol/control";
|
|
6
|
+
import type { PluginInstallCommitInput, PluginInstallCommitResult, PluginInstallPreparation, PluginInstallPrepareInput, PluginManagementItem } from "@rynx-ai/protocol/plugin-management";
|
|
7
|
+
import type { PairingOffer } from "@rynx-ai/protocol/direct-runtime";
|
|
8
|
+
import type { DaemonStatus } from "@rynx-ai/protocol/remote-runtime";
|
|
9
|
+
import type { RuntimeBrowserBootstrapCredential, RuntimeBrowserEndpointDescriptor } from "@rynx-ai/protocol/runtime-browser-bootstrap";
|
|
10
|
+
import type { RuntimeBrowserInspectMessage, RuntimeBrowserInspectTarget } from "@rynx-ai/protocol/runtime-browser-inspect";
|
|
11
|
+
import type { RuntimeBrowserSurfaceClientFrame, RuntimeBrowserSurfaceImageFrame, RuntimeBrowserSurfaceOpenFrame, RuntimeBrowserSurfaceReadyFrame, RuntimeBrowserSurfaceServerFrame } from "@rynx-ai/protocol/runtime-browser-surface";
|
|
12
|
+
import type { RuntimeEmulatorSurfaceImageFrame, RuntimeEmulatorSurfaceReadyFrame } from "@rynx-ai/protocol/runtime-emulator-surface";
|
|
13
|
+
import type { RemoteRuntimeRpcMethod, RemoteRuntimeRpcParams, RemoteRuntimeRpcResultFor, RemoteRuntimeSequencedSessionEvent } from "@rynx-ai/protocol/remote-runtime-rpc";
|
|
14
|
+
import type { PluginAgentSummary, PluginResolvedSessionExecution, PluginSessionExecutionSnapshot } from "@rynx-ai/plugin-sdk";
|
|
15
|
+
import { RunnerManager, type CodexSessionStore, type RunnerSessionContextProvider } from "@rynx-ai/runtime";
|
|
4
16
|
import { ChannelManager } from "./channel-manager.js";
|
|
5
|
-
import { type ControlPlaneDeps } from "./control-api.js";
|
|
17
|
+
import { type ControlPlaneDeps, type LocalSessionResourceHost, type SessionResourceLifecycle } from "./control-api.js";
|
|
18
|
+
import type { DaemonRuntimeHost } from "./remote-runtime.js";
|
|
19
|
+
import { type AttachDesktopBrowserHostServerOptions } from "./desktop-browser-host.js";
|
|
20
|
+
import { SessionRuntimeIndex } from "./session-runtime-index.js";
|
|
21
|
+
import type { SessionEmulatorService } from "./session-emulator-service.js";
|
|
22
|
+
import { type SessionTerminalHost } from "./session-terminal-host.js";
|
|
23
|
+
import type { ProviderCliManagementHost } from "./provider-cli-host.js";
|
|
24
|
+
import { type RuntimeWebAccessPolicy } from "./runtime-web-auth.js";
|
|
6
25
|
export { ChannelManager } from "./channel-manager.js";
|
|
7
26
|
export type { ChannelInstanceStatus } from "./channel-manager.js";
|
|
8
|
-
export type {
|
|
27
|
+
export type { ProviderCliManagementHost, ProviderCliStatusHost, } from "./provider-cli-host.js";
|
|
28
|
+
export { MachineSessionService, MachineSessionServiceFailure, MachineSessionServiceInputError, synthesizeSessionTitle, } from "./machine-session-service.js";
|
|
29
|
+
export type { MachineSessionAgentCatalogPort, MachineSessionCreateInput, MachineSessionCreateResult, MachineSessionDeleteResult, MachineSessionInterruptPort, MachineSessionInterruptResult, MachineSessionInteractionResult, MachineSessionListInput, MachineSessionListPage, MachineSessionMessageResult, MachineSessionMessageEnqueueResult, MachineSessionMessageInput, MachineSessionMessageOperationState, MachineSessionPendingMessage, MachineSessionPendingMessagePort, MachineSessionPreparedInput, MachineSessionResourcePort, MachineSessionRunnerPort, MachineSessionRuntimeStatePort, MachineSessionServiceFailureCode, MachineSessionServiceOptions, MachineSessionServicePorts, MachineSessionSnapshotInput, MachineSessionSnapshotPage, MachineSessionWatch, } from "./machine-session-service.js";
|
|
30
|
+
export { SessionBrowserHostError, SessionBrowserService, SessionBrowserServiceError, SessionBrowserSurfaceUnsupportedError, } from "./session-browser-service.js";
|
|
31
|
+
export type { SessionBrowserHost, SessionBrowserHostCreateInput, SessionBrowserHostErrorCode, SessionBrowserHostEvent, SessionBrowserHostHandle, SessionBrowserHostPage, SessionBrowserHostSurfaceFrame, SessionBrowserHostSurfaceOpenInput, SessionBrowserHostSurfaceSource, SessionBrowserHostSurfaceTrustedInput, SessionBrowserHostSurfaceViewport, SessionBrowserHostSnapshot, SessionBrowserInspectionEndpoint, SessionBrowserInspectionTarget, SessionBrowserRegistryPort, SessionBrowserServiceErrorCode, SessionBrowserServiceOptions, SessionBrowserServicePorts, SessionBrowserSurfaceOpenInput, SessionBrowserSurfaceSource, } from "./session-browser-service.js";
|
|
32
|
+
export { SessionEmulatorBindingConflictError, SessionEmulatorService, SessionEmulatorServiceError, } from "./session-emulator-service.js";
|
|
33
|
+
export type { SessionEmulatorBindingRecord, SessionEmulatorBindingStore, SessionEmulatorServiceErrorCode, SessionEmulatorServiceOptions, SessionEmulatorSurface, } from "./session-emulator-service.js";
|
|
34
|
+
export { SessionBrowserSurfaceCoordinator } from "./session-browser-surface-coordinator.js";
|
|
35
|
+
export type { SessionBrowserSurfaceCoordinatorOptions, } from "./session-browser-surface-coordinator.js";
|
|
36
|
+
export { attachDesktopBrowserHostServer, createDesktopFirstSessionBrowserHost, DesktopBrowserHostAbsentError, DesktopBrowserHostProtocolError, DesktopBrowserHostRegistry, } from "./desktop-browser-host.js";
|
|
37
|
+
export type { AttachDesktopBrowserHostServerOptions, DesktopBrowserHostRegistryOptions, } from "./desktop-browser-host.js";
|
|
38
|
+
export type { ControlPlaneDeps, LocalSessionResourceHost, StoredSessionMeta, } from "./control-api.js";
|
|
39
|
+
export { createDaemonRuntimeHost, encodeDaemonStatus } from "./remote-runtime.js";
|
|
40
|
+
export type { DaemonRuntimeHost, DaemonRuntimeSnapshot } from "./remote-runtime.js";
|
|
41
|
+
export { DIRECT_RUNTIME_CONTROL_PATH, DirectRuntimeConnectionHub, startDirectRuntimeServer, } from "./direct-runtime-server.js";
|
|
42
|
+
export type { DirectRuntimeAuthenticationResult, DirectRuntimeAuthenticator, DirectRuntimeEmulatorSurfaceAttachment, DirectRuntimeEmulatorSurfaceHost, DirectRuntimePeer, DirectRuntimeServer, DirectRuntimeServerLimits, StartDirectRuntimeServerOptions, } from "./direct-runtime-server.js";
|
|
43
|
+
export { attachDirectRuntimeBrowserSurfaceServer, DirectRuntimeBrowserSurfaceHostError, } from "./direct-runtime-browser-surface-server.js";
|
|
44
|
+
export { attachDirectRuntimeBrowserInspectServer, DirectRuntimeBrowserInspectHostError, } from "./direct-runtime-browser-inspect-server.js";
|
|
45
|
+
export type { AttachDirectRuntimeBrowserInspectServerOptions, DirectRuntimeBrowserInspectAttachment, DirectRuntimeBrowserInspectConnectionHub, DirectRuntimeBrowserInspectHost, DirectRuntimeBrowserInspectServer, DirectRuntimeBrowserInspectServerLimits, DirectRuntimeBrowserInspectTransportCloseReason, } from "./direct-runtime-browser-inspect-server.js";
|
|
46
|
+
export type { AttachDirectRuntimeBrowserSurfaceServerOptions, DirectRuntimeBrowserSurfaceAttachment, DirectRuntimeBrowserSurfaceAttachmentEvent, DirectRuntimeBrowserSurfaceConnectionHub, DirectRuntimeBrowserSurfaceHost, DirectRuntimeBrowserSurfaceServer, DirectRuntimeBrowserSurfaceServerLimits, DirectRuntimeBrowserSurfaceTransportCloseReason, } from "./direct-runtime-browser-surface-server.js";
|
|
47
|
+
export { RemoteRuntimeDispatcher } from "./remote-runtime-dispatcher.js";
|
|
48
|
+
export type { AuthenticatedRuntimeSubject, RemoteRuntimeEmulatorHost, RemoteRuntimeSessionEmulatorHost, RemoteRuntimeDispatchContext, RemoteRuntimeDispatcherOptions, } from "./remote-runtime-dispatcher.js";
|
|
49
|
+
export { createRunnerSessionTerminalHost, SessionTerminalOpenError, SessionTerminalStreamError, } from "./session-terminal-host.js";
|
|
50
|
+
export type { RunnerSessionTerminalHostOptions, RunnerSessionTerminalHost, SessionTerminalAttachment, SessionTerminalCloseInfo, SessionTerminalCloseReason, SessionTerminalHost, SessionTerminalOpenErrorCode, SessionTerminalOpenOptions, SessionTerminalRole, } from "./session-terminal-host.js";
|
|
9
51
|
export type { ControlChannel, ControlChannelType, ControlInstanceConfig, ControlInstanceStatus, ControlAgentSummary, } from "@rynx-ai/protocol/control";
|
|
10
52
|
export interface CreateAppOptions {
|
|
11
53
|
config?: AppConfig;
|
|
@@ -20,16 +62,27 @@ export interface CreateAppOptions {
|
|
|
20
62
|
sessionLog?: SessionLogStore;
|
|
21
63
|
runnerManager?: RunnerManager;
|
|
22
64
|
sessionStore?: CodexSessionStore;
|
|
65
|
+
pluginRuntimeStatus?: () => unknown;
|
|
66
|
+
pluginRuntimeReload?: (pluginId: string) => Promise<unknown>;
|
|
67
|
+
pluginRuntimeEnsure?: (pluginId: string) => Promise<unknown>;
|
|
68
|
+
daemonManagement?: DaemonManagementHost;
|
|
69
|
+
remoteRuntime?: DaemonRuntimeHost;
|
|
70
|
+
remoteRuntimeAdmin?: RemoteRuntimeAdminHost;
|
|
71
|
+
runtimeTargetControl?: RuntimeTargetControlHost;
|
|
72
|
+
runtimeWebAccess?: RuntimeWebAccessPolicy;
|
|
73
|
+
runtimeConnectionResolver?: RuntimeConnectionResolverHost;
|
|
74
|
+
localSessionResources?: LocalSessionResourceHost;
|
|
75
|
+
sessionEmulators?: SessionEmulatorService;
|
|
76
|
+
/** Host lifecycle signal for ending SSE/video streams before drain. */
|
|
77
|
+
shutdownSignal?: AbortSignal;
|
|
78
|
+
sessionRuntimeIndex?: SessionRuntimeIndex;
|
|
79
|
+
sessionLifecycle?: SessionResourceLifecycle;
|
|
80
|
+
runtimeLocalBrowser?: RuntimeLocalBrowserAutomationHost;
|
|
81
|
+
providerClis?: ProviderCliManagementHost;
|
|
23
82
|
};
|
|
24
83
|
}
|
|
25
84
|
export interface StartServerOptions {
|
|
26
85
|
config?: AppConfig;
|
|
27
|
-
/**
|
|
28
|
-
* Legacy: channel plugins to mount as one shared-context batch. Kept for
|
|
29
|
-
* back-compat (and tests); the daemon now uses {@link loadInstances} so each
|
|
30
|
-
* instance gets its own context. Empty ⇒ a pure `/health` server.
|
|
31
|
-
*/
|
|
32
|
-
channelFactories?: ChannelFactory[];
|
|
33
86
|
/** Static set of channel instances to mount, each with its own context. */
|
|
34
87
|
channelInstances?: ChannelInstanceDescriptor[];
|
|
35
88
|
/**
|
|
@@ -55,12 +108,311 @@ export interface StartServerOptions {
|
|
|
55
108
|
* per session; the control plane lists every session uniformly from it.
|
|
56
109
|
*/
|
|
57
110
|
sessionRegistry?: SessionRegistry;
|
|
111
|
+
/** Trusted daemon-side bridge for isolated plugin runners. Installed plugin
|
|
112
|
+
* code never receives these objects; the bridge projects capability-gated
|
|
113
|
+
* JSON RPC from them. */
|
|
114
|
+
pluginRuntime?: PluginRuntimeLifecycle;
|
|
115
|
+
/** Narrow, loopback-only bridge for resident-daemon management clients. */
|
|
116
|
+
daemonManagement?: DaemonManagementHost;
|
|
117
|
+
/** Transport-independent Remote Runtime application port. */
|
|
118
|
+
remoteRuntime?: DaemonRuntimeHost;
|
|
119
|
+
/** Loopback-only enrollment and client-grant administration. */
|
|
120
|
+
remoteRuntimeAdmin?: RemoteRuntimeAdminHost;
|
|
121
|
+
/** Local BFF authority for explicit Local or Direct Runtime targets. */
|
|
122
|
+
runtimeTargetControl?: RuntimeTargetControlHost;
|
|
123
|
+
/** Secret-owning backend resolver for explicit Local or Direct Runtime calls. */
|
|
124
|
+
runtimeConnectionResolver?: RuntimeConnectionResolverHost;
|
|
125
|
+
/** In-process resource authority used only by the Local Runtime BFF. */
|
|
126
|
+
localSessionResources?: LocalSessionResourceHost;
|
|
127
|
+
/** Runtime-owned Session Emulator binding authority for Local compatibility routes. */
|
|
128
|
+
sessionEmulators?: SessionEmulatorService;
|
|
129
|
+
/** Pre-composed daemon-owned Session runtime. Supplying this lets the daemon
|
|
130
|
+
* inject the same application service into Local HTTP and Direct Runtime
|
|
131
|
+
* adapters without mirroring Session state into another owner. */
|
|
132
|
+
sessionRuntimeServices?: SessionRuntimeServices;
|
|
133
|
+
/** Shared fence for Session-owned resources on canonical and legacy deletes. */
|
|
134
|
+
sessionLifecycle?: SessionResourceLifecycle;
|
|
135
|
+
/** Shared local terminal host. Supplying this lets Local HTTP/WebSocket and
|
|
136
|
+
* Direct Runtime attachments contribute to one activity count. */
|
|
137
|
+
sessionTerminals?: SessionTerminalHost;
|
|
138
|
+
/** Runtime-local, Session-capability-authorized CDP bootstrap. Never remote. */
|
|
139
|
+
runtimeLocalBrowser?: RuntimeLocalBrowserAutomationHost;
|
|
140
|
+
/** Runtime-owned provider CLI inspection and local lifecycle operations. */
|
|
141
|
+
providerClis?: ProviderCliManagementHost;
|
|
142
|
+
/** Private resident-app Browser Host socket, authenticated by daemonManagement. */
|
|
143
|
+
desktopBrowserHost?: Omit<AttachDesktopBrowserHostServerOptions, "managementToken">;
|
|
144
|
+
}
|
|
145
|
+
export interface SessionRuntimeServices {
|
|
146
|
+
sessionStore: CodexSessionStore;
|
|
147
|
+
runnerManager: RunnerManager;
|
|
148
|
+
sessionBus: SessionBus;
|
|
149
|
+
sessionRuntimeIndex: SessionRuntimeIndex;
|
|
150
|
+
conversationRuntime: ConversationRuntime;
|
|
151
|
+
}
|
|
152
|
+
export interface PluginRuntimeHostServices {
|
|
153
|
+
conversationRuntime: ConversationRuntime;
|
|
154
|
+
capabilities: AgentCapabilities;
|
|
155
|
+
sessionStore: AgentSessionStore;
|
|
156
|
+
sessionRegistry: SessionRegistry;
|
|
157
|
+
agentCatalog: {
|
|
158
|
+
list(): Promise<PluginAgentSummary[]>;
|
|
159
|
+
get(id: string): Promise<PluginAgentSummary | null>;
|
|
160
|
+
resolveExecution(input: {
|
|
161
|
+
defaultAgent?: string;
|
|
162
|
+
session: PluginSessionExecutionSnapshot;
|
|
163
|
+
}): Promise<PluginResolvedSessionExecution>;
|
|
164
|
+
};
|
|
165
|
+
interruptSession(sessionId: string): Promise<boolean>;
|
|
166
|
+
resolveSessionInteraction(sessionId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
|
|
167
|
+
disposition: "applied" | "already_resolved" | "not_found" | "invalid";
|
|
168
|
+
}>;
|
|
169
|
+
}
|
|
170
|
+
export interface PluginRuntimeLifecycle {
|
|
171
|
+
bindHostServices(services: PluginRuntimeHostServices): void;
|
|
172
|
+
startPluginRuntimes(): Promise<void>;
|
|
173
|
+
reloadPluginRuntime(pluginId: string): Promise<unknown>;
|
|
174
|
+
ensurePluginRuntime(pluginId: string): Promise<unknown>;
|
|
175
|
+
/** Cached process/contribution health; must not block on plugin RPC. */
|
|
176
|
+
statusSnapshot(): unknown;
|
|
177
|
+
dispose(): Promise<void>;
|
|
178
|
+
}
|
|
179
|
+
export interface DaemonControlIdentity {
|
|
180
|
+
installationId: string;
|
|
181
|
+
algorithm: "Ed25519";
|
|
182
|
+
publicKey: string;
|
|
183
|
+
}
|
|
184
|
+
export interface PluginCliInvocationInput {
|
|
185
|
+
pluginId: string;
|
|
186
|
+
args: string[];
|
|
187
|
+
stdin?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface PluginCliInvocationOutput {
|
|
190
|
+
code: number;
|
|
191
|
+
stdout: string;
|
|
192
|
+
stderr: string;
|
|
193
|
+
truncated: boolean;
|
|
194
|
+
}
|
|
195
|
+
export interface DaemonManagementInvocationContext {
|
|
196
|
+
signal: AbortSignal;
|
|
197
|
+
}
|
|
198
|
+
export interface PluginManagementHost {
|
|
199
|
+
listPlugins(): {
|
|
200
|
+
plugins: PluginManagementItem[];
|
|
201
|
+
} | Promise<{
|
|
202
|
+
plugins: PluginManagementItem[];
|
|
203
|
+
}>;
|
|
204
|
+
setPluginEnabled(pluginId: string, enabled: boolean): PluginManagementItem | undefined | Promise<PluginManagementItem | undefined>;
|
|
205
|
+
uninstallPlugin(pluginId: string): Promise<boolean>;
|
|
206
|
+
prepareInstallation(input: PluginInstallPrepareInput, context: DaemonManagementInvocationContext): Promise<PluginInstallPreparation>;
|
|
207
|
+
commitInstallation(token: string, input: PluginInstallCommitInput, context: DaemonManagementInvocationContext): Promise<PluginInstallCommitResult>;
|
|
208
|
+
cancelPreparation(token: string): boolean | Promise<boolean>;
|
|
209
|
+
dispose?(): void | Promise<void>;
|
|
210
|
+
}
|
|
211
|
+
export interface BrowserArtifactManagementHost {
|
|
212
|
+
install(input: DaemonBrowserArtifactInstallInput, context: DaemonManagementInvocationContext): Promise<DaemonBrowserArtifactInstallResult>;
|
|
213
|
+
update(input: DaemonBrowserArtifactUpdateInput, context: DaemonManagementInvocationContext): Promise<DaemonBrowserArtifactInstallResult>;
|
|
214
|
+
version(): DaemonBrowserArtifactVersionResult;
|
|
215
|
+
clean(): DaemonBrowserArtifactCleanResult;
|
|
216
|
+
}
|
|
217
|
+
export interface MaintenanceManagementHost {
|
|
218
|
+
cleanupSessions(input: DaemonCleanupSessionsInput): DaemonCleanupSessionsResult;
|
|
219
|
+
}
|
|
220
|
+
export interface ChromeInspectionManagementHost {
|
|
221
|
+
status(): DaemonChromeInspectionStatus | Promise<DaemonChromeInspectionStatus>;
|
|
222
|
+
configure(input: DaemonChromeInspectionConfigureInput): Promise<DaemonChromeInspectionStatus>;
|
|
223
|
+
}
|
|
224
|
+
/** The complete local management authority injected by the daemon composition root. */
|
|
225
|
+
export interface DaemonManagementHost {
|
|
226
|
+
managementToken: string;
|
|
227
|
+
identity(): DaemonControlIdentity;
|
|
228
|
+
/** Public, non-secret health signal used to detect an in-place daemon rebuild. */
|
|
229
|
+
buildStatus?(): {
|
|
230
|
+
restartRequired: boolean;
|
|
231
|
+
};
|
|
232
|
+
/** Perform one final activity check and schedule shutdown only when idle. */
|
|
233
|
+
shutdownIfIdle?(): DaemonShutdownIfIdleResult;
|
|
234
|
+
/** Stateful plugin registry operations owned by the resident daemon. */
|
|
235
|
+
pluginManagement?: PluginManagementHost;
|
|
236
|
+
/** Stateful Chrome for Testing artifact operations owned by the daemon. */
|
|
237
|
+
browserArtifacts?: BrowserArtifactManagementHost;
|
|
238
|
+
/** Destructive maintenance operations over daemon-owned state. */
|
|
239
|
+
maintenance?: MaintenanceManagementHost;
|
|
240
|
+
/** Local Chrome DevTools discovery gateway configuration and readiness. */
|
|
241
|
+
chromeInspection?: ChromeInspectionManagementHost;
|
|
242
|
+
invokePluginCli(input: PluginCliInvocationInput, context: DaemonManagementInvocationContext): Promise<PluginCliInvocationOutput>;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Runtime-local Browser automation bootstrap. Returning `undefined` means the
|
|
246
|
+
* Session capability was not accepted; implementations must not reveal which
|
|
247
|
+
* half of the credential was wrong.
|
|
248
|
+
*/
|
|
249
|
+
export interface RuntimeLocalBrowserAutomationHost {
|
|
250
|
+
authorizeCredential(credential: RuntimeBrowserBootstrapCredential): boolean | Promise<boolean>;
|
|
251
|
+
endpointForCredential(credential: RuntimeBrowserBootstrapCredential): Promise<RuntimeBrowserEndpointDescriptor | undefined>;
|
|
252
|
+
endpointForSession(sessionId: string): Promise<RuntimeBrowserEndpointDescriptor>;
|
|
253
|
+
}
|
|
254
|
+
export interface RemoteRuntimeClientGrantView {
|
|
255
|
+
grantId: string;
|
|
256
|
+
clientId: string;
|
|
257
|
+
clientLabel: string | null;
|
|
258
|
+
clientKeyFingerprint: string;
|
|
259
|
+
authorities: string[];
|
|
260
|
+
createdAt: string;
|
|
261
|
+
revokedAt: string | null;
|
|
262
|
+
lastUsedAt: string | null;
|
|
58
263
|
}
|
|
264
|
+
/** Local operator authority for enabling new Direct clients and revoking them. */
|
|
265
|
+
export interface RemoteRuntimeAdminHost {
|
|
266
|
+
listShareAddresses(): ControlRuntimeShareAddress[];
|
|
267
|
+
createPairingOffer(input?: {
|
|
268
|
+
clientLabel?: string;
|
|
269
|
+
/** Host or ws(s) endpoint advertised by this individual access link. */
|
|
270
|
+
address?: string;
|
|
271
|
+
}): PairingOffer;
|
|
272
|
+
listClientGrants(): RemoteRuntimeClientGrantView[];
|
|
273
|
+
revokeClientGrant(grantId: string): {
|
|
274
|
+
revoked: boolean;
|
|
275
|
+
closedConnections: number;
|
|
276
|
+
};
|
|
277
|
+
deleteRevokedClientGrant(grantId: string): {
|
|
278
|
+
deleted: boolean;
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/** Secret-free Runtime target projection safe for the local Control Plane UI. */
|
|
282
|
+
export interface RuntimeTargetView {
|
|
283
|
+
/** Client-local selector: the reserved `local` selector or an opaque daemon id. */
|
|
284
|
+
selector: string;
|
|
285
|
+
daemonId: string;
|
|
286
|
+
displayName: string;
|
|
287
|
+
binding: "local" | "direct";
|
|
288
|
+
endpoint?: string;
|
|
289
|
+
identityKeyFingerprint?: string;
|
|
290
|
+
createdAt?: string;
|
|
291
|
+
}
|
|
292
|
+
export interface RuntimeTargetTestResult {
|
|
293
|
+
target: RuntimeTargetView;
|
|
294
|
+
status: DaemonStatus;
|
|
295
|
+
}
|
|
296
|
+
export interface RuntimeTargetPairResult {
|
|
297
|
+
target: RuntimeTargetView;
|
|
298
|
+
/** Authenticated status probe completed before the target is reported paired. */
|
|
299
|
+
status: DaemonStatus;
|
|
300
|
+
}
|
|
301
|
+
/** Local backend seam; credentials and pinned identity keys never cross it. */
|
|
302
|
+
export interface RuntimeTargetControlHost {
|
|
303
|
+
list(): RuntimeTargetView[] | Promise<RuntimeTargetView[]>;
|
|
304
|
+
pair(input: {
|
|
305
|
+
offer: unknown;
|
|
306
|
+
displayName?: string;
|
|
307
|
+
replaceExisting?: boolean;
|
|
308
|
+
expectedDaemonId?: string;
|
|
309
|
+
}): RuntimeTargetPairResult | Promise<RuntimeTargetPairResult>;
|
|
310
|
+
test(selector: string): RuntimeTargetTestResult | Promise<RuntimeTargetTestResult>;
|
|
311
|
+
forget(daemonId: string): {
|
|
312
|
+
forgotten: true;
|
|
313
|
+
} | Promise<{
|
|
314
|
+
forgotten: true;
|
|
315
|
+
}>;
|
|
316
|
+
}
|
|
317
|
+
/** Secret-free logical Runtime connection leased by the local Control Plane BFF. */
|
|
318
|
+
export interface RuntimeConnectionLease {
|
|
319
|
+
readonly target: {
|
|
320
|
+
selector: string;
|
|
321
|
+
daemonId: string;
|
|
322
|
+
};
|
|
323
|
+
call<M extends RemoteRuntimeRpcMethod>(method: M, params: RemoteRuntimeRpcParams<M>, options?: {
|
|
324
|
+
signal?: AbortSignal;
|
|
325
|
+
timeoutMs?: number;
|
|
326
|
+
}): Promise<RemoteRuntimeRpcResultFor<M>>;
|
|
327
|
+
subscribeSessionEvents(sessionId: string, options?: {
|
|
328
|
+
signal?: AbortSignal;
|
|
329
|
+
timeoutMs?: number;
|
|
330
|
+
}): Promise<RuntimeSessionEventsSubscription>;
|
|
331
|
+
openSessionTerminal(sessionId: string, options: {
|
|
332
|
+
role: "owner" | "read-only";
|
|
333
|
+
cols: number;
|
|
334
|
+
rows: number;
|
|
335
|
+
signal?: AbortSignal;
|
|
336
|
+
timeoutMs?: number;
|
|
337
|
+
}): Promise<import("./session-terminal-host.js").SessionTerminalAttachment>;
|
|
338
|
+
openBrowserSurface(frame: RuntimeBrowserSurfaceOpenFrame, options?: {
|
|
339
|
+
signal?: AbortSignal;
|
|
340
|
+
timeoutMs?: number;
|
|
341
|
+
}): Promise<RuntimeBrowserSurfaceConnection>;
|
|
342
|
+
openBrowserInspect(target: RuntimeBrowserInspectTarget, options?: {
|
|
343
|
+
signal?: AbortSignal;
|
|
344
|
+
timeoutMs?: number;
|
|
345
|
+
}): Promise<RuntimeBrowserInspectConnection>;
|
|
346
|
+
openEmulatorSurface(sessionId: string, bindingId: string, options?: {
|
|
347
|
+
signal?: AbortSignal;
|
|
348
|
+
timeoutMs?: number;
|
|
349
|
+
maximumFrameRate?: number;
|
|
350
|
+
}): Promise<RuntimeEmulatorSurfaceConnection>;
|
|
351
|
+
release(): void;
|
|
352
|
+
}
|
|
353
|
+
/** Secret-free Browser presentation stream owned by one selected Runtime. */
|
|
354
|
+
export interface RuntimeBrowserSurfaceConnection extends AsyncIterable<RuntimeBrowserSurfaceEvent> {
|
|
355
|
+
readonly ready: RuntimeBrowserSurfaceReadyFrame;
|
|
356
|
+
send(frame: Exclude<RuntimeBrowserSurfaceClientFrame, RuntimeBrowserSurfaceOpenFrame>): Promise<void>;
|
|
357
|
+
close(): Promise<void>;
|
|
358
|
+
}
|
|
359
|
+
export type RuntimeBrowserSurfaceEvent = Exclude<RuntimeBrowserSurfaceServerFrame, RuntimeBrowserSurfaceReadyFrame> | RuntimeBrowserSurfaceImageFrame;
|
|
360
|
+
/** Dedicated transparent CDP stream owned by one selected Runtime page. */
|
|
361
|
+
export interface RuntimeBrowserInspectConnection extends AsyncIterable<RuntimeBrowserInspectMessage> {
|
|
362
|
+
readonly daemonInstanceId: string;
|
|
363
|
+
send(message: RuntimeBrowserInspectMessage): Promise<void>;
|
|
364
|
+
close(): Promise<void>;
|
|
365
|
+
}
|
|
366
|
+
export interface RuntimeEmulatorSurfaceConnection extends AsyncIterable<RuntimeEmulatorSurfaceImageFrame> {
|
|
367
|
+
readonly ready: RuntimeEmulatorSurfaceReadyFrame;
|
|
368
|
+
sendTouch(point: {
|
|
369
|
+
phase: "begin" | "move" | "end";
|
|
370
|
+
x: number;
|
|
371
|
+
y: number;
|
|
372
|
+
}): Promise<void>;
|
|
373
|
+
close(): Promise<void>;
|
|
374
|
+
}
|
|
375
|
+
/** One Runtime-owned live Session tail. The lease must outlive this handle. */
|
|
376
|
+
export interface RuntimeSessionEventsSubscription extends AsyncIterable<RemoteRuntimeSequencedSessionEvent> {
|
|
377
|
+
readonly sessionId: string;
|
|
378
|
+
readonly daemonInstanceId: string;
|
|
379
|
+
close(): Promise<void>;
|
|
380
|
+
}
|
|
381
|
+
/** Application-facing half of the daemon-owned connection manager. */
|
|
382
|
+
export interface RuntimeConnectionResolverHost {
|
|
383
|
+
acquire(selector: string, options?: {
|
|
384
|
+
signal?: AbortSignal;
|
|
385
|
+
}): Promise<RuntimeConnectionLease>;
|
|
386
|
+
}
|
|
387
|
+
/** HTTP server plus an idempotent join point for all daemon-owned resources. */
|
|
388
|
+
export interface RynxServer extends HttpServer {
|
|
389
|
+
/** Synchronously stop new HTTP admission without closing upgraded Hosts. */
|
|
390
|
+
stopAccepting(): void;
|
|
391
|
+
shutdown(): Promise<void>;
|
|
392
|
+
}
|
|
393
|
+
/** Preserve one session's mirror order without serializing unrelated sessions. */
|
|
394
|
+
export declare class SessionMirrorQueue {
|
|
395
|
+
private readonly persist;
|
|
396
|
+
private readonly tails;
|
|
397
|
+
constructor(persist: (sessionId: string, event: SessionEvent) => Promise<void>);
|
|
398
|
+
enqueue(sessionId: string, event: SessionEvent): Promise<void>;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Compose the process-owned Session runtime once. The daemon may call this
|
|
402
|
+
* before creating its Direct dispatcher; {@link startServer} accepts the same
|
|
403
|
+
* bundle and therefore does not create a second bus, runtime index, or runner.
|
|
404
|
+
*/
|
|
405
|
+
export declare function createSessionRuntimeServices(input: {
|
|
406
|
+
config: AppConfig;
|
|
407
|
+
sessionLog?: SessionLogStore;
|
|
408
|
+
onMirrorError?: (error: unknown, sessionId: string) => void;
|
|
409
|
+
sessionContextProvider?: RunnerSessionContextProvider;
|
|
410
|
+
}): SessionRuntimeServices;
|
|
59
411
|
/**
|
|
60
412
|
* The HTTP surface is just a liveness probe for container orchestration — all
|
|
61
413
|
* agent capabilities are forwarded through the mounted channel plugins (the
|
|
62
414
|
* Lark bot reaches its server over an outbound WebSocket long connection), so
|
|
63
415
|
* no agent request / response / SSE endpoints are exposed here.
|
|
64
416
|
*/
|
|
65
|
-
export declare function createApp({ control }?: CreateAppOptions): Koa<Koa.DefaultState, Koa.DefaultContext>;
|
|
66
|
-
export declare function startServer({ config,
|
|
417
|
+
export declare function createApp({ config, control }?: CreateAppOptions): Koa<Koa.DefaultState, Koa.DefaultContext>;
|
|
418
|
+
export declare function startServer({ config, channelInstances, loadInstances, control, sessionLog, sessionRegistry, pluginRuntime, daemonManagement, remoteRuntime, remoteRuntimeAdmin, runtimeTargetControl, runtimeConnectionResolver, localSessionResources, sessionEmulators, sessionRuntimeServices, sessionLifecycle, sessionTerminals, runtimeLocalBrowser, providerClis, desktopBrowserHost, }?: StartServerOptions): Promise<RynxServer>;
|