ds-harness-remote 0.3.8

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.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -0
  3. package/cordis.patch.yml +7 -0
  4. package/dist/adapters/agent-adapter.d.ts +35 -0
  5. package/dist/adapters/agent-adapter.d.ts.map +1 -0
  6. package/dist/adapters/agent-adapter.js +80 -0
  7. package/dist/adapters/agent-adapter.js.map +1 -0
  8. package/dist/adapters/permission-adapter.d.ts +13 -0
  9. package/dist/adapters/permission-adapter.d.ts.map +1 -0
  10. package/dist/adapters/permission-adapter.js +67 -0
  11. package/dist/adapters/permission-adapter.js.map +1 -0
  12. package/dist/adapters/session-adapter.d.ts +38 -0
  13. package/dist/adapters/session-adapter.d.ts.map +1 -0
  14. package/dist/adapters/session-adapter.js +230 -0
  15. package/dist/adapters/session-adapter.js.map +1 -0
  16. package/dist/adapters/workspace-adapter.d.ts +13 -0
  17. package/dist/adapters/workspace-adapter.d.ts.map +1 -0
  18. package/dist/adapters/workspace-adapter.js +21 -0
  19. package/dist/adapters/workspace-adapter.js.map +1 -0
  20. package/dist/api-proxy-switch.d.ts +33 -0
  21. package/dist/api-proxy-switch.d.ts.map +1 -0
  22. package/dist/api-proxy-switch.js +107 -0
  23. package/dist/api-proxy-switch.js.map +1 -0
  24. package/dist/bin/doctor.d.ts +3 -0
  25. package/dist/bin/doctor.d.ts.map +1 -0
  26. package/dist/bin/doctor.js +13 -0
  27. package/dist/bin/doctor.js.map +1 -0
  28. package/dist/client-runtime.d.ts +98 -0
  29. package/dist/client-runtime.d.ts.map +1 -0
  30. package/dist/client-runtime.js +421 -0
  31. package/dist/client-runtime.js.map +1 -0
  32. package/dist/client-secure-transport.d.ts +22 -0
  33. package/dist/client-secure-transport.d.ts.map +1 -0
  34. package/dist/client-secure-transport.js +129 -0
  35. package/dist/client-secure-transport.js.map +1 -0
  36. package/dist/client.d.ts +12 -0
  37. package/dist/client.d.ts.map +1 -0
  38. package/dist/client.github.js +2938 -0
  39. package/dist/client.js +2938 -0
  40. package/dist/client.js.map +1 -0
  41. package/dist/config.d.ts +33 -0
  42. package/dist/config.d.ts.map +1 -0
  43. package/dist/config.js +80 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/connection-controller.d.ts +39 -0
  46. package/dist/connection-controller.d.ts.map +1 -0
  47. package/dist/connection-controller.js +170 -0
  48. package/dist/connection-controller.js.map +1 -0
  49. package/dist/control-runtime.d.ts +36 -0
  50. package/dist/control-runtime.d.ts.map +1 -0
  51. package/dist/control-runtime.js +265 -0
  52. package/dist/control-runtime.js.map +1 -0
  53. package/dist/event-sequencer.d.ts +23 -0
  54. package/dist/event-sequencer.d.ts.map +1 -0
  55. package/dist/event-sequencer.js +54 -0
  56. package/dist/event-sequencer.js.map +1 -0
  57. package/dist/harness-api-bridge.d.ts +55 -0
  58. package/dist/harness-api-bridge.d.ts.map +1 -0
  59. package/dist/harness-api-bridge.js +387 -0
  60. package/dist/harness-api-bridge.js.map +1 -0
  61. package/dist/identity-store.d.ts +45 -0
  62. package/dist/identity-store.d.ts.map +1 -0
  63. package/dist/identity-store.js +183 -0
  64. package/dist/identity-store.js.map +1 -0
  65. package/dist/ids.d.ts +2 -0
  66. package/dist/ids.d.ts.map +1 -0
  67. package/dist/ids.js +17 -0
  68. package/dist/ids.js.map +1 -0
  69. package/dist/index.d.ts +38 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +16091 -0
  72. package/dist/index.js.map +7 -0
  73. package/dist/logging.d.ts +18 -0
  74. package/dist/logging.d.ts.map +1 -0
  75. package/dist/logging.js +30 -0
  76. package/dist/logging.js.map +1 -0
  77. package/dist/pairing-controller.d.ts +52 -0
  78. package/dist/pairing-controller.d.ts.map +1 -0
  79. package/dist/pairing-controller.js +73 -0
  80. package/dist/pairing-controller.js.map +1 -0
  81. package/dist/pending-approvals.d.ts +14 -0
  82. package/dist/pending-approvals.d.ts.map +1 -0
  83. package/dist/pending-approvals.js +52 -0
  84. package/dist/pending-approvals.js.map +1 -0
  85. package/dist/remote-api-proxy.d.ts +12 -0
  86. package/dist/remote-api-proxy.d.ts.map +1 -0
  87. package/dist/remote-api-proxy.js +191 -0
  88. package/dist/remote-api-proxy.js.map +1 -0
  89. package/dist/remote-directory-browser.d.ts +16 -0
  90. package/dist/remote-directory-browser.d.ts.map +1 -0
  91. package/dist/remote-directory-browser.js +48 -0
  92. package/dist/remote-directory-browser.js.map +1 -0
  93. package/dist/rpc-router.d.ts +21 -0
  94. package/dist/rpc-router.d.ts.map +1 -0
  95. package/dist/rpc-router.js +93 -0
  96. package/dist/rpc-router.js.map +1 -0
  97. package/dist/server-api.d.ts +80 -0
  98. package/dist/server-api.d.ts.map +1 -0
  99. package/dist/server-api.js +405 -0
  100. package/dist/server-api.js.map +1 -0
  101. package/dist/server-connection.d.ts +70 -0
  102. package/dist/server-connection.d.ts.map +1 -0
  103. package/dist/server-connection.js +759 -0
  104. package/dist/server-connection.js.map +1 -0
  105. package/dist/server-credentials.d.ts +46 -0
  106. package/dist/server-credentials.d.ts.map +1 -0
  107. package/dist/server-credentials.js +71 -0
  108. package/dist/server-credentials.js.map +1 -0
  109. package/dist/service.d.ts +56 -0
  110. package/dist/service.d.ts.map +1 -0
  111. package/dist/service.js +162 -0
  112. package/dist/service.js.map +1 -0
  113. package/dist/typert-gateway-switch.d.ts +19 -0
  114. package/dist/typert-gateway-switch.d.ts.map +1 -0
  115. package/dist/typert-gateway-switch.js +41 -0
  116. package/dist/typert-gateway-switch.js.map +1 -0
  117. package/dist/types.d.ts +20 -0
  118. package/dist/types.d.ts.map +1 -0
  119. package/dist/types.js +2 -0
  120. package/dist/types.js.map +1 -0
  121. package/dist/version.d.ts +12 -0
  122. package/dist/version.d.ts.map +1 -0
  123. package/dist/version.js +12 -0
  124. package/dist/version.js.map +1 -0
  125. package/dist/werift-rtc.d.ts +85 -0
  126. package/dist/werift-rtc.d.ts.map +1 -0
  127. package/dist/werift-rtc.js +164 -0
  128. package/dist/werift-rtc.js.map +1 -0
  129. package/package.json +98 -0
  130. package/public.d.ts +19 -0
