@vibesdotdev/terminal-client 0.0.0-stage → 1.0.0-rc.3

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 (201) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +102 -2
  3. package/dist/ansi/index.d.ts +11 -0
  4. package/dist/ansi/index.d.ts.map +1 -0
  5. package/dist/ansi/index.js +11 -0
  6. package/dist/ansi/index.js.map +1 -0
  7. package/dist/ansi/keymap.d.ts +77 -0
  8. package/dist/ansi/keymap.d.ts.map +1 -0
  9. package/dist/ansi/keymap.js +257 -0
  10. package/dist/ansi/keymap.js.map +1 -0
  11. package/dist/api-client-plugin.d.ts +4 -0
  12. package/dist/api-client-plugin.d.ts.map +1 -0
  13. package/dist/api-client-plugin.js +16 -0
  14. package/dist/api-client-plugin.js.map +1 -0
  15. package/dist/client/http-session.d.ts +44 -0
  16. package/dist/client/http-session.d.ts.map +1 -0
  17. package/dist/client/http-session.js +457 -0
  18. package/dist/client/http-session.js.map +1 -0
  19. package/dist/client/index.d.ts +8 -0
  20. package/dist/client/index.d.ts.map +1 -0
  21. package/dist/client/index.js +8 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client.d.ts +56 -0
  24. package/dist/client.d.ts.map +1 -0
  25. package/dist/client.js +169 -0
  26. package/dist/client.js.map +1 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +14 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/pty-bridge/index.d.ts +15 -0
  32. package/dist/pty-bridge/index.d.ts.map +1 -0
  33. package/dist/pty-bridge/index.js +15 -0
  34. package/dist/pty-bridge/index.js.map +1 -0
  35. package/dist/pty-bridge/protocol.d.ts +6 -0
  36. package/dist/pty-bridge/protocol.d.ts.map +1 -0
  37. package/dist/pty-bridge/protocol.js +6 -0
  38. package/dist/pty-bridge/protocol.js.map +1 -0
  39. package/dist/pty-bridge/server.d.ts +7 -0
  40. package/dist/pty-bridge/server.d.ts.map +1 -0
  41. package/dist/pty-bridge/server.js +9 -0
  42. package/dist/pty-bridge/server.js.map +1 -0
  43. package/dist/remote-session.d.ts +51 -0
  44. package/dist/remote-session.d.ts.map +1 -0
  45. package/dist/remote-session.js +326 -0
  46. package/dist/remote-session.js.map +1 -0
  47. package/dist/schemas/http.d.ts +61 -0
  48. package/dist/schemas/http.d.ts.map +1 -0
  49. package/dist/schemas/http.js +45 -0
  50. package/dist/schemas/http.js.map +1 -0
  51. package/dist/schemas/remote.d.ts +25 -0
  52. package/dist/schemas/remote.d.ts.map +1 -0
  53. package/dist/schemas/remote.js +23 -0
  54. package/dist/schemas/remote.js.map +1 -0
  55. package/dist/schemas/session.d.ts +26 -0
  56. package/dist/schemas/session.d.ts.map +1 -0
  57. package/dist/schemas/session.js +17 -0
  58. package/dist/schemas/session.js.map +1 -0
  59. package/dist/schemas/store.d.ts +29 -0
  60. package/dist/schemas/store.d.ts.map +1 -0
  61. package/dist/schemas/store.js +22 -0
  62. package/dist/schemas/store.js.map +1 -0
  63. package/dist/schemas/terminal.d.ts +296 -0
  64. package/dist/schemas/terminal.d.ts.map +1 -0
  65. package/dist/schemas/terminal.js +243 -0
  66. package/dist/schemas/terminal.js.map +1 -0
  67. package/dist/server/index.d.ts +9 -0
  68. package/dist/server/index.d.ts.map +1 -0
  69. package/dist/server/index.js +9 -0
  70. package/dist/server/index.js.map +1 -0
  71. package/dist/server/session-store.d.ts +176 -0
  72. package/dist/server/session-store.d.ts.map +1 -0
  73. package/dist/server/session-store.js +462 -0
  74. package/dist/server/session-store.js.map +1 -0
  75. package/dist/server/sse-stream.d.ts +32 -0
  76. package/dist/server/sse-stream.d.ts.map +1 -0
  77. package/dist/server/sse-stream.js +87 -0
  78. package/dist/server/sse-stream.js.map +1 -0
  79. package/dist/svelte/HostPicker.svelte +263 -0
  80. package/dist/svelte/HostPicker.svelte.d.ts +36 -0
  81. package/dist/svelte/HostPicker.svelte.d.ts.map +1 -0
  82. package/dist/svelte/README.md +75 -0
  83. package/dist/svelte/ReconnectBanner.svelte +88 -0
  84. package/dist/svelte/ReconnectBanner.svelte.d.ts +16 -0
  85. package/dist/svelte/ReconnectBanner.svelte.d.ts.map +1 -0
  86. package/dist/svelte/SessionTabs.svelte +192 -0
  87. package/dist/svelte/SessionTabs.svelte.d.ts +17 -0
  88. package/dist/svelte/SessionTabs.svelte.d.ts.map +1 -0
  89. package/dist/svelte/Terminal.svelte +567 -0
  90. package/dist/svelte/Terminal.svelte.d.ts +25 -0
  91. package/dist/svelte/Terminal.svelte.d.ts.map +1 -0
  92. package/dist/svelte/TerminalHostWorkspace.svelte +264 -0
  93. package/dist/svelte/TerminalHostWorkspace.svelte.d.ts +59 -0
  94. package/dist/svelte/TerminalHostWorkspace.svelte.d.ts.map +1 -0
  95. package/dist/svelte/TerminalMobileToolbar.svelte +56 -0
  96. package/dist/svelte/TerminalMobileToolbar.svelte.d.ts +14 -0
  97. package/dist/svelte/TerminalMobileToolbar.svelte.d.ts.map +1 -0
  98. package/dist/svelte/TerminalWorkspace.svelte +562 -0
  99. package/dist/svelte/TerminalWorkspace.svelte.d.ts +25 -0
  100. package/dist/svelte/TerminalWorkspace.svelte.d.ts.map +1 -0
  101. package/dist/svelte/ambient.d.ts +9 -0
  102. package/dist/svelte/docs/terminal-svelte.docs.descriptor.d.ts +4 -0
  103. package/dist/svelte/docs/terminal-svelte.docs.descriptor.d.ts.map +1 -0
  104. package/dist/svelte/docs/terminal-svelte.docs.descriptor.js +74 -0
  105. package/dist/svelte/index.d.ts +29 -0
  106. package/dist/svelte/index.d.ts.map +1 -0
  107. package/dist/svelte/index.js +28 -0
  108. package/dist/svelte/styles.css +8 -0
  109. package/dist/svelte/terminal-host-workspace.d.ts +152 -0
  110. package/dist/svelte/terminal-host-workspace.d.ts.map +1 -0
  111. package/dist/svelte/terminal-host-workspace.js +335 -0
  112. package/dist/svelte/terminal-session-authority.d.ts +17 -0
  113. package/dist/svelte/terminal-session-authority.d.ts.map +1 -0
  114. package/dist/svelte/terminal-session-authority.js +25 -0
  115. package/dist/svelte/terminal-svelte.plugin.d.ts +21 -0
  116. package/dist/svelte/terminal-svelte.plugin.d.ts.map +1 -0
  117. package/dist/svelte/terminal-svelte.plugin.js +53 -0
  118. package/dist/svelte/terminal-theme.d.ts +11 -0
  119. package/dist/svelte/terminal-theme.d.ts.map +1 -0
  120. package/dist/svelte/terminal-theme.js +116 -0
  121. package/dist/svelte/tool-widgets/TerminalToolCard.svelte +65 -0
  122. package/dist/svelte/tool-widgets/TerminalToolCard.svelte.d.ts +5 -0
  123. package/dist/svelte/tool-widgets/TerminalToolCard.svelte.d.ts.map +1 -0
  124. package/dist/svelte/tool-widgets/terminal-tool-card.d.ts +25 -0
  125. package/dist/svelte/tool-widgets/terminal-tool-card.d.ts.map +1 -0
  126. package/dist/svelte/tool-widgets/terminal-tool-card.js +116 -0
  127. package/dist/svelte/types.d.ts +160 -0
  128. package/dist/svelte/types.d.ts.map +1 -0
  129. package/dist/svelte/types.js +51 -0
  130. package/dist/svelte/workspace.d.ts +3 -0
  131. package/dist/svelte/workspace.d.ts.map +1 -0
  132. package/dist/svelte/workspace.js +2 -0
  133. package/dist/terminal-client.plugin.d.ts +3 -0
  134. package/dist/terminal-client.plugin.d.ts.map +1 -0
  135. package/dist/terminal-client.plugin.js +3 -0
  136. package/dist/terminal-client.plugin.js.map +1 -0
  137. package/dist/terminal-runtime.d.ts +30 -0
  138. package/dist/terminal-runtime.d.ts.map +1 -0
  139. package/dist/terminal-runtime.js +673 -0
  140. package/dist/terminal-runtime.js.map +1 -0
  141. package/dist/terminal.consumer.plugin.d.ts +14 -0
  142. package/dist/terminal.consumer.plugin.d.ts.map +1 -0
  143. package/dist/terminal.consumer.plugin.js +31 -0
  144. package/dist/terminal.consumer.plugin.js.map +1 -0
  145. package/dist/tools/terminal.impl.consumer.d.ts +11 -0
  146. package/dist/tools/terminal.impl.consumer.d.ts.map +1 -0
  147. package/dist/tools/terminal.impl.consumer.js +20 -0
  148. package/dist/tools/terminal.impl.consumer.js.map +1 -0
  149. package/dist/tools/terminal.schemas.d.ts +3 -0
  150. package/dist/tools/terminal.schemas.d.ts.map +1 -0
  151. package/dist/tools/terminal.schemas.js +3 -0
  152. package/dist/tools/terminal.schemas.js.map +1 -0
  153. package/dist/tools/terminal.unified.descriptor.d.ts +218 -0
  154. package/dist/tools/terminal.unified.descriptor.d.ts.map +1 -0
  155. package/dist/tools/terminal.unified.descriptor.js +36 -0
  156. package/dist/tools/terminal.unified.descriptor.js.map +1 -0
  157. package/dist/tui/index.d.ts +9 -0
  158. package/dist/tui/index.d.ts.map +1 -0
  159. package/dist/tui/index.js +8 -0
  160. package/dist/tui/index.js.map +1 -0
  161. package/dist/tui/terminal-open.descriptor.d.ts +9 -0
  162. package/dist/tui/terminal-open.descriptor.d.ts.map +1 -0
  163. package/dist/tui/terminal-open.descriptor.js +18 -0
  164. package/dist/tui/terminal-open.descriptor.js.map +1 -0
  165. package/dist/tui/terminal-open.impl.consumer.d.ts +9 -0
  166. package/dist/tui/terminal-open.impl.consumer.d.ts.map +1 -0
  167. package/dist/tui/terminal-open.impl.consumer.js +13 -0
  168. package/dist/tui/terminal-open.impl.consumer.js.map +1 -0
  169. package/dist/tui/terminal-registry.descriptor.d.ts +11 -0
  170. package/dist/tui/terminal-registry.descriptor.d.ts.map +1 -0
  171. package/dist/tui/terminal-registry.descriptor.js +17 -0
  172. package/dist/tui/terminal-registry.descriptor.js.map +1 -0
  173. package/dist/tui/terminal-registry.impl.consumer.d.ts +71 -0
  174. package/dist/tui/terminal-registry.impl.consumer.d.ts.map +1 -0
  175. package/dist/tui/terminal-registry.impl.consumer.js +190 -0
  176. package/dist/tui/terminal-registry.impl.consumer.js.map +1 -0
  177. package/dist/tui/terminal-tui.plugin.d.ts +10 -0
  178. package/dist/tui/terminal-tui.plugin.d.ts.map +1 -0
  179. package/dist/tui/terminal-tui.plugin.js +32 -0
  180. package/dist/tui/terminal-tui.plugin.js.map +1 -0
  181. package/dist/tui/terminal.descriptor.d.ts +10 -0
  182. package/dist/tui/terminal.descriptor.d.ts.map +1 -0
  183. package/dist/tui/terminal.descriptor.js +25 -0
  184. package/dist/tui/terminal.descriptor.js.map +1 -0
  185. package/dist/tui/terminal.impl.consumer.d.ts +14 -0
  186. package/dist/tui/terminal.impl.consumer.d.ts.map +1 -0
  187. package/dist/tui/terminal.impl.consumer.js +189 -0
  188. package/dist/tui/terminal.impl.consumer.js.map +1 -0
  189. package/dist/tui/terminal.state-key.d.ts +30 -0
  190. package/dist/tui/terminal.state-key.d.ts.map +1 -0
  191. package/dist/tui/terminal.state-key.js +9 -0
  192. package/dist/tui/terminal.state-key.js.map +1 -0
  193. package/dist/tui/terminal.state.d.ts +152 -0
  194. package/dist/tui/terminal.state.d.ts.map +1 -0
  195. package/dist/tui/terminal.state.js +149 -0
  196. package/dist/tui/terminal.state.js.map +1 -0
  197. package/dist/workspace.d.ts +155 -0
  198. package/dist/workspace.d.ts.map +1 -0
  199. package/dist/workspace.js +292 -0
  200. package/dist/workspace.js.map +1 -0
  201. package/package.json +228 -4
