@agentuity/coder 1.0.39 → 1.0.41

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 (49) hide show
  1. package/dist/client.d.ts +2 -2
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +2 -0
  4. package/dist/client.js.map +1 -1
  5. package/dist/hub-overlay-state.d.ts +30 -0
  6. package/dist/hub-overlay-state.d.ts.map +1 -0
  7. package/dist/hub-overlay-state.js +68 -0
  8. package/dist/hub-overlay-state.js.map +1 -0
  9. package/dist/hub-overlay.d.ts +41 -2
  10. package/dist/hub-overlay.d.ts.map +1 -1
  11. package/dist/hub-overlay.js +667 -115
  12. package/dist/hub-overlay.js.map +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +19 -34
  15. package/dist/index.js.map +1 -1
  16. package/dist/native-remote-ui-context.d.ts +5 -0
  17. package/dist/native-remote-ui-context.d.ts.map +1 -0
  18. package/dist/native-remote-ui-context.js +30 -0
  19. package/dist/native-remote-ui-context.js.map +1 -0
  20. package/dist/protocol.d.ts +210 -38
  21. package/dist/protocol.d.ts.map +1 -1
  22. package/dist/protocol.js +2 -1
  23. package/dist/protocol.js.map +1 -1
  24. package/dist/remote-lifecycle.d.ts +61 -0
  25. package/dist/remote-lifecycle.d.ts.map +1 -0
  26. package/dist/remote-lifecycle.js +190 -0
  27. package/dist/remote-lifecycle.js.map +1 -0
  28. package/dist/remote-session.d.ts +15 -0
  29. package/dist/remote-session.d.ts.map +1 -1
  30. package/dist/remote-session.js +240 -35
  31. package/dist/remote-session.js.map +1 -1
  32. package/dist/remote-tui.d.ts.map +1 -1
  33. package/dist/remote-tui.js +95 -12
  34. package/dist/remote-tui.js.map +1 -1
  35. package/dist/remote-ui-handler.d.ts +5 -0
  36. package/dist/remote-ui-handler.d.ts.map +1 -0
  37. package/dist/remote-ui-handler.js +53 -0
  38. package/dist/remote-ui-handler.js.map +1 -0
  39. package/package.json +5 -5
  40. package/src/client.ts +5 -3
  41. package/src/hub-overlay-state.ts +117 -0
  42. package/src/hub-overlay.ts +974 -138
  43. package/src/index.ts +19 -50
  44. package/src/native-remote-ui-context.ts +41 -0
  45. package/src/protocol.ts +270 -56
  46. package/src/remote-lifecycle.ts +270 -0
  47. package/src/remote-session.ts +293 -38
  48. package/src/remote-tui.ts +129 -13
  49. package/src/remote-ui-handler.ts +86 -0