@@ -0,0 +1,265 @@
1
+ import { hostname } from 'node:os';
2
+ import { resolveConfig } from './config.js';
3
+ import { ClientModeError, } from './client-runtime.js';
4
+ import { IdentityStore, serverStorageDirectory } from './identity-store.js';
5
+ import { ClientServerApi, HostServerApi } from './server-api.js';
6
+ import { ServerCredentialStore } from './server-credentials.js';
7
+ /** Loopback-only control plane shared by Local/Remote switching and plugin setup. */
8
+ export class PluginControlRuntime {
9
+ config;
10
+ identityDirectory;
11
+ settings;
12
+ client;
13
+ host;
14
+ constructor(config, identityDirectory, settings, client, host) {
15
+ this.config = config;
16
+ this.identityDirectory = identityDirectory;
17
+ this.settings = settings;
18
+ this.client = client;
19
+ this.host = host;
20
+ }
21
+ register(connection) {
22
+ return connection.rpc.handle('/remote', (endpoint, payload, signal) => this.handle(endpoint, payload, signal), {
23
+ authority: 'loopback',
24
+ });
25
+ }
26
+ async handle(endpoint, payload, signal) {
27
+ try {
28
+ if (endpoint === 'settings.get')
29
+ return ok(await this.settingsView());
30
+ if (endpoint === 'settings.configure')
31
+ return ok(await this.configure(payload));
32
+ if (endpoint === 'settings.server.set')
33
+ return ok(await this.setServer(payload));
34
+ if (endpoint === 'settings.role.set')
35
+ return ok(await this.setRole(payload));
36
+ if (endpoint === 'settings.logout')
37
+ return ok(await this.logout());
38
+ if (endpoint === 'host.reconnect') {
39
+ if (this.host === undefined)
40
+ throw new ClientModeError('METHOD_NOT_ALLOWED', 'This plugin is not running as a Host.');
41
+ this.host.reconnectHost();
42
+ return ok(this.hostOnlyStatus());
43
+ }
44
+ if (this.client !== undefined)
45
+ return this.client.handleControl(endpoint, payload, signal);
46
+ if (endpoint === 'status')
47
+ return ok(this.hostOnlyStatus());
48
+ if (endpoint === 'devices')
49
+ return ok([]);
50
+ if (endpoint === 'host.account.login') {
51
+ if (this.host === undefined)
52
+ throw new ClientModeError('METHOD_NOT_ALLOWED', 'This plugin is not running as a Host.');
53
+ const value = record(payload);
54
+ if (typeof value.email !== 'string' || typeof value.password !== 'string') {
55
+ throw new ClientModeError('INVALID_MESSAGE', 'Email and password are required.');
56
+ }
57
+ return ok(await this.host.authorizeHostWithAccount(value.email, value.password));
58
+ }
59
+ if (endpoint === 'host.registration-code.submit') {
60
+ if (this.host === undefined)
61
+ throw new ClientModeError('METHOD_NOT_ALLOWED', 'This plugin is not running as a Host.');
62
+ const value = record(payload);
63
+ if (typeof value.code !== 'string' || value.code.trim() === '') {
64
+ throw new ClientModeError('INVALID_MESSAGE', 'A Host registration code is required.');
65
+ }
66
+ return ok(await this.host.authorizeHostWithCode(value.code));
67
+ }
68
+ if (endpoint === 'mode.set' && record(payload).mode === 'local')
69
+ return ok(this.hostOnlyStatus());
70
+ throw new ClientModeError('METHOD_NOT_ALLOWED', 'Remote Client mode is disabled by the plugin role.');
71
+ }
72
+ catch (error) {
73
+ return fail(error);
74
+ }
75
+ }
76
+ async configure(payload) {
77
+ if (this.settings === undefined) {
78
+ throw new ClientModeError('SETTINGS_UNAVAILABLE', 'DSH user settings are unavailable in this profile.');
79
+ }
80
+ const value = record(payload);
81
+ if (value.role !== 'host' && value.role !== 'client') {
82
+ throw new ClientModeError('INVALID_MESSAGE', 'Role must be Host or Client.');
83
+ }
84
+ if (typeof value.serverUrl !== 'string') {
85
+ throw new ClientModeError('INVALID_MESSAGE', 'Server URL is required.');
86
+ }
87
+ const current = editableConfig(resolveConfig(this.settings.get()));
88
+ const next = resolveConfig({ ...current, role: value.role, serverUrl: value.serverUrl });
89
+ const identities = new IdentityStore({
90
+ directory: serverStorageDirectory(this.identityDirectory, next.serverUrl, value.role),
91
+ });
92
+ const identity = await identities.loadOrCreate(hostname());
93
+ const api = value.role === 'host'
94
+ ? new HostServerApi(next.serverUrl, new ServerCredentialStore(identities.directory))
95
+ : new ClientServerApi(next.serverUrl, new ServerCredentialStore(identities.directory));
96
+ let authorization;
97
+ if (value.role === 'host' && typeof value.registrationCode === 'string' && value.registrationCode.trim() !== '') {
98
+ authorization = await api.authorizeHostWithCode(identity, value.registrationCode);
99
+ }
100
+ else {
101
+ if (typeof value.email !== 'string' || typeof value.password !== 'string') {
102
+ throw new ClientModeError('INVALID_MESSAGE', 'Email and password are required for account authorization.');
103
+ }
104
+ authorization = await api.authorizeWithAccount(identity, value.email, value.password);
105
+ }
106
+ await this.settings.replace(editableConfig(next));
107
+ return {
108
+ status: 'authorized',
109
+ role: value.role,
110
+ ...(authorization.account === undefined ? {} : { account: authorization.account }),
111
+ settings: await this.settingsView(),
112
+ };
113
+ }
114
+ async setServer(payload) {
115
+ if (this.settings === undefined) {
116
+ throw new ClientModeError('SETTINGS_UNAVAILABLE', 'DSH user settings are unavailable in this profile.');
117
+ }
118
+ const value = record(payload);
119
+ if (typeof value.serverUrl !== 'string') {
120
+ throw new ClientModeError('INVALID_MESSAGE', 'Server URL is required.');
121
+ }
122
+ const current = editableConfig(resolveConfig(this.settings.get()));
123
+ const next = resolveConfig({ ...current, serverUrl: value.serverUrl });
124
+ await this.settings.replace(editableConfig(next));
125
+ return this.settingsView();
126
+ }
127
+ async setRole(payload) {
128
+ if (this.settings === undefined) {
129
+ throw new ClientModeError('SETTINGS_UNAVAILABLE', 'DSH user settings are unavailable in this profile.');
130
+ }
131
+ const role = record(payload).role;
132
+ if (role !== 'host' && role !== 'client') {
133
+ throw new ClientModeError('INVALID_MESSAGE', 'Role must be Host or Client.');
134
+ }
135
+ const current = editableConfig(resolveConfig(this.settings.get()));
136
+ const currentRole = current.role === 'client' ? 'client' : 'host';
137
+ if (role !== currentRole && current.serverUrl !== undefined
138
+ && await this.association(current.serverUrl, role) === undefined) {
139
+ await this.authorizeOwnedRole(current.serverUrl, currentRole, role);
140
+ }
141
+ await this.settings.replace({ ...current, role });
142
+ return this.settingsView();
143
+ }
144
+ async authorizeOwnedRole(serverUrl, sourceRole, targetRole) {
145
+ const sourceDirectory = serverStorageDirectory(this.identityDirectory, serverUrl, sourceRole);
146
+ const sourceIdentity = await new IdentityStore({ directory: sourceDirectory }).loadOrCreate(hostname());
147
+ const sourceStore = new ServerCredentialStore(sourceDirectory);
148
+ if (await sourceStore.load(serverUrl, sourceIdentity.deviceId) === undefined)
149
+ return;
150
+ const sourceApi = sourceRole === 'host'
151
+ ? new HostServerApi(serverUrl, sourceStore)
152
+ : new ClientServerApi(serverUrl, sourceStore);
153
+ const sourceCredentials = await sourceApi.authenticate(sourceIdentity);
154
+ const targetDirectory = serverStorageDirectory(this.identityDirectory, serverUrl, targetRole);
155
+ const targetIdentity = await new IdentityStore({ directory: targetDirectory }).loadOrCreate(hostname());
156
+ const targetApi = targetRole === 'host'
157
+ ? new HostServerApi(serverUrl, new ServerCredentialStore(targetDirectory))
158
+ : new ClientServerApi(serverUrl, new ServerCredentialStore(targetDirectory));
159
+ await targetApi.authorizeOwnedRole(targetIdentity, sourceCredentials.accessToken, sourceCredentials.account);
160
+ }
161
+ async logout() {
162
+ if (this.settings === undefined) {
163
+ throw new ClientModeError('SETTINGS_UNAVAILABLE', 'DSH user settings are unavailable in this profile.');
164
+ }
165
+ const config = resolveConfig(this.settings.get());
166
+ if (config.serverUrl !== undefined) {
167
+ await Promise.all([
168
+ this.client?.clearClientAuthorization(),
169
+ this.host?.clearHostAuthorization(),
170
+ ]);
171
+ await Promise.all(['host', 'client'].map(async (role) => {
172
+ const directory = serverStorageDirectory(this.identityDirectory, config.serverUrl, role);
173
+ await new ServerCredentialStore(directory).clear();
174
+ }));
175
+ }
176
+ return this.settingsView();
177
+ }
178
+ async settingsView() {
179
+ const config = this.settings === undefined ? editableConfig(this.config) : editableConfig(resolveConfig(this.settings.get()));
180
+ const associations = await this.associations(config);
181
+ const role = config.role === 'client' ? 'client' : 'host';
182
+ const association = associations[role];
183
+ return {
184
+ config,
185
+ deviceName: hostname(),
186
+ writable: this.settings !== undefined,
187
+ applies: 'restart',
188
+ associations,
189
+ ...(association === undefined ? {} : { association }),
190
+ };
191
+ }
192
+ async associations(config) {
193
+ if (config.serverUrl === undefined)
194
+ return {};
195
+ const [host, client] = await Promise.all([
196
+ this.association(config.serverUrl, 'host'),
197
+ this.association(config.serverUrl, 'client'),
198
+ ]);
199
+ return {
200
+ ...(host === undefined ? {} : { host }),
201
+ ...(client === undefined ? {} : { client }),
202
+ };
203
+ }
204
+ async association(serverUrl, role) {
205
+ const identities = new IdentityStore({
206
+ directory: serverStorageDirectory(this.identityDirectory, serverUrl, role),
207
+ });
208
+ const identity = await identities.loadOrCreate(hostname());
209
+ const credentials = await new ServerCredentialStore(identities.directory).load(serverUrl, identity.deviceId);
210
+ if (credentials === undefined)
211
+ return undefined;
212
+ return {
213
+ method: credentials.authorizationMethod,
214
+ ...(credentials.account === undefined ? {} : { account: credentials.account }),
215
+ };
216
+ }
217
+ hostOnlyStatus() {
218
+ return {
219
+ mode: 'local',
220
+ available: false,
221
+ hostAuthorizationAvailable: this.host !== undefined,
222
+ ...(this.host === undefined ? {} : { host: this.host.hostStatus() }),
223
+ };
224
+ }
225
+ }
226
+ function editableConfig(config) {
227
+ return {
228
+ enabled: config.enabled,
229
+ role: config.role,
230
+ ...(config.serverUrl === undefined ? {} : { serverUrl: config.serverUrl }),
231
+ forceRelay: config.forceRelay,
232
+ logLevel: config.logLevel,
233
+ reconnect: config.reconnect.enabled
234
+ ? {
235
+ initialDelayMs: config.reconnect.initialDelayMs,
236
+ maxDelayMs: config.reconnect.maxDelayMs,
237
+ jitter: config.reconnect.jitter,
238
+ }
239
+ : false,
240
+ };
241
+ }
242
+ function isRecord(value) {
243
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
244
+ }
245
+ function record(value) {
246
+ if (!isRecord(value))
247
+ throw new ClientModeError('INVALID_MESSAGE', 'The control request payload is invalid.');
248
+ return value;
249
+ }
250
+ function ok(value) { return { ok: true, value }; }
251
+ function fail(error) {
252
+ const source = error instanceof Error ? error : undefined;
253
+ const remoteCode = source !== undefined && 'code' in source && typeof source.code === 'string'
254
+ ? source.code
255
+ : source instanceof ClientModeError ? source.code : undefined;
256
+ return {
257
+ ok: false,
258
+ error: {
259
+ code: 'internal',
260
+ message: source?.message ?? 'The plugin control operation failed.',
261
+ details: remoteCode === undefined ? {} : { remoteCode },
262
+ },
263
+ };
264
+ }
265
+ //# sourceMappingURL=control-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-runtime.js","sourceRoot":"","sources":["../src/control-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type EventPayload, type RemoteEventName, type RemoteMessage } from '@dsh-remote/protocol';
2
+ export interface ReplayResult {
3
+ events: RemoteMessage<EventPayload>[];
4
+ lastSeq: number;
5
+ hasMore: boolean;
6
+ }
7
+ export declare class FullResyncRequiredError extends Error {
8
+ readonly currentSeq: number;
9
+ readonly code = "FULL_RESYNC_REQUIRED";
10
+ constructor(currentSeq: number);
11
+ }
12
+ export declare class EventSequencer {
13
+ private readonly maxEvents;
14
+ private readonly maxAgeMs;
15
+ private seq;
16
+ private readonly events;
17
+ constructor(maxEvents?: number, maxAgeMs?: number);
18
+ currentSeq(): number;
19
+ publish<TData>(event: RemoteEventName, data: TData, sessionId?: string): RemoteMessage<EventPayload<TData>>;
20
+ replay(afterSeq: number, limit?: number): ReplayResult;
21
+ private trim;
22
+ }
23
+ //# sourceMappingURL=event-sequencer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-sequencer.d.ts","sourceRoot":"","sources":["../src/event-sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAE/G,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,EAAE,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAEpC,QAAQ,CAAC,UAAU,EAAE,MAAM;IADvC,QAAQ,CAAC,IAAI,0BAAyB;gBACjB,UAAU,EAAE,MAAM;CAGxC;AAED,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAW,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAH1E,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;gBAE9B,SAAS,SAAS,EAAmB,QAAQ,SAAc;IAKxF,UAAU,IAAI,MAAM;IAEpB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAU3G,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAQ,GAAG,YAAY;IAYrD,OAAO,CAAC,IAAI;CAIb"}
@@ -0,0 +1,54 @@
1
+ import { createEvent } from '@dsh-remote/protocol';
2
+ export class FullResyncRequiredError extends Error {
3
+ currentSeq;
4
+ code = 'FULL_RESYNC_REQUIRED';
5
+ constructor(currentSeq) {
6
+ super('The requested event replay window is no longer available.');
7
+ this.currentSeq = currentSeq;
8
+ }
9
+ }
10
+ export class EventSequencer {
11
+ maxEvents;
12
+ maxAgeMs;
13
+ seq = 0;
14
+ events = [];
15
+ constructor(maxEvents = 10_000, maxAgeMs = 15 * 60_000) {
16
+ this.maxEvents = maxEvents;
17
+ this.maxAgeMs = maxAgeMs;
18
+ if (!Number.isSafeInteger(maxEvents) || maxEvents < 1)
19
+ throw new TypeError('maxEvents must be a positive safe integer');
20
+ if (!Number.isSafeInteger(maxAgeMs) || maxAgeMs < 1)
21
+ throw new TypeError('maxAgeMs must be a positive safe integer');
22
+ }
23
+ currentSeq() { return this.seq; }
24
+ publish(event, data, sessionId) {
25
+ const message = createEvent(event, data, {
26
+ seq: ++this.seq,
27
+ ...(sessionId === undefined ? {} : { sessionId }),
28
+ });
29
+ this.events.push(message);
30
+ this.trim(message.timestamp);
31
+ return message;
32
+ }
33
+ replay(afterSeq, limit = 1_000) {
34
+ if (!Number.isSafeInteger(afterSeq) || afterSeq < 0)
35
+ throw new TypeError('afterSeq must be a non-negative safe integer');
36
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1_000)
37
+ throw new TypeError('limit must be between 1 and 1000');
38
+ this.trim(Date.now());
39
+ if (afterSeq >= this.seq)
40
+ return { events: [], lastSeq: this.seq, hasMore: false };
41
+ const firstSeq = this.events[0]?.payload.seq;
42
+ if (firstSeq === undefined || firstSeq > afterSeq + 1)
43
+ throw new FullResyncRequiredError(this.seq);
44
+ const events = this.events.filter(event => event.payload.seq > afterSeq).slice(0, limit);
45
+ const lastReturned = events.at(-1)?.payload.seq ?? afterSeq;
46
+ return { events, lastSeq: this.seq, hasMore: lastReturned < this.seq };
47
+ }
48
+ trim(now) {
49
+ const oldest = now - this.maxAgeMs;
50
+ while (this.events.length > this.maxEvents || (this.events[0]?.timestamp ?? now) < oldest)
51
+ this.events.shift();
52
+ }
53
+ }
54
+ //# sourceMappingURL=event-sequencer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-sequencer.js","sourceRoot":"","sources":["../src/event-sequencer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { ApiProxy, RpcResponse } from '@deepseek-ai/dsh-host-apiproxy/api';
2
+ import type { HarnessApiFrameData, HarnessApiStreamClosedData } from '@dsh-remote/protocol';
3
+ import type { SafeLogger } from './logging.js';
4
+ type PublishFrame = (event: 'harness.api.frame' | 'harness.api.stream.closed', data: HarnessApiFrameData | HarnessApiStreamClosedData) => Promise<void>;
5
+ /**
6
+ * Harness API methods that are safe to expose to an authenticated remote UI.
7
+ * Settings, credentials, native open/picker calls, directory mutation, file
8
+ * contents, downloads, and attachment upload intentionally remain outside
9
+ * this bridge. Directory listing exposes metadata only for workspace picking.
10
+ */
11
+ export declare const HARNESS_API_ALLOWLIST: readonly ["session.list", "session.search", "session.create", "session.history", "session.models", "session.selectModel", "session.rename", "session.fork", "session.prompt", "session.updateQueue", "session.cancel", "subagent.list", "subagent.history", "subagent.prompt", "subagent.interrupt", "host.describe", "host.listDirectory", "workspace.list", "workspace.create", "workspace.rename", "workspace.delete", "workspace.insertBefore", "workspace.insertSessionBefore", "workspace.archiveSession", "skill.list", "agentPreset.list", "agentPreset.select", "agentPreset.read", "goal.create", "goal.edit", "goal.pause", "goal.resume", "goal.complete", "goal.clear", "commands.execute", "llm.providers", "llm.models"];
12
+ export type AllowedHarnessApiMethod = typeof HARNESS_API_ALLOWLIST[number];
13
+ /**
14
+ * The official Typert gateway surface (`typertGateway` service from
15
+ * `dsh-api-gateway`) used to dispatch Harness command endpoints. The ApiProxy
16
+ * has no `commands` domain — commands live behind the Typert registry, which
17
+ * is exactly the path the official Web UI exercises via `/api/commands/*`.
18
+ */
19
+ export interface TypertGatewayLike {
20
+ invoke(request: {
21
+ namespace: string;
22
+ method: string;
23
+ args: Record<string, unknown>;
24
+ signal?: AbortSignal;
25
+ }): Promise<unknown>;
26
+ }
27
+ export declare class HarnessApiBridge {
28
+ private readonly api;
29
+ private readonly publish;
30
+ private readonly maxStreams;
31
+ private readonly logger?;
32
+ private readonly methods;
33
+ private readonly streams;
34
+ private readonly respondable;
35
+ private readonly mux;
36
+ private readonly host;
37
+ private readonly answer;
38
+ constructor(api: ApiProxy, publish: PublishFrame, maxStreams?: number, logger?: SafeLogger | undefined, typertGateway?: TypertGatewayLike);
39
+ call(input: unknown): Promise<RpcResponse<unknown>>;
40
+ respond(input: unknown): Promise<unknown>;
41
+ openStream(input: unknown): {
42
+ opened: true;
43
+ streamId: string;
44
+ };
45
+ closeStream(input: unknown): {
46
+ closed: boolean;
47
+ streamId: string;
48
+ };
49
+ closeAll(reason?: HarnessApiStreamClosedData['reason']): Promise<void>;
50
+ private pump;
51
+ private trackRespondable;
52
+ private deleteRespondable;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=harness-api-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-api-bridge.d.ts","sourceRoot":"","sources":["../src/harness-api-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAKR,WAAW,EACZ,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAEV,mBAAmB,EAEnB,0BAA0B,EAE3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAM9C,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,mBAAmB,GAAG,2BAA2B,EAAE,IAAI,EAAE,mBAAmB,GAAG,0BAA0B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAoCvJ;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,ysBAsCxB,CAAA;AAEV,MAAM,MAAM,uBAAuB,GAAG,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAA;AAoB1E;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,OAAO,EAAE;QACd,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,CAAC,EAAE,WAAW,CAAA;KACrB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACrB;AAED,qBAAa,gBAAgB;IASzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAX1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA2B;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAGzB,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,YAAY,EACrB,UAAU,SAAI,EACd,MAAM,CAAC,EAAE,UAAU,YAAA,EACpC,aAAa,CAAC,EAAE,iBAAiB;IAQ7B,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IA6CnD,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAW/C,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG;QAAE,MAAM,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAoB9D,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAgB5D,QAAQ,CAAC,MAAM,GAAE,0BAA0B,CAAC,QAAQ,CAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YAYnF,IAAI;IA4BlB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,iBAAiB;CAK1B"}