@@ -0,0 +1,457 @@
1
+ /**
2
+ * @vibesdotdev/terminal-client/client/http-session — browser ExecutionSession adapter.
3
+ *
4
+ * Implements the L3 `ExecutionSession` interface against the `/api/session/**`
5
+ * bridge endpoints. Works for BOTH remote fleet sessions (hq-web) and local PTY
6
+ * sessions (consumer-hq): both surfaces use the identical wire format.
7
+ *
8
+ * - `onOutput` ← Server-Sent Events from `GET /api/session/{id}/output`
9
+ * - `write`/`resize`/`signal`/`kill` → `POST /api/session/{id}/{verb}`
10
+ * - `exited()` ← resolves when the SSE stream signals exit (or the channel ends)
11
+ *
12
+ * ### Auto-reconnect
13
+ *
14
+ * When the EventSource drops (network blip, server restart), the adapter retries
15
+ * transparently with jittered exponential backoff. Callers get `onReconnecting` /
16
+ * `onReconnected` hooks to show a UI banner. The same server-side backlog ring
17
+ * replays missed output on re-attach. A clean exit from the session (the server
18
+ * sends `event: exit`) is NOT retried — it resolves `exited()` normally.
19
+ *
20
+ * `<Terminal>` doesn't care which transport backs the session — it only ever sees
21
+ * an `ExecutionSession`. The SSE-error → `exited()`-reject path maps to the
22
+ * component's `onDisconnect` banner once retries are exhausted.
23
+ *
24
+ * BROWSER-ONLY. Depends on `fetch` and `EventSource` (both available in browsers
25
+ * and in Bun).
26
+ */
27
+ import { CapabilityError, settle, CaughtFailureSchema } from '@vibesdotdev/kernel';
28
+ import { getLogger } from '@vibesdotdev/logging';
29
+ import * as z from 'zod/v4';
30
+ import { bytesToBase64 } from "../pty-bridge/protocol.js";
31
+ // ---------------------------------------------------------------------------
32
+ // Wire schemas
33
+ // ---------------------------------------------------------------------------
34
+ import { MessageEventDataSchema, TerminalEventSourceConstructorSchema } from "../schemas/http.js";
35
+ function captureHttpEvent(read, message, reason) {
36
+ try {
37
+ return { kind: 'success', value: read() };
38
+ }
39
+ catch (cause) {
40
+ return {
41
+ kind: 'failure',
42
+ failure: new CapabilityError(message, 'UNAVAILABLE', {
43
+ reason,
44
+ retryable: false,
45
+ cause
46
+ })
47
+ };
48
+ }
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // Internal POST helper
52
+ // ---------------------------------------------------------------------------
53
+ async function fetchSession(input, init) {
54
+ const outcome = await settle(() => fetch(input, init));
55
+ if (outcome.ok)
56
+ return outcome.value;
57
+ // Some hosts wrap fetch aborts; preserve the owning wait's typed cancellation.
58
+ if (init.signal.aborted)
59
+ throw init.signal.reason;
60
+ throw outcome.cause;
61
+ }
62
+ async function post(runtime, timeoutMs, baseUrl, id, verb, body) {
63
+ await runtime.lifecycle.wait(async (signal) => {
64
+ const response = await fetchSession(`${baseUrl}/api/session/${encodeURIComponent(id)}/${verb}`, {
65
+ method: 'POST',
66
+ headers: { 'content-type': 'application/json' },
67
+ credentials: 'include',
68
+ body: JSON.stringify(body),
69
+ signal
70
+ });
71
+ if (!response.ok) {
72
+ throw new CapabilityError('The terminal session request failed.', 'UNAVAILABLE', {
73
+ reason: `terminal-${verb}-request-failed`,
74
+ retryable: response.status >= 500,
75
+ details: { status: response.status }
76
+ });
77
+ }
78
+ }, { timeoutMs, reason: `terminal-http-${verb}` });
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Reconnect options
82
+ // ---------------------------------------------------------------------------
83
+ export {} from "../schemas/http.js";
84
+ import { OpenHttpSessionOptionsSchema, HttpSessionOpenResponseSchema, HttpSessionExitEventSchema, HttpSessionFailureEventSchema } from "../schemas/http.js";
85
+ function admitOptions(input) {
86
+ try {
87
+ return OpenHttpSessionOptionsSchema.parse(input);
88
+ }
89
+ catch (cause) {
90
+ throw new CapabilityError('The HTTP terminal session request is invalid.', 'INVALID_INPUT', {
91
+ reason: 'terminal-http-session-request-invalid',
92
+ retryable: false,
93
+ cause
94
+ });
95
+ }
96
+ }
97
+ /**
98
+ * Open a terminal session over HTTP and return a browser `ExecutionSession` bound
99
+ * to it. Call from `onMount` (uses `EventSource` / `fetch`).
100
+ *
101
+ * Returns `{ session, id, environmentId }` so callers can inspect metadata if
102
+ * needed; the `session` is ready to pass to `<Terminal session={session} />`.
103
+ */
104
+ export async function openHttpSession(runtime, input) {
105
+ const opts = admitOptions(input);
106
+ return runtime.lifecycle.wait(async (signal) => {
107
+ const opened = await openHttpSessionTransport(runtime, opts, signal);
108
+ // A response received after cancellation still names a real server shell.
109
+ // The owning wait tracks its cleanup instead of abandoning that session.
110
+ if (signal.aborted) {
111
+ opened.session.kill();
112
+ await opened.session.exited();
113
+ throw signal.reason;
114
+ }
115
+ return opened;
116
+ }, { timeoutMs: opts.timeoutMs, reason: 'terminal-http-session-open', signal: opts.signal });
117
+ }
118
+ async function openHttpSessionTransport(runtime, opts, signal) {
119
+ const baseUrl = opts.baseUrl;
120
+ const logger = getLogger('terminal.http-session', runtime);
121
+ let id;
122
+ let environmentId;
123
+ if (opts.existingId) {
124
+ id = opts.existingId;
125
+ environmentId = 'remote';
126
+ const res = await fetchSession(`${baseUrl}/api/session/${encodeURIComponent(id)}/attach`, {
127
+ method: 'POST',
128
+ credentials: 'include',
129
+ signal
130
+ });
131
+ if (!res.ok) {
132
+ throw new CapabilityError('The terminal session could not be attached.', 'UNAVAILABLE', {
133
+ reason: 'terminal-session-attach-failed',
134
+ retryable: res.status >= 500,
135
+ details: { status: res.status }
136
+ });
137
+ }
138
+ }
139
+ else {
140
+ const body = {
141
+ cols: opts.cols,
142
+ rows: opts.rows
143
+ };
144
+ if (opts.extra !== undefined)
145
+ Object.assign(body, opts.extra);
146
+ if (opts.command !== undefined)
147
+ body.command = opts.command;
148
+ if (opts.args !== undefined)
149
+ body.args = opts.args;
150
+ const res = await fetchSession(`${baseUrl}/api/session`, {
151
+ method: 'POST',
152
+ headers: { 'content-type': 'application/json' },
153
+ credentials: 'include',
154
+ body: JSON.stringify(body),
155
+ signal
156
+ });
157
+ if (!res.ok) {
158
+ throw new CapabilityError('The terminal session could not be opened.', 'UNAVAILABLE', {
159
+ reason: 'terminal-session-open-failed',
160
+ retryable: res.status >= 500,
161
+ details: { status: res.status }
162
+ });
163
+ }
164
+ let payload;
165
+ try {
166
+ payload = await res.json();
167
+ }
168
+ catch (cause) {
169
+ throw new CapabilityError('The terminal session response is invalid.', 'UNAVAILABLE', {
170
+ reason: 'terminal-session-response-invalid',
171
+ retryable: false,
172
+ cause
173
+ });
174
+ }
175
+ const parsed = HttpSessionOpenResponseSchema.safeParse(payload);
176
+ if (!parsed.success) {
177
+ throw new CapabilityError('The terminal session response is invalid.', 'UNAVAILABLE', {
178
+ reason: 'terminal-session-response-invalid',
179
+ retryable: false,
180
+ cause: parsed.error
181
+ });
182
+ }
183
+ ({ id, environmentId } = parsed.data);
184
+ }
185
+ // -------------------------------------------------------------------------
186
+ // Reconnect configuration
187
+ // -------------------------------------------------------------------------
188
+ const reconnectCfg = opts.reconnect;
189
+ const outputHandlers = new Set();
190
+ let exitResolve;
191
+ let exitReject;
192
+ let settled = false;
193
+ let stopping = false;
194
+ const exitedPromise = new Promise((resolve, reject) => {
195
+ exitResolve = resolve;
196
+ exitReject = reject;
197
+ });
198
+ /** Build (or re-build) the SSE connection. Returns a dispose function. */
199
+ function openSseConnection(onError, onOpen, boundOpening = true) {
200
+ const EventSourceConstructor = TerminalEventSourceConstructorSchema.parse(EventSource);
201
+ const source = new EventSourceConstructor(`${baseUrl}/api/session/${encodeURIComponent(id)}/output`);
202
+ let opened = false;
203
+ const stopOpeningDeadline = boundOpening ? runtime.lifecycle.timeout(() => {
204
+ if (opened || settled || stopping)
205
+ return;
206
+ source.close();
207
+ onError(new CapabilityError('The terminal output stream did not open in time.', 'TIMEOUT', {
208
+ reason: 'terminal-stream-open-timeout', retryable: true
209
+ }));
210
+ }, opts.timeoutMs) : () => { };
211
+ source.addEventListener('open', () => {
212
+ if (opened || settled)
213
+ return;
214
+ opened = true;
215
+ stopOpeningDeadline();
216
+ onOpen?.();
217
+ });
218
+ source.addEventListener('data', (event) => {
219
+ if (settled || stopping)
220
+ return;
221
+ const outcome = captureHttpEvent(() => {
222
+ const { data } = MessageEventDataSchema.parse(event);
223
+ const bin = atob(data);
224
+ const bytes = new Uint8Array(bin.length);
225
+ for (let index = 0; index < bin.length; index += 1)
226
+ bytes[index] = bin.charCodeAt(index);
227
+ for (const handler of outputHandlers)
228
+ handler(bytes);
229
+ }, 'The terminal output event is invalid.', 'terminal-output-event-invalid');
230
+ if (outcome.kind === 'failure')
231
+ fail(outcome.failure);
232
+ });
233
+ source.addEventListener('exit', (event) => {
234
+ if (settled)
235
+ return;
236
+ const outcome = captureHttpEvent(() => {
237
+ const message = MessageEventDataSchema.parse(event);
238
+ return HttpSessionExitEventSchema.parse(JSON.parse(message.data));
239
+ }, 'The terminal exit event is invalid.', 'terminal-exit-event-invalid');
240
+ if (outcome.kind === 'failure') {
241
+ fail(outcome.failure);
242
+ return;
243
+ }
244
+ settled = true;
245
+ source.close();
246
+ exitResolve(outcome.value);
247
+ });
248
+ source.addEventListener('failure', (event) => {
249
+ if (settled)
250
+ return;
251
+ const outcome = captureHttpEvent(() => {
252
+ const message = MessageEventDataSchema.parse(event);
253
+ const payload = HttpSessionFailureEventSchema.parse(JSON.parse(message.data));
254
+ return new CapabilityError(payload.message, payload.code, {
255
+ reason: payload.reason,
256
+ retryable: payload.retryable
257
+ });
258
+ }, 'The terminal failure event is invalid.', 'terminal-failure-event-invalid');
259
+ fail(outcome.kind === 'success'
260
+ ? outcome.value
261
+ : outcome.failure);
262
+ });
263
+ const sourceFailure = new Promise((_resolve, reject) => {
264
+ source.onerror = reject;
265
+ });
266
+ void sourceFailure
267
+ .then(() => ({ kind: 'cancelled' }), (cause) => ({
268
+ kind: 'failure',
269
+ failure: CaughtFailureSchema.parse(cause)
270
+ }))
271
+ .then((outcome) => {
272
+ if (outcome.kind === 'failure') {
273
+ stopOpeningDeadline();
274
+ onError(outcome.failure);
275
+ source.close();
276
+ }
277
+ });
278
+ return () => {
279
+ stopOpeningDeadline();
280
+ source.close();
281
+ };
282
+ }
283
+ // -------------------------------------------------------------------------
284
+ // Reconnect loop — jittered exponential backoff
285
+ // -------------------------------------------------------------------------
286
+ let disposeSse = null;
287
+ let reconnectAttempt = 0;
288
+ let disposeReconnectTimer = null;
289
+ function closeTransport() {
290
+ disposeReconnectTimer?.();
291
+ disposeReconnectTimer = null;
292
+ disposeSse?.();
293
+ disposeSse = null;
294
+ }
295
+ function recordFailure(error) {
296
+ if (settled)
297
+ return null;
298
+ const failure = CapabilityError.from(error);
299
+ settled = true;
300
+ closeTransport();
301
+ logger.debug('terminal HTTP session failed', {
302
+ error: CaughtFailureSchema.parse(failure),
303
+ reason: failure.reason
304
+ });
305
+ return failure;
306
+ }
307
+ function fail(error) {
308
+ const failure = recordFailure(error);
309
+ if (failure)
310
+ exitReject(failure);
311
+ }
312
+ let inputQueue = Promise.resolve();
313
+ function send(verb, body) {
314
+ if (settled || stopping)
315
+ return;
316
+ // ExecutionSession's input methods are synchronous. Deliver asynchronous
317
+ // failures through its existing disconnect channel, never an unhandled POST.
318
+ // Separate HTTP requests can arrive out of order; preserve terminal input
319
+ // order and discard unsent input after a disconnect or explicit kill.
320
+ const delivery = inputQueue
321
+ .then(() => {
322
+ if (!settled && !stopping)
323
+ return post(runtime, opts.timeoutMs, baseUrl, id, verb, body);
324
+ })
325
+ .then(() => ({ kind: 'success' }), (cause) => ({
326
+ kind: 'failure',
327
+ failure: CapabilityError.from(CaughtFailureSchema.parse(cause))
328
+ }));
329
+ inputQueue = delivery.then((outcome) => {
330
+ if (outcome.kind === 'failure')
331
+ fail(outcome.failure);
332
+ });
333
+ }
334
+ function jitter(base) {
335
+ return base + Math.floor(Math.random() * base * 0.3);
336
+ }
337
+ function handleDisconnect(disconnectCause) {
338
+ const disconnectFailure = new CapabilityError('The terminal output stream disconnected.', 'UNAVAILABLE', {
339
+ reason: 'terminal-stream-disconnected',
340
+ retryable: true,
341
+ cause: disconnectCause
342
+ });
343
+ if (settled || stopping)
344
+ return;
345
+ disposeSse = null;
346
+ if (!reconnectCfg) {
347
+ fail(new CapabilityError('The terminal output stream disconnected.', 'UNAVAILABLE', {
348
+ reason: 'terminal-stream-disconnected',
349
+ retryable: true,
350
+ cause: disconnectFailure
351
+ }));
352
+ return;
353
+ }
354
+ const { maxAttempts, baseDelayMs, maxDelayMs, onReconnecting, onReconnected } = reconnectCfg;
355
+ reconnectAttempt++;
356
+ if (reconnectAttempt > maxAttempts) {
357
+ fail(new CapabilityError('The terminal output stream could not reconnect.', 'UNAVAILABLE', {
358
+ reason: 'terminal-stream-reconnect-exhausted',
359
+ retryable: true,
360
+ cause: disconnectFailure
361
+ }));
362
+ return;
363
+ }
364
+ const rawDelay = Math.min(baseDelayMs * Math.pow(2, reconnectAttempt - 1), maxDelayMs);
365
+ const delayMs = jitter(rawDelay);
366
+ const attempt = reconnectAttempt;
367
+ onReconnecting?.(attempt, delayMs);
368
+ disposeReconnectTimer = runtime.lifecycle.timeout(() => {
369
+ disposeReconnectTimer = null;
370
+ if (settled)
371
+ return;
372
+ disposeSse = openSseConnection(handleDisconnect, () => {
373
+ // A constructor receipt is not a live transport receipt. Only reset
374
+ // the retry budget and report recovery after EventSource opens.
375
+ reconnectAttempt = 0;
376
+ onReconnected?.(attempt);
377
+ });
378
+ }, delayMs);
379
+ }
380
+ // -------------------------------------------------------------------------
381
+ // ExecutionSession implementation
382
+ // -------------------------------------------------------------------------
383
+ const session = {
384
+ id,
385
+ environmentId,
386
+ write(data) {
387
+ send('write', { data: bytesToBase64(data) });
388
+ },
389
+ onOutput(handler) {
390
+ outputHandlers.add(handler);
391
+ return () => outputHandlers.delete(handler);
392
+ },
393
+ resize(cols, rows) {
394
+ send('resize', { cols, rows });
395
+ },
396
+ signal(sig) {
397
+ send('signal', { signal: sig });
398
+ },
399
+ exited() {
400
+ return exitedPromise;
401
+ },
402
+ kill() {
403
+ if (stopping)
404
+ return;
405
+ stopping = true;
406
+ closeTransport();
407
+ void post(runtime, opts.timeoutMs, baseUrl, id, 'kill', {})
408
+ .then(() => ({ kind: 'success' }), (cause) => ({
409
+ kind: 'failure',
410
+ failure: CapabilityError.from(CaughtFailureSchema.parse(cause))
411
+ }))
412
+ .then((outcome) => {
413
+ if (outcome.kind === 'failure') {
414
+ fail(outcome.failure);
415
+ return;
416
+ }
417
+ settled = true;
418
+ exitResolve({ exitCode: null });
419
+ });
420
+ }
421
+ };
422
+ // Admission is complete only after the output channel is live. Cancellation
423
+ // after receiving the id still owns the shell and joins its teardown.
424
+ if (signal.aborted) {
425
+ session.kill();
426
+ await session.exited();
427
+ throw signal.reason;
428
+ }
429
+ const ready = Promise.withResolvers();
430
+ let initiallyOpened = false;
431
+ const abortOpening = () => ready.reject(signal.reason);
432
+ signal.addEventListener('abort', abortOpening, { once: true });
433
+ void exitedPromise.then(() => ready.reject(new CapabilityError('The terminal ended before its output stream opened.', 'UNAVAILABLE', {
434
+ reason: 'terminal-stream-ended-before-open', retryable: true
435
+ })), cause => ready.reject(cause));
436
+ try {
437
+ disposeSse = openSseConnection(cause => initiallyOpened ? handleDisconnect(cause) : ready.reject(new CapabilityError('The terminal output stream could not open.', 'UNAVAILABLE', {
438
+ reason: 'terminal-stream-open-failed', retryable: true, cause
439
+ })), () => { initiallyOpened = true; ready.resolve(); }, false);
440
+ await ready.promise;
441
+ }
442
+ catch (cause) {
443
+ const cleanup = await settle(async () => {
444
+ session.kill();
445
+ await session.exited();
446
+ });
447
+ if (!cleanup.ok) {
448
+ throw new AggregateError([cause, cleanup.cause], 'Terminal admission and cleanup failed.', { cause });
449
+ }
450
+ throw cause;
451
+ }
452
+ finally {
453
+ signal.removeEventListener('abort', abortOpening);
454
+ }
455
+ return { session, id, environmentId };
456
+ }
457
+ //# sourceMappingURL=http-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-session.js","sourceRoot":"","sources":["../../src/client/http-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @vibesdotdev/terminal-client/client/http-session — browser subpath.
3
+ *
4
+ * Re-exports the fetch+EventSource `ExecutionSession` adapter that drives the
5
+ * `/api/session/**` bridge from the browser.
6
+ */
7
+ export { openHttpSession, type OpenHttpSessionOptions, type ReconnectOptions } from './http-session.ts';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACN,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @vibesdotdev/terminal-client/client/http-session — browser subpath.
3
+ *
4
+ * Re-exports the fetch+EventSource `ExecutionSession` adapter that drives the
5
+ * `/api/session/**` bridge from the browser.
6
+ */
7
+ export { openHttpSession } from "./http-session.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACN,eAAe,EAGf,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Local and explicitly remote terminal sessions over runtime/execution and
3
+ * kernel-rpc. The terminal semantic client owns remote identity and cleanup.
4
+ */
5
+ import { type DeclaredSessionOptions, type VibesRuntime, type RuntimeRefHandle } from '@vibesdotdev/kernel';
6
+ import { type OpenTerminalOptions } from './schemas/session.ts';
7
+ export { OpenTerminalOptionsSchema, type OpenTerminalOptions } from './schemas/session.ts';
8
+ import type { ExecutionSession } from '@vibesdotdev/kernel/execution';
9
+ export type { ExecutionSession } from '@vibesdotdev/kernel/execution';
10
+ /**
11
+ * A remote session request: a declaration, never an environment (rc02-rc03
12
+ * C15, cross-host). The receiving host admits it and composes the child's
13
+ * environment on its own runtime (`composeDeclaredSession`); only the
14
+ * variables the caller names travel.
15
+ */
16
+ export declare function remoteSessionRequest(opts: OpenTerminalOptions): DeclaredSessionOptions;
17
+ /**
18
+ * Open a LOCAL terminal session against this runtime's execution impl.
19
+ *
20
+ * The default, zero-config path (Correction #1: local is the default). Resolves
21
+ * `runtime/execution` on consumer hardware (where `runtime-execution-local`
22
+ * self-registers `LocalExecution`) and opens a real Bun.Terminal PTY. The
23
+ * returned `ExecutionSession` is renderable directly by `<Terminal>`.
24
+ *
25
+ * Throws if no execution impl is resolvable here (e.g. on a CF Workers surface,
26
+ * which registers no PTY-capable impl) or if the impl lacks the `pty` capability.
27
+ */
28
+ export declare function openLocalSession(runtime: VibesRuntime, opts: OpenTerminalOptions): Promise<ExecutionSession>;
29
+ /**
30
+ * Open a REMOTE terminal session on a specific fleet host (L9b — phase 4).
31
+ *
32
+ * Remoteness is an EXPLICIT constraint (Correction #1) — the caller names the host
33
+ * ref; this client never picks a remote silently. The returned session is an RPC
34
+ * PROXY adapted to the canonical `ExecutionSession` shape: its byte stream rides
35
+ * L4's `stream` verb (the `'pty'` channel) and its `write`/`resize`/`signal`/`kill`
36
+ * are `invoke` calls. Its `exited()` read can reject with `RPC_DISCONNECTED` when
37
+ * the transport drops — the visible result-type difference `<Terminal>` renders as
38
+ * a disconnect banner. The component consumes it with IDENTICAL code to the local
39
+ * case (terminal.md §"Target design" — same UI, only a proxied session).
40
+ *
41
+ * Composition (no transport of its own):
42
+ * 1. Reach the host EXPLICITLY via `getVibesRemoteFrom(runtime,
43
+ * hostRef.runtimeId)` — the supplied runtime owns the registered
44
+ * `runtime/rpc` descriptor and credential loader; this client never
45
+ * reaches for an ambient registry or `discover()`s.
46
+ * 2. `query('runtime/execution')` over the wire → an execution proxy.
47
+ * 3. `session(opts)` → a session wire-proxy.
48
+ * 4. `adaptRemoteSession()` wraps that proxy in the `ExecutionSession` interface.
49
+ *
50
+ * The L5 authz + friction gates run on the HOST side inside L1's invoke pipeline
51
+ * (every arriving `invoke` is gated before the method applies) — this client does
52
+ * not re-implement them; an unauthorized peer or out-of-policy `session` open is
53
+ * denied at the host, surfacing here as a rejected invoke.
54
+ */
55
+ export declare function openRemoteSession(runtime: VibesRuntime, hostRef: RuntimeRefHandle, opts: OpenTerminalOptions): Promise<ExecutionSession>;
56
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAErB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAA6B,KAAK,mBAAmB,EAAyB,MAAM,sBAAsB,CAAC;AAClH,OAAO,EAAE,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EACX,gBAAgB,EAGhB,MAAM,+BAA+B,CAAC;AAIvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAgCtE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,sBAAsB,CAWtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,mBAAmB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAqB3B;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,mBAAmB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAuD3B"}