@@ -0,0 +1,270 @@
1
+ export type RemoteLifecyclePhase =
2
+ | 'connecting'
3
+ | 'hydrating'
4
+ | 'replaying'
5
+ | 'live'
6
+ | 'paused'
7
+ | 'resuming'
8
+ | 'reconnecting'
9
+ | 'disconnected';
10
+
11
+ export type RemoteTransportState = 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
12
+
13
+ export interface RemoteLifecycleState {
14
+ sessionId: string;
15
+ label: string;
16
+ transport: RemoteTransportState;
17
+ phase: RemoteLifecyclePhase;
18
+ leadConnected: boolean | null;
19
+ isStreaming: boolean;
20
+ hydrationReceived: boolean;
21
+ streamId: string | null;
22
+ streamUrl: string | null;
23
+ lastError: string | null;
24
+ }
25
+
26
+ export interface RemoteLifecycleWorkingMessageUi {
27
+ setWorkingMessage(message?: string): void;
28
+ }
29
+
30
+ export type RemoteLifecycleEvent =
31
+ | { type: 'connect_start'; reconnect: boolean }
32
+ | { type: 'init'; sessionId?: string; label?: string }
33
+ | {
34
+ type: 'hydration';
35
+ leadConnected?: boolean;
36
+ isStreaming?: boolean;
37
+ }
38
+ | { type: 'replay_event' }
39
+ | { type: 'replay_idle' }
40
+ | { type: 'live_signal'; isStreaming?: boolean }
41
+ | { type: 'session_resume'; streamId?: string | null; streamUrl?: string | null }
42
+ | { type: 'stream_ready'; streamId?: string | null; streamUrl?: string | null }
43
+ | { type: 'rpc_command_error'; error: string; paused: boolean }
44
+ | { type: 'local_resume_requested' }
45
+ | { type: 'connection_change'; state: 'reconnecting' | 'disconnected' };
46
+
47
+ export function createRemoteLifecycleState(sessionId: string): RemoteLifecycleState {
48
+ return {
49
+ sessionId,
50
+ label: '',
51
+ transport: 'disconnected',
52
+ phase: 'disconnected',
53
+ leadConnected: null,
54
+ isStreaming: false,
55
+ hydrationReceived: false,
56
+ streamId: null,
57
+ streamUrl: null,
58
+ lastError: null,
59
+ };
60
+ }
61
+
62
+ function patchState(
63
+ state: RemoteLifecycleState,
64
+ patch: Partial<RemoteLifecycleState>
65
+ ): RemoteLifecycleState {
66
+ let changed = false;
67
+ const next = { ...state };
68
+
69
+ for (const [key, value] of Object.entries(patch)) {
70
+ const typedKey = key as keyof RemoteLifecycleState;
71
+ if (next[typedKey] !== value) {
72
+ changed = true;
73
+ (next[typedKey] as RemoteLifecycleState[keyof RemoteLifecycleState]) =
74
+ value as RemoteLifecycleState[keyof RemoteLifecycleState];
75
+ }
76
+ }
77
+
78
+ return changed ? next : state;
79
+ }
80
+
81
+ function resolveConnectedPhase(input: {
82
+ leadConnected: boolean | null;
83
+ isStreaming: boolean;
84
+ }): RemoteLifecyclePhase {
85
+ if (input.isStreaming) return 'live';
86
+ if (input.leadConnected === false) return 'paused';
87
+ return 'live';
88
+ }
89
+
90
+ export function applyRemoteLifecycleEvent(
91
+ state: RemoteLifecycleState,
92
+ event: RemoteLifecycleEvent
93
+ ): RemoteLifecycleState {
94
+ switch (event.type) {
95
+ case 'connect_start':
96
+ return patchState(state, {
97
+ transport: event.reconnect ? 'reconnecting' : 'connecting',
98
+ phase: event.reconnect ? 'reconnecting' : 'connecting',
99
+ lastError: null,
100
+ });
101
+
102
+ case 'init':
103
+ return patchState(state, {
104
+ sessionId: event.sessionId || state.sessionId,
105
+ label: event.label || state.label,
106
+ transport: 'connected',
107
+ phase: 'hydrating',
108
+ lastError: null,
109
+ });
110
+
111
+ case 'hydration': {
112
+ const leadConnected =
113
+ typeof event.leadConnected === 'boolean' ? event.leadConnected : state.leadConnected;
114
+ const isStreaming =
115
+ typeof event.isStreaming === 'boolean' ? event.isStreaming : state.isStreaming;
116
+ return patchState(state, {
117
+ leadConnected,
118
+ isStreaming,
119
+ hydrationReceived: true,
120
+ transport: 'connected',
121
+ phase: resolveConnectedPhase({ leadConnected, isStreaming }),
122
+ lastError: null,
123
+ });
124
+ }
125
+
126
+ case 'replay_event':
127
+ if (state.transport !== 'connected') return state;
128
+ return patchState(state, {
129
+ phase: 'replaying',
130
+ });
131
+
132
+ case 'replay_idle':
133
+ if (state.phase !== 'replaying') return state;
134
+ return patchState(state, {
135
+ phase: resolveConnectedPhase({
136
+ leadConnected: state.leadConnected,
137
+ isStreaming: state.isStreaming,
138
+ }),
139
+ });
140
+
141
+ case 'live_signal':
142
+ return patchState(state, {
143
+ transport: 'connected',
144
+ phase: 'live',
145
+ leadConnected: true,
146
+ isStreaming:
147
+ typeof event.isStreaming === 'boolean' ? event.isStreaming : state.isStreaming,
148
+ lastError: null,
149
+ });
150
+
151
+ case 'session_resume':
152
+ return patchState(state, {
153
+ streamId: event.streamId ?? state.streamId,
154
+ streamUrl: event.streamUrl ?? state.streamUrl,
155
+ phase: 'resuming',
156
+ lastError: null,
157
+ });
158
+
159
+ case 'stream_ready':
160
+ return patchState(state, {
161
+ streamId: event.streamId ?? state.streamId,
162
+ streamUrl: event.streamUrl ?? state.streamUrl,
163
+ });
164
+
165
+ case 'rpc_command_error':
166
+ return patchState(state, {
167
+ lastError: event.error,
168
+ leadConnected: event.paused ? false : state.leadConnected,
169
+ isStreaming: event.paused ? false : state.isStreaming,
170
+ phase: event.paused ? 'paused' : state.phase,
171
+ });
172
+
173
+ case 'local_resume_requested':
174
+ return patchState(state, {
175
+ phase: 'resuming',
176
+ lastError: null,
177
+ });
178
+
179
+ case 'connection_change':
180
+ return patchState(state, {
181
+ transport: event.state,
182
+ phase: event.state,
183
+ isStreaming: false,
184
+ });
185
+ }
186
+ }
187
+
188
+ export function getRemoteLifecycleLabel(state: RemoteLifecycleState): string {
189
+ switch (state.phase) {
190
+ case 'connecting':
191
+ return 'Connecting';
192
+ case 'hydrating':
193
+ return 'Hydrating';
194
+ case 'replaying':
195
+ return 'Replaying';
196
+ case 'paused':
197
+ return 'Paused';
198
+ case 'resuming':
199
+ return 'Resuming';
200
+ case 'reconnecting':
201
+ return 'Reconnecting';
202
+ case 'disconnected':
203
+ return 'Disconnected';
204
+ case 'live':
205
+ return 'Live';
206
+ }
207
+ }
208
+
209
+ export function getRemoteLifecycleActivityLabel(state: RemoteLifecycleState): string | undefined {
210
+ switch (state.phase) {
211
+ case 'connecting':
212
+ return 'connecting to sandbox...';
213
+ case 'hydrating':
214
+ return 'hydrating remote session...';
215
+ case 'replaying':
216
+ return 'replaying remote history...';
217
+ case 'paused':
218
+ return 'sandbox paused';
219
+ case 'resuming':
220
+ return 'resuming sandbox...';
221
+ case 'reconnecting':
222
+ return 'reconnecting...';
223
+ case 'disconnected':
224
+ return state.lastError ? `disconnected: ${state.lastError}` : 'disconnected';
225
+ case 'live':
226
+ return undefined;
227
+ }
228
+ }
229
+
230
+ export function getRemoteLifecycleWorkingMessage(state: RemoteLifecycleState): string | undefined {
231
+ switch (state.phase) {
232
+ case 'connecting':
233
+ return 'Connecting to remote sandbox...';
234
+ case 'hydrating':
235
+ return 'Hydrating remote session...';
236
+ case 'replaying':
237
+ return 'Replaying remote history...';
238
+ case 'resuming':
239
+ return 'Resuming remote sandbox...';
240
+ case 'reconnecting':
241
+ return 'Connection lost - reconnecting...';
242
+ case 'paused':
243
+ case 'disconnected':
244
+ case 'live':
245
+ return undefined;
246
+ }
247
+ }
248
+
249
+ export function clearRemoteLifecycleWorkingMessage(
250
+ ui: RemoteLifecycleWorkingMessageUi,
251
+ lifecycleOwnsWorkingMessage: boolean
252
+ ): boolean {
253
+ if (lifecycleOwnsWorkingMessage) {
254
+ ui.setWorkingMessage();
255
+ }
256
+ return false;
257
+ }
258
+
259
+ export function syncRemoteLifecycleWorkingMessage(
260
+ state: RemoteLifecycleState,
261
+ ui: RemoteLifecycleWorkingMessageUi,
262
+ lifecycleOwnsWorkingMessage: boolean
263
+ ): boolean {
264
+ const working = getRemoteLifecycleWorkingMessage(state);
265
+ if (working) {
266
+ ui.setWorkingMessage(working);
267
+ return true;
268
+ }
269
+ return clearRemoteLifecycleWorkingMessage(ui, lifecycleOwnsWorkingMessage);
270
+ }