@blue-soda/dsh-remote 0.4.28
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/LICENSE +29 -0
- package/README.md +81 -0
- package/bin/ds-harness-remote.js +11 -0
- package/cordis.patch.yml +32 -0
- package/dist/acp.d.ts +75 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +61 -0
- package/dist/acp.js.map +1 -0
- package/dist/api-proxy-switch.d.ts +33 -0
- package/dist/api-proxy-switch.d.ts.map +1 -0
- package/dist/api-proxy-switch.js +109 -0
- package/dist/api-proxy-switch.js.map +1 -0
- package/dist/bin/doctor.d.ts +3 -0
- package/dist/bin/doctor.d.ts.map +1 -0
- package/dist/bin/doctor.js +13 -0
- package/dist/bin/doctor.js.map +1 -0
- package/dist/cli.d.ts +32 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +289 -0
- package/dist/cli.js.map +1 -0
- package/dist/client-runtime.d.ts +239 -0
- package/dist/client-runtime.d.ts.map +1 -0
- package/dist/client-runtime.js +1391 -0
- package/dist/client-runtime.js.map +1 -0
- package/dist/client-secure-transport.d.ts +23 -0
- package/dist/client-secure-transport.d.ts.map +1 -0
- package/dist/client-secure-transport.js +143 -0
- package/dist/client-secure-transport.js.map +1 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.github.js +4231 -0
- package/dist/client.js +4231 -0
- package/dist/codex/app-server.d.ts +71 -0
- package/dist/codex/app-server.d.ts.map +1 -0
- package/dist/codex/app-server.js +268 -0
- package/dist/codex/app-server.js.map +1 -0
- package/dist/codex/codex-image-codec.d.ts +7 -0
- package/dist/codex/codex-image-codec.d.ts.map +1 -0
- package/dist/codex/codex-image-codec.js +288 -0
- package/dist/codex/codex-image-codec.js.map +1 -0
- package/dist/codex/domain.d.ts +93 -0
- package/dist/codex/domain.d.ts.map +1 -0
- package/dist/codex/domain.js +1282 -0
- package/dist/codex/domain.js.map +1 -0
- package/dist/codex/method-policy.d.ts +338 -0
- package/dist/codex/method-policy.d.ts.map +1 -0
- package/dist/codex/method-policy.js +141 -0
- package/dist/codex/method-policy.js.map +1 -0
- package/dist/codex/peer-bridge.d.ts +57 -0
- package/dist/codex/peer-bridge.d.ts.map +1 -0
- package/dist/codex/peer-bridge.js +299 -0
- package/dist/codex/peer-bridge.js.map +1 -0
- package/dist/codex/permissions.d.ts +4 -0
- package/dist/codex/permissions.d.ts.map +1 -0
- package/dist/codex/permissions.js +21 -0
- package/dist/codex/permissions.js.map +1 -0
- package/dist/codex/session-id.d.ts +10 -0
- package/dist/codex/session-id.d.ts.map +1 -0
- package/dist/codex/session-id.js +15 -0
- package/dist/codex/session-id.js.map +1 -0
- package/dist/codex/virtual-harness.d.ts +209 -0
- package/dist/codex/virtual-harness.d.ts.map +1 -0
- package/dist/codex/virtual-harness.js +2616 -0
- package/dist/codex/virtual-harness.js.map +1 -0
- package/dist/codex-workspace-bridge.d.ts +108 -0
- package/dist/codex-workspace-bridge.d.ts.map +1 -0
- package/dist/codex-workspace-bridge.js +502 -0
- package/dist/codex-workspace-bridge.js.map +1 -0
- package/dist/config.d.ts +99 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/connection-controller.d.ts +44 -0
- package/dist/connection-controller.d.ts.map +1 -0
- package/dist/connection-controller.js +185 -0
- package/dist/connection-controller.js.map +1 -0
- package/dist/control-route.d.ts +34 -0
- package/dist/control-route.d.ts.map +1 -0
- package/dist/control-route.js +136 -0
- package/dist/control-route.js.map +1 -0
- package/dist/control-runtime.d.ts +138 -0
- package/dist/control-runtime.d.ts.map +1 -0
- package/dist/control-runtime.js +543 -0
- package/dist/control-runtime.js.map +1 -0
- package/dist/control-stream.d.ts +67 -0
- package/dist/control-stream.d.ts.map +1 -0
- package/dist/control-stream.js +179 -0
- package/dist/control-stream.js.map +1 -0
- package/dist/defaults.d.ts +9 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +9 -0
- package/dist/defaults.js.map +1 -0
- package/dist/file-viewer-bridge.d.ts +30 -0
- package/dist/file-viewer-bridge.d.ts.map +1 -0
- package/dist/file-viewer-bridge.js +128 -0
- package/dist/file-viewer-bridge.js.map +1 -0
- package/dist/file-viewer-contract.d.ts +5 -0
- package/dist/file-viewer-contract.d.ts.map +1 -0
- package/dist/file-viewer-contract.js +4 -0
- package/dist/file-viewer-contract.js.map +1 -0
- package/dist/harness-api-bridge.d.ts +79 -0
- package/dist/harness-api-bridge.d.ts.map +1 -0
- package/dist/harness-api-bridge.js +852 -0
- package/dist/harness-api-bridge.js.map +1 -0
- package/dist/harness-api-history.d.ts +3 -0
- package/dist/harness-api-history.d.ts.map +1 -0
- package/dist/harness-api-history.js +59 -0
- package/dist/harness-api-history.js.map +1 -0
- package/dist/harness-remote-bridge.d.ts +52 -0
- package/dist/harness-remote-bridge.d.ts.map +1 -0
- package/dist/harness-remote-bridge.js +529 -0
- package/dist/harness-remote-bridge.js.map +1 -0
- package/dist/harness-version.d.ts +23 -0
- package/dist/harness-version.d.ts.map +1 -0
- package/dist/harness-version.js +95 -0
- package/dist/harness-version.js.map +1 -0
- package/dist/identity-store.d.ts +45 -0
- package/dist/identity-store.d.ts.map +1 -0
- package/dist/identity-store.js +183 -0
- package/dist/identity-store.js.map +1 -0
- package/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +17 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28870 -0
- package/dist/index.js.map +7 -0
- package/dist/logging.d.ts +18 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +30 -0
- package/dist/logging.js.map +1 -0
- package/dist/loopback-host.d.ts +20 -0
- package/dist/loopback-host.d.ts.map +1 -0
- package/dist/loopback-host.js +245 -0
- package/dist/loopback-host.js.map +1 -0
- package/dist/loopback-preview.d.ts +19 -0
- package/dist/loopback-preview.d.ts.map +1 -0
- package/dist/loopback-preview.js +232 -0
- package/dist/loopback-preview.js.map +1 -0
- package/dist/native-rtc-helper.d.ts +14 -0
- package/dist/native-rtc-helper.d.ts.map +1 -0
- package/dist/native-rtc-helper.js +575 -0
- package/dist/native-rtc-helper.js.map +1 -0
- package/dist/remote-api-proxy.d.ts +17 -0
- package/dist/remote-api-proxy.d.ts.map +1 -0
- package/dist/remote-api-proxy.js +400 -0
- package/dist/remote-api-proxy.js.map +1 -0
- package/dist/remote-directory-browser.d.ts +16 -0
- package/dist/remote-directory-browser.d.ts.map +1 -0
- package/dist/remote-directory-browser.js +48 -0
- package/dist/remote-directory-browser.js.map +1 -0
- package/dist/remote-file-content-provider.d.ts +48 -0
- package/dist/remote-file-content-provider.d.ts.map +1 -0
- package/dist/remote-file-content-provider.js +93 -0
- package/dist/remote-file-content-provider.js.map +1 -0
- package/dist/remote-typert-gateway.d.ts +20 -0
- package/dist/remote-typert-gateway.d.ts.map +1 -0
- package/dist/remote-typert-gateway.js +332 -0
- package/dist/remote-typert-gateway.js.map +1 -0
- package/dist/rpc-router.d.ts +31 -0
- package/dist/rpc-router.d.ts.map +1 -0
- package/dist/rpc-router.js +201 -0
- package/dist/rpc-router.js.map +1 -0
- package/dist/safe-error.d.ts +8 -0
- package/dist/safe-error.d.ts.map +1 -0
- package/dist/safe-error.js +20 -0
- package/dist/safe-error.js.map +1 -0
- package/dist/server-api.d.ts +109 -0
- package/dist/server-api.d.ts.map +1 -0
- package/dist/server-api.js +520 -0
- package/dist/server-api.js.map +1 -0
- package/dist/server-connection.d.ts +79 -0
- package/dist/server-connection.d.ts.map +1 -0
- package/dist/server-connection.js +1023 -0
- package/dist/server-connection.js.map +1 -0
- package/dist/server-credentials.d.ts +55 -0
- package/dist/server-credentials.d.ts.map +1 -0
- package/dist/server-credentials.js +105 -0
- package/dist/server-credentials.js.map +1 -0
- package/dist/service.d.ts +141 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +432 -0
- package/dist/service.js.map +1 -0
- package/dist/session-format-compat.d.ts +3 -0
- package/dist/session-format-compat.d.ts.map +1 -0
- package/dist/session-format-compat.js +183 -0
- package/dist/session-format-compat.js.map +1 -0
- package/dist/status-stream.d.ts +48 -0
- package/dist/status-stream.d.ts.map +1 -0
- package/dist/status-stream.js +133 -0
- package/dist/status-stream.js.map +1 -0
- package/dist/terminal-policy.d.ts +21 -0
- package/dist/terminal-policy.d.ts.map +1 -0
- package/dist/terminal-policy.js +68 -0
- package/dist/terminal-policy.js.map +1 -0
- package/dist/tui-command.d.ts +13 -0
- package/dist/tui-command.d.ts.map +1 -0
- package/dist/tui-command.js +390 -0
- package/dist/tui-command.js.map +1 -0
- package/dist/typert-gateway-contract.d.ts +59 -0
- package/dist/typert-gateway-contract.d.ts.map +1 -0
- package/dist/typert-gateway-contract.js +2 -0
- package/dist/typert-gateway-contract.js.map +1 -0
- package/dist/typert-gateway-switch.d.ts +85 -0
- package/dist/typert-gateway-switch.d.ts.map +1 -0
- package/dist/typert-gateway-switch.js +315 -0
- package/dist/typert-gateway-switch.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +12 -0
- package/dist/version.js.map +1 -0
- package/dist/werift-rtc.d.ts +121 -0
- package/dist/werift-rtc.d.ts.map +1 -0
- package/dist/werift-rtc.js +490 -0
- package/dist/werift-rtc.js.map +1 -0
- package/dsh-plugin.json +41 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +165 -0
- package/public.d.ts +26 -0
package/dist/service.js
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { LoopbackHost } from './loopback-host.js';
|
|
2
|
+
import { TerminalPolicy } from './terminal-policy.js';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { createEvent } from '@dsh-remote/protocol';
|
|
5
|
+
import { ConnectionController } from './connection-controller.js';
|
|
6
|
+
import { harnessSessionGeneration, normalizeHarnessVersion, readHarnessDistributionVersion, selectHarnessVersion, } from './harness-version.js';
|
|
7
|
+
import { RpcRouter } from './rpc-router.js';
|
|
8
|
+
import { RemoteFileViewerBridge } from './file-viewer-bridge.js';
|
|
9
|
+
import { HostServerApi, ServerApiError, } from './server-api.js';
|
|
10
|
+
import { HostServerConnection } from './server-connection.js';
|
|
11
|
+
import { ServerCredentialStore } from './server-credentials.js';
|
|
12
|
+
import { HarnessApiBridge } from './harness-api-bridge.js';
|
|
13
|
+
import { HarnessRemoteBridge } from './harness-remote-bridge.js';
|
|
14
|
+
import { loadNodeRtcFactory } from './werift-rtc.js';
|
|
15
|
+
import { CodexRemoteDomain } from './codex/domain.js';
|
|
16
|
+
import { AcpGateway, StdioAcpAdapter } from './acp.js';
|
|
17
|
+
import { execFileSync } from 'node:child_process';
|
|
18
|
+
import { RpcError } from './safe-error.js';
|
|
19
|
+
import { CodexWorkspaceBridge, CodexWorkspaceState } from './codex-workspace-bridge.js';
|
|
20
|
+
export class HostPluginRuntime {
|
|
21
|
+
config;
|
|
22
|
+
identities;
|
|
23
|
+
apiProxy;
|
|
24
|
+
logger;
|
|
25
|
+
localGateway;
|
|
26
|
+
fileViewerHost;
|
|
27
|
+
terminalSpawner;
|
|
28
|
+
connections;
|
|
29
|
+
terminalOwners = new Map();
|
|
30
|
+
loopbackHosts = new Set();
|
|
31
|
+
terminalEnabled;
|
|
32
|
+
loopbackPorts;
|
|
33
|
+
identity;
|
|
34
|
+
serverApi;
|
|
35
|
+
serverConnection;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the user asked this machine to stay unreachable.
|
|
38
|
+
*
|
|
39
|
+
* Pausing keeps the credentials and the device identity: it only stops the
|
|
40
|
+
* outbound connection, so resuming needs no re-authorization and consumes no
|
|
41
|
+
* device identity, unlike clearing the authorization.
|
|
42
|
+
*/
|
|
43
|
+
paused;
|
|
44
|
+
harnessVersion;
|
|
45
|
+
closed = false;
|
|
46
|
+
codex;
|
|
47
|
+
codexWorkspaceState = new CodexWorkspaceState();
|
|
48
|
+
localCodexPeer;
|
|
49
|
+
localCodexPublish = async () => undefined;
|
|
50
|
+
constructor(config, identities, apiProxy, logger, localGateway, fileViewerHost,
|
|
51
|
+
/** PTY-backed terminal provider from the Host `subprocess` service, when present. */
|
|
52
|
+
terminalSpawner) {
|
|
53
|
+
this.config = config;
|
|
54
|
+
this.identities = identities;
|
|
55
|
+
this.apiProxy = apiProxy;
|
|
56
|
+
this.logger = logger;
|
|
57
|
+
this.localGateway = localGateway;
|
|
58
|
+
this.fileViewerHost = fileViewerHost;
|
|
59
|
+
this.terminalSpawner = terminalSpawner;
|
|
60
|
+
this.terminalEnabled = config.terminal.enabled;
|
|
61
|
+
this.loopbackPorts = [...config.loopback.ports];
|
|
62
|
+
// Honour a pause recorded by an earlier run, so "do not connect me" is not
|
|
63
|
+
// silently undone by restarting DSH.
|
|
64
|
+
this.paused = config.hostControl?.paused === true;
|
|
65
|
+
this.codex = new CodexRemoteDomain(config.codex, logger);
|
|
66
|
+
this.connections = new ConnectionController(this.identities, (context, send) => {
|
|
67
|
+
const harnessApi = this.apiProxy === undefined
|
|
68
|
+
? undefined
|
|
69
|
+
: new HarnessApiBridge(this.apiProxy, (event, data) => send(createEvent(event, data)), undefined, this.logger, this.localGateway, this.harnessVersion);
|
|
70
|
+
const harnessRemote = this.localGateway?.supportsCarrier === true
|
|
71
|
+
? new HarnessRemoteBridge(this.localGateway, (event, data) => send(createEvent(event, data)), this.logger, this.harnessVersion, new TerminalPolicy(() => this.terminalEnabled, context.peerDeviceId, this.terminalOwners), new CodexWorkspaceBridge((threadId, signal) => this.codex.resolveThreadWorkspace(context.connectionId, threadId), () => this.terminalEnabled, this.codexWorkspaceState, this.terminalSpawner))
|
|
72
|
+
: undefined;
|
|
73
|
+
const fileViewer = new RemoteFileViewerBridge(() => this.fileViewerHost?.(), this.logger);
|
|
74
|
+
const codex = this.codex.createPeer(context, (event, data) => send(createEvent(event, data)));
|
|
75
|
+
const adapters = (config.acp?.backends ?? []).filter(item => item.enabled && this.acpAvailable(item.command)).map(item => new StdioAcpAdapter(item));
|
|
76
|
+
const acp = config.acp?.enabled && adapters.length > 0 ? new AcpGateway(adapters) : undefined;
|
|
77
|
+
return new RpcRouter(harnessApi, undefined, this.logger, fileViewer, harnessRemote, () => this.hostCapabilities(), codex, acp,
|
|
78
|
+
// Handles and their lifetime belong to this connection; only policy is shared.
|
|
79
|
+
this.createLoopbackHost());
|
|
80
|
+
}, this.logger);
|
|
81
|
+
if (config.serverUrl !== undefined) {
|
|
82
|
+
this.serverApi = new HostServerApi(config.serverUrl, new ServerCredentialStore(identities.directory));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
setTerminalEnabled(enabled) {
|
|
86
|
+
this.terminalEnabled = enabled;
|
|
87
|
+
}
|
|
88
|
+
setLoopbackPorts(ports) {
|
|
89
|
+
this.loopbackPorts = [...ports];
|
|
90
|
+
for (const loopback of this.loopbackHosts)
|
|
91
|
+
loopback.setPorts(this.loopbackPorts);
|
|
92
|
+
}
|
|
93
|
+
createLoopbackHost() {
|
|
94
|
+
let loopback;
|
|
95
|
+
loopback = new LoopbackHost(() => this.loopbackPorts, () => this.loopbackHosts.delete(loopback));
|
|
96
|
+
this.loopbackHosts.add(loopback);
|
|
97
|
+
return loopback;
|
|
98
|
+
}
|
|
99
|
+
async start() {
|
|
100
|
+
if (this.closed)
|
|
101
|
+
throw new Error('remote runtime is closed');
|
|
102
|
+
this.identity = await this.identities.loadOrCreate(this.config.deviceName);
|
|
103
|
+
this.logger.info('host identity ready', {
|
|
104
|
+
deviceId: shortId(this.identity.deviceId),
|
|
105
|
+
fingerprint: this.identity.fingerprint,
|
|
106
|
+
server: this.config.serverUrl ?? 'not configured',
|
|
107
|
+
});
|
|
108
|
+
await this.codex.start();
|
|
109
|
+
if (this.serverApi !== undefined) {
|
|
110
|
+
this.harnessVersion = await this.readHarnessVersion();
|
|
111
|
+
this.serverApi.setHarnessVersion(this.harnessVersion);
|
|
112
|
+
this.serverApi.bindIdentity(this.identity);
|
|
113
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
114
|
+
// A paused installation stays quiet until the user resumes it; a restart
|
|
115
|
+
// must not turn a paused machine reachable again.
|
|
116
|
+
if (!this.paused)
|
|
117
|
+
this.serverConnection.start();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
currentIdentity() {
|
|
121
|
+
if (this.identity === undefined)
|
|
122
|
+
throw new Error('remote runtime has not started');
|
|
123
|
+
return this.identity;
|
|
124
|
+
}
|
|
125
|
+
acceptAuthenticatedPeer(channel) {
|
|
126
|
+
this.currentIdentity();
|
|
127
|
+
return this.connections.accept(channel);
|
|
128
|
+
}
|
|
129
|
+
hostStatus() {
|
|
130
|
+
const error = this.serverConnection?.lastError();
|
|
131
|
+
const authorization = this.serverApi?.currentAuthorization();
|
|
132
|
+
return {
|
|
133
|
+
...(this.identity === undefined ? {} : { deviceId: this.identity.deviceId }),
|
|
134
|
+
configured: this.serverApi !== undefined,
|
|
135
|
+
online: this.serverConnection?.isOnline() ?? false,
|
|
136
|
+
reconnecting: this.serverConnection?.isReconnecting() ?? false,
|
|
137
|
+
...(this.serverConnection?.lastActivity() === undefined
|
|
138
|
+
? {}
|
|
139
|
+
: { lastActiveAt: this.serverConnection.lastActivity() }),
|
|
140
|
+
...(error === undefined ? {} : { error }),
|
|
141
|
+
...(authorization?.account === undefined ? {} : { account: authorization.account }),
|
|
142
|
+
authorized: authorization !== undefined,
|
|
143
|
+
accountRequired: error === 'ACCOUNT_AUTH_REQUIRED' || error === 'AUTH_INVALID' || error === 'TOKEN_EXPIRED',
|
|
144
|
+
paused: this.paused,
|
|
145
|
+
connectedClients: this.listConnectedClients(),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async hasStoredAuthorization() {
|
|
149
|
+
return this.serverApi?.hasStoredAuthorization() ?? false;
|
|
150
|
+
}
|
|
151
|
+
listConnectedClients() {
|
|
152
|
+
return this.connections.connectedPeers().map(peer => {
|
|
153
|
+
const trusted = this.identities.trustedPeer(peer.deviceId);
|
|
154
|
+
return {
|
|
155
|
+
deviceId: peer.deviceId,
|
|
156
|
+
name: trusted?.name.trim() ?? '',
|
|
157
|
+
...(trusted === undefined ? {} : { platform: trusted.platform }),
|
|
158
|
+
...(peer.mode === undefined ? {} : { mode: peer.mode }),
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
localHarnessVersion() {
|
|
163
|
+
return this.harnessVersion;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Stop this machine from being reachable without releasing its authorization.
|
|
167
|
+
*
|
|
168
|
+
* Clearing the authorization revokes the device and rotates its identity, so a
|
|
169
|
+
* user who only wants to stop being remotely reachable would have to authorize
|
|
170
|
+
* again and would consume a device identity. Pausing closes the connection and
|
|
171
|
+
* keeps both.
|
|
172
|
+
*/
|
|
173
|
+
async pauseHostConnection() {
|
|
174
|
+
this.paused = true;
|
|
175
|
+
await this.serverConnection?.stop();
|
|
176
|
+
this.logger.info('Host connection paused');
|
|
177
|
+
}
|
|
178
|
+
/** Resume a paused connection with the same credentials and identity. */
|
|
179
|
+
async resumeHostConnection() {
|
|
180
|
+
const wasPaused = this.paused;
|
|
181
|
+
this.paused = false;
|
|
182
|
+
this.serverConnection?.resume();
|
|
183
|
+
if (wasPaused)
|
|
184
|
+
this.logger.info('Host connection resumed');
|
|
185
|
+
}
|
|
186
|
+
isPaused() { return this.paused; }
|
|
187
|
+
reconnectHost() {
|
|
188
|
+
if (this.closed)
|
|
189
|
+
throw new Error('remote runtime is closed');
|
|
190
|
+
if (this.serverConnection === undefined) {
|
|
191
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Configure serverUrl before reconnecting.', false);
|
|
192
|
+
}
|
|
193
|
+
// Asking to reconnect is explicit: it lifts a pause rather than being
|
|
194
|
+
// swallowed by it, so the button always has an effect.
|
|
195
|
+
this.paused = false;
|
|
196
|
+
this.serverConnection.reconnect();
|
|
197
|
+
}
|
|
198
|
+
async startHostOAuthQrLogin(provider) {
|
|
199
|
+
if (this.serverApi === undefined) {
|
|
200
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Remote Host Server is unavailable.', false);
|
|
201
|
+
}
|
|
202
|
+
return this.serverApi.startOAuthQrLogin(provider);
|
|
203
|
+
}
|
|
204
|
+
async pollHostOAuthQrLogin(qrId) {
|
|
205
|
+
if (this.serverApi === undefined) {
|
|
206
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Remote Host Server is unavailable.', false);
|
|
207
|
+
}
|
|
208
|
+
const result = await this.serverApi.pollOAuthQrLogin(this.currentIdentity(), qrId, async () => {
|
|
209
|
+
await this.serverConnection?.stop();
|
|
210
|
+
this.identity = await this.identities.reset(this.config.deviceName);
|
|
211
|
+
this.serverApi.bindIdentity(this.identity);
|
|
212
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
213
|
+
return this.identity;
|
|
214
|
+
});
|
|
215
|
+
if (result.status === 'complete') {
|
|
216
|
+
this.serverConnection?.reconnect();
|
|
217
|
+
this.logger.info('Host account authorized through OAuth QR login');
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Stop this Host from being authorized, keeping its device identity.
|
|
223
|
+
*
|
|
224
|
+
* Revoking the device here would force a new identity on the next sign-in and
|
|
225
|
+
* register a second device for the same installation. An account holds at most
|
|
226
|
+
* 256 devices and the count only grows for new identities, so signing out
|
|
227
|
+
* often enough could exhaust it. The credentials themselves are cleared by the
|
|
228
|
+
* caller; this device simply stops authenticating.
|
|
229
|
+
*/
|
|
230
|
+
async clearHostAuthorization() {
|
|
231
|
+
await this.serverConnection?.stop();
|
|
232
|
+
// Clearing the stored credential is not enough: this API caches the
|
|
233
|
+
// authorization in memory too, and the stale copy keeps reporting the Host as
|
|
234
|
+
// authorized. That makes `authorizeHostByDefault()` skip re-authorization and
|
|
235
|
+
// leaves the connection retrying tokens the Server no longer accepts.
|
|
236
|
+
await this.serverApi?.clearAuthorization();
|
|
237
|
+
// The connection survives, bound to the identity it keeps.
|
|
238
|
+
if (this.serverApi !== undefined && this.identity !== undefined) {
|
|
239
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
240
|
+
}
|
|
241
|
+
this.logger.info('Host authorization cleared');
|
|
242
|
+
}
|
|
243
|
+
async authorizeHostAsOwned(accessToken, account) {
|
|
244
|
+
if (this.serverApi === undefined) {
|
|
245
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Configure serverUrl before enabling Host access.', false);
|
|
246
|
+
}
|
|
247
|
+
let result;
|
|
248
|
+
try {
|
|
249
|
+
result = await this.serverApi.authorizeOwnedRole(this.currentIdentity(), accessToken, account);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (!(error instanceof ServerApiError) || error.code !== 'DEVICE_REVOKED')
|
|
253
|
+
throw error;
|
|
254
|
+
await this.serverConnection?.stop();
|
|
255
|
+
this.identity = await this.identities.reset(this.config.deviceName);
|
|
256
|
+
this.serverApi.bindIdentity(this.identity);
|
|
257
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
258
|
+
result = await this.serverApi.authorizeOwnedRole(this.identity, accessToken, account);
|
|
259
|
+
this.logger.info('Rotated revoked Host identity before owned-device authorization');
|
|
260
|
+
}
|
|
261
|
+
// An authorization does not lift an explicit pause: the UI shows the paused
|
|
262
|
+
// state with its own resume action, so the user's choice stays in force.
|
|
263
|
+
if (!this.paused)
|
|
264
|
+
this.serverConnection?.resume();
|
|
265
|
+
this.logger.info('Host authorized as an owned device');
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
async authorizeHostWithAccount(email, password) {
|
|
269
|
+
if (this.serverApi === undefined) {
|
|
270
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Configure serverUrl before signing in.', false);
|
|
271
|
+
}
|
|
272
|
+
const result = await this.serverApi.authorizeWithAccount(this.currentIdentity(), email, password);
|
|
273
|
+
// An authorization does not lift an explicit pause: the UI shows the paused
|
|
274
|
+
// state with its own resume action, so the user's choice stays in force.
|
|
275
|
+
if (!this.paused)
|
|
276
|
+
this.serverConnection?.resume();
|
|
277
|
+
this.logger.info('Host account authorized');
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
async authorizeHostWithCode(code) {
|
|
281
|
+
if (this.serverApi === undefined) {
|
|
282
|
+
throw new ServerApiError('SERVER_NOT_CONFIGURED', 'Configure serverUrl before entering a Host registration code.', false);
|
|
283
|
+
}
|
|
284
|
+
const result = await this.serverApi.authorizeHostWithCode(this.currentIdentity(), code);
|
|
285
|
+
// An authorization does not lift an explicit pause: the UI shows the paused
|
|
286
|
+
// state with its own resume action, so the user's choice stays in force.
|
|
287
|
+
if (!this.paused)
|
|
288
|
+
this.serverConnection?.resume();
|
|
289
|
+
this.logger.info('Host registration code authorized');
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
async revokePeer(deviceId) {
|
|
293
|
+
const revoked = await this.identities.revokePeer(deviceId);
|
|
294
|
+
if (revoked)
|
|
295
|
+
await this.connections.revoke(deviceId);
|
|
296
|
+
return revoked;
|
|
297
|
+
}
|
|
298
|
+
codexStatus() {
|
|
299
|
+
return this.codex.status();
|
|
300
|
+
}
|
|
301
|
+
codexCall(input) {
|
|
302
|
+
return this.requireLocalCodexPeer().call(input);
|
|
303
|
+
}
|
|
304
|
+
codexRespond(input) {
|
|
305
|
+
return this.requireLocalCodexPeer().respond(input);
|
|
306
|
+
}
|
|
307
|
+
codexOpenStream(input, publish) {
|
|
308
|
+
this.localCodexPublish = publish;
|
|
309
|
+
return this.requireLocalCodexPeer().openStream(input);
|
|
310
|
+
}
|
|
311
|
+
async codexCloseStream(input) {
|
|
312
|
+
const peer = this.localCodexPeer;
|
|
313
|
+
if (peer !== undefined)
|
|
314
|
+
return peer.closeStream(input);
|
|
315
|
+
const streamId = isPlainRecord(input) && typeof input.streamId === 'string' ? input.streamId : undefined;
|
|
316
|
+
if (streamId === undefined)
|
|
317
|
+
throw new RpcError('INVALID_MESSAGE', 'A Codex stream is required.');
|
|
318
|
+
return { closed: false, streamId };
|
|
319
|
+
}
|
|
320
|
+
async close() {
|
|
321
|
+
if (this.closed)
|
|
322
|
+
return;
|
|
323
|
+
this.closed = true;
|
|
324
|
+
await this.serverConnection?.stop();
|
|
325
|
+
await this.connections.close();
|
|
326
|
+
await this.localCodexPeer?.closeAll();
|
|
327
|
+
this.localCodexPeer = undefined;
|
|
328
|
+
await this.codex.close();
|
|
329
|
+
this.logger.info('host runtime stopped');
|
|
330
|
+
}
|
|
331
|
+
diagnostics() {
|
|
332
|
+
return {
|
|
333
|
+
loaded: this.identity !== undefined,
|
|
334
|
+
deviceId: this.identity === undefined ? undefined : shortId(this.identity.deviceId),
|
|
335
|
+
identityValid: this.identity !== undefined,
|
|
336
|
+
serverConfigured: this.config.serverUrl !== undefined,
|
|
337
|
+
serverOnline: this.serverConnection?.isOnline() ?? false,
|
|
338
|
+
serverError: this.serverConnection?.lastError(),
|
|
339
|
+
online: this.connections.isOnline(),
|
|
340
|
+
activeConnections: this.connections.connectionCount(),
|
|
341
|
+
peerDeviceId: this.connections.peerDeviceId() === undefined ? undefined : shortId(this.connections.peerDeviceId()),
|
|
342
|
+
peerDeviceIds: this.connections.peerDeviceIds().map(shortId),
|
|
343
|
+
trustedPeers: this.identities.listTrustedPeers().length,
|
|
344
|
+
capabilities: this.hostCapabilities(),
|
|
345
|
+
codex: this.codex.status(),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
createServerConnection(identity) {
|
|
349
|
+
return new HostServerConnection(this.config, identity, this.identities, this.serverApi, this.connections, this.logger, undefined, this.config.forceRelay
|
|
350
|
+
? undefined
|
|
351
|
+
: () => loadNodeRtcFactory({ routeTargets: this.config.serverUrl === undefined ? [] : [this.config.serverUrl] }), () => this.hostCapabilities(), this.harnessVersion);
|
|
352
|
+
}
|
|
353
|
+
async readHarnessVersion() {
|
|
354
|
+
let reportedVersion;
|
|
355
|
+
let errorCode;
|
|
356
|
+
try {
|
|
357
|
+
const response = await this.apiProxy?.host.describe({ rpcId: randomUUID(), payload: {} });
|
|
358
|
+
if (response === undefined)
|
|
359
|
+
throw new Error('ApiProxy is unavailable');
|
|
360
|
+
if (!response.result.ok) {
|
|
361
|
+
errorCode = response.result.error.code;
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
reportedVersion = normalizeHarnessVersion(response.result.value.version);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Older Harness builds may not expose host.describe.
|
|
369
|
+
}
|
|
370
|
+
const distributionVersion = reportedVersion === undefined || reportedVersion === '0.0.1'
|
|
371
|
+
? await readHarnessDistributionVersion()
|
|
372
|
+
: undefined;
|
|
373
|
+
const version = selectHarnessVersion(reportedVersion, distributionVersion);
|
|
374
|
+
if (version !== undefined)
|
|
375
|
+
return version;
|
|
376
|
+
this.logger.warn('Harness version is unavailable', errorCode === undefined ? undefined : { code: errorCode });
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
hostCapabilities() {
|
|
380
|
+
const capabilities = [];
|
|
381
|
+
if (this.loopbackPorts.length > 0)
|
|
382
|
+
capabilities.push('loopback.http-ws.v1');
|
|
383
|
+
if (this.localGateway?.supportsCarrier === true) {
|
|
384
|
+
capabilities.push(harnessSessionGeneration(this.harnessVersion) === 'v3' ? 'harness.remote.v3' : 'harness.remote.v1', 'harness.remote.transfer.v1');
|
|
385
|
+
}
|
|
386
|
+
if (this.localGateway?.supportsCarrier && this.terminalEnabled)
|
|
387
|
+
capabilities.push('harness.terminal.v1');
|
|
388
|
+
if (this.apiProxy !== undefined) {
|
|
389
|
+
capabilities.push('harness.api.v1', 'harness.api.transfer.v1');
|
|
390
|
+
}
|
|
391
|
+
if (this.fileViewerHost?.() !== undefined)
|
|
392
|
+
capabilities.push('fileviewer.read.v1');
|
|
393
|
+
if (this.codex.isAvailable())
|
|
394
|
+
capabilities.push('codex.appserver.v1', 'codex.appserver.transfer.v1');
|
|
395
|
+
if (this.config.acp?.enabled)
|
|
396
|
+
for (const item of this.config.acp.backends)
|
|
397
|
+
if (item.enabled && this.acpAvailable(item.command))
|
|
398
|
+
capabilities.push(`agent.acp.v1.${item.id}`);
|
|
399
|
+
return capabilities;
|
|
400
|
+
}
|
|
401
|
+
acpAvailable(command) {
|
|
402
|
+
try {
|
|
403
|
+
execFileSync(process.platform === 'win32' ? 'where' : 'which', [command], { stdio: 'ignore' });
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
requireLocalCodexPeer() {
|
|
411
|
+
if (!this.codex.isAvailable()) {
|
|
412
|
+
throw new RpcError('CODEX_UNAVAILABLE', 'Local CodeX is disabled or unavailable on this Host.');
|
|
413
|
+
}
|
|
414
|
+
if (this.localCodexPeer !== undefined)
|
|
415
|
+
return this.localCodexPeer;
|
|
416
|
+
const identity = this.currentIdentity();
|
|
417
|
+
const peer = this.codex.createPeer({
|
|
418
|
+
connectionId: `loopback:${identity.deviceId}`,
|
|
419
|
+
peerDeviceId: identity.deviceId,
|
|
420
|
+
}, (event, data) => this.localCodexPublish(event, data));
|
|
421
|
+
if (peer === undefined) {
|
|
422
|
+
throw new RpcError('CODEX_UNAVAILABLE', 'Local CodeX is disabled or unavailable on this Host.');
|
|
423
|
+
}
|
|
424
|
+
this.localCodexPeer = peer;
|
|
425
|
+
return peer;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function shortId(value) { return value.length <= 12 ? value : `${value.slice(0, 8)}…${value.slice(-4)}`; }
|
|
429
|
+
function isPlainRecord(value) {
|
|
430
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-format-compat.d.ts","sourceRoot":"","sources":["../src/session-format-compat.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG,cAAc,CAAA;AAEvD,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAI5F"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
export function normalizeLegacySessionGatewayValue(endpoint, value) {
|
|
2
|
+
if (endpoint === 'session/page')
|
|
3
|
+
return normalizePage(value);
|
|
4
|
+
if (endpoint === 'session/follow')
|
|
5
|
+
return normalizeFollowFrame(value);
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
function normalizeFollowFrame(value) {
|
|
9
|
+
if (!isRecord(value))
|
|
10
|
+
return value;
|
|
11
|
+
if (value.type === 'snapshot') {
|
|
12
|
+
return {
|
|
13
|
+
...value,
|
|
14
|
+
header: normalizeHeader(value.header),
|
|
15
|
+
records: normalizeRecords(value.records),
|
|
16
|
+
...(value.assistantStream === undefined ? { assistantStream: { revision: 0 } } : {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return normalizeEntry(value);
|
|
20
|
+
}
|
|
21
|
+
function normalizePage(value) {
|
|
22
|
+
if (!isRecord(value))
|
|
23
|
+
return value;
|
|
24
|
+
return { ...value, records: normalizeRecords(value.records) };
|
|
25
|
+
}
|
|
26
|
+
function normalizeRecords(value) {
|
|
27
|
+
if (!Array.isArray(value))
|
|
28
|
+
return value;
|
|
29
|
+
const records = [];
|
|
30
|
+
let previousSeq;
|
|
31
|
+
for (const record of value) {
|
|
32
|
+
if (!isEventEntry(record))
|
|
33
|
+
continue;
|
|
34
|
+
const seq = entrySeq(record);
|
|
35
|
+
if (previousSeq !== undefined && seq !== undefined && seq > previousSeq + 1) {
|
|
36
|
+
for (let fillerSeq = previousSeq + 1; fillerSeq < seq; fillerSeq += 1) {
|
|
37
|
+
records.push(createLegacyGapRecord(fillerSeq, record));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
records.push(normalizeEntry(record));
|
|
41
|
+
if (seq !== undefined)
|
|
42
|
+
previousSeq = seq;
|
|
43
|
+
}
|
|
44
|
+
return records;
|
|
45
|
+
}
|
|
46
|
+
function normalizeEntry(value) {
|
|
47
|
+
if (!isEventEntry(value))
|
|
48
|
+
return value;
|
|
49
|
+
return { ...value, event: normalizeEvent(value.event) };
|
|
50
|
+
}
|
|
51
|
+
function entrySeq(value) {
|
|
52
|
+
if (!isEventEntry(value))
|
|
53
|
+
return undefined;
|
|
54
|
+
return isEventSeq(value.event.seq) ? value.event.seq : undefined;
|
|
55
|
+
}
|
|
56
|
+
function createLegacyGapRecord(seq, nextRecord) {
|
|
57
|
+
return {
|
|
58
|
+
type: 'event',
|
|
59
|
+
event: {
|
|
60
|
+
type: 'legacy/session-gap',
|
|
61
|
+
seq,
|
|
62
|
+
time: eventTime(nextRecord),
|
|
63
|
+
ignorable: true,
|
|
64
|
+
data: {},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function eventTime(value) {
|
|
69
|
+
if (!isEventEntry(value))
|
|
70
|
+
return 0;
|
|
71
|
+
return typeof value.event.time === 'number' && Number.isSafeInteger(value.event.time)
|
|
72
|
+
? value.event.time
|
|
73
|
+
: 0;
|
|
74
|
+
}
|
|
75
|
+
function isEventEntry(value) {
|
|
76
|
+
return isRecord(value) && value.type === 'event' && isRecord(value.event);
|
|
77
|
+
}
|
|
78
|
+
function normalizeHeader(value) {
|
|
79
|
+
if (!isRecord(value))
|
|
80
|
+
return value;
|
|
81
|
+
const next = {
|
|
82
|
+
...value,
|
|
83
|
+
version: 3,
|
|
84
|
+
...(value.delegationDepth === undefined ? { delegationDepth: 0 } : {}),
|
|
85
|
+
};
|
|
86
|
+
return next.agentPreset === 'code' ? { ...next, agentPreset: 'ptc' } : next;
|
|
87
|
+
}
|
|
88
|
+
function normalizeEvent(value) {
|
|
89
|
+
if (!isRecord(value))
|
|
90
|
+
return value;
|
|
91
|
+
let next = value;
|
|
92
|
+
const type = normalizeEventType(value.type);
|
|
93
|
+
if (type !== value.type)
|
|
94
|
+
next = { ...next, type };
|
|
95
|
+
if (type === 'assistant/message' && Object.hasOwn(next, 'sourceEventSeqs')) {
|
|
96
|
+
const { sourceEventSeqs: _sourceEventSeqs, ...rest } = next;
|
|
97
|
+
next = rest;
|
|
98
|
+
}
|
|
99
|
+
const data = normalizeEventData(type, next.data);
|
|
100
|
+
if (data !== next.data)
|
|
101
|
+
next = { ...next, data };
|
|
102
|
+
const surfaceOp = normalizeSurfaceOp(next.surfaceOp);
|
|
103
|
+
if (surfaceOp !== next.surfaceOp)
|
|
104
|
+
next = { ...next, surfaceOp };
|
|
105
|
+
return next;
|
|
106
|
+
}
|
|
107
|
+
function normalizeEventType(value) {
|
|
108
|
+
if (value === 'tool/code-dispatch-start')
|
|
109
|
+
return 'tool/ptc-dispatch-start';
|
|
110
|
+
if (value === 'tool/code-dispatch')
|
|
111
|
+
return 'tool/ptc-dispatch';
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
function normalizeEventData(type, value) {
|
|
115
|
+
if (!isRecord(value))
|
|
116
|
+
return value;
|
|
117
|
+
if (type === 'request/header')
|
|
118
|
+
return normalizeRequestHeaderData(value);
|
|
119
|
+
if (type === 'agent-preset/selected' && value.agentPreset === 'code')
|
|
120
|
+
return { ...value, agentPreset: 'ptc' };
|
|
121
|
+
if (type === 'user/message')
|
|
122
|
+
return normalizeMessage(value);
|
|
123
|
+
if (type === 'agent/inbox/spliced' && Array.isArray(value.inserted)) {
|
|
124
|
+
return { ...value, inserted: value.inserted.map(item => normalizeMessage(item)) };
|
|
125
|
+
}
|
|
126
|
+
if (type === 'session/title-llm-request' && Array.isArray(value.messages)) {
|
|
127
|
+
return { ...value, messages: value.messages.map(item => normalizeMessage(item)) };
|
|
128
|
+
}
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
function normalizeRequestHeaderData(value) {
|
|
132
|
+
if (!isRecord(value.header))
|
|
133
|
+
return value;
|
|
134
|
+
const header = normalizeRequestHeader(value.header);
|
|
135
|
+
return header === value.header ? value : { ...value, header };
|
|
136
|
+
}
|
|
137
|
+
function normalizeRequestHeader(value) {
|
|
138
|
+
let changed = false;
|
|
139
|
+
const next = {};
|
|
140
|
+
for (const [key, field] of Object.entries(value)) {
|
|
141
|
+
if (key === 'system') {
|
|
142
|
+
changed = true;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (key === 'tools' && Array.isArray(field) && field.length === 0) {
|
|
146
|
+
changed = true;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (key === 'adapterDefaults' && isRecord(field) && Object.keys(field).length === 0) {
|
|
150
|
+
changed = true;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
next[key] = field;
|
|
154
|
+
}
|
|
155
|
+
return changed ? next : value;
|
|
156
|
+
}
|
|
157
|
+
function normalizeMessage(value) {
|
|
158
|
+
if (!isRecord(value) || !isRecord(value.source))
|
|
159
|
+
return value;
|
|
160
|
+
if (value.source.kind !== 'plugin' || value.source.plugin !== 'tools-code-mode')
|
|
161
|
+
return value;
|
|
162
|
+
return { ...value, source: { ...value.source, plugin: 'tools-ptc' } };
|
|
163
|
+
}
|
|
164
|
+
function normalizeSurfaceOp(value) {
|
|
165
|
+
if (!isRecord(value) || value.op !== 'replace')
|
|
166
|
+
return value;
|
|
167
|
+
const { start, end, ...rest } = value;
|
|
168
|
+
if (start === undefined && end === undefined)
|
|
169
|
+
return value;
|
|
170
|
+
return {
|
|
171
|
+
...rest,
|
|
172
|
+
op: 'replace',
|
|
173
|
+
...(start === undefined ? {} : { startSeq: start }),
|
|
174
|
+
...(end === undefined ? {} : { endSeq: end }),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function isRecord(value) {
|
|
178
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
179
|
+
}
|
|
180
|
+
function isEventSeq(value) {
|
|
181
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=session-format-compat.js.map
|