@agentuity/coder 1.0.37
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/README.md +57 -0
- package/dist/chain-preview.d.ts +55 -0
- package/dist/chain-preview.d.ts.map +1 -0
- package/dist/chain-preview.js +472 -0
- package/dist/chain-preview.js.map +1 -0
- package/dist/client.d.ts +43 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +402 -0
- package/dist/client.js.map +1 -0
- package/dist/commands.d.ts +22 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +99 -0
- package/dist/commands.js.map +1 -0
- package/dist/footer.d.ts +34 -0
- package/dist/footer.d.ts.map +1 -0
- package/dist/footer.js +249 -0
- package/dist/footer.js.map +1 -0
- package/dist/handlers.d.ts +24 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +83 -0
- package/dist/handlers.js.map +1 -0
- package/dist/hub-overlay.d.ts +107 -0
- package/dist/hub-overlay.d.ts.map +1 -0
- package/dist/hub-overlay.js +1794 -0
- package/dist/hub-overlay.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1585 -0
- package/dist/index.js.map +1 -0
- package/dist/output-viewer.d.ts +49 -0
- package/dist/output-viewer.d.ts.map +1 -0
- package/dist/output-viewer.js +389 -0
- package/dist/output-viewer.js.map +1 -0
- package/dist/overlay.d.ts +40 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +225 -0
- package/dist/overlay.js.map +1 -0
- package/dist/protocol.d.ts +118 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +3 -0
- package/dist/protocol.js.map +1 -0
- package/dist/remote-session.d.ts +113 -0
- package/dist/remote-session.d.ts.map +1 -0
- package/dist/remote-session.js +645 -0
- package/dist/remote-session.js.map +1 -0
- package/dist/remote-tui.d.ts +40 -0
- package/dist/remote-tui.d.ts.map +1 -0
- package/dist/remote-tui.js +606 -0
- package/dist/remote-tui.js.map +1 -0
- package/dist/renderers.d.ts +34 -0
- package/dist/renderers.d.ts.map +1 -0
- package/dist/renderers.js +669 -0
- package/dist/renderers.js.map +1 -0
- package/dist/review.d.ts +15 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +154 -0
- package/dist/review.js.map +1 -0
- package/dist/titlebar.d.ts +3 -0
- package/dist/titlebar.d.ts.map +1 -0
- package/dist/titlebar.js +59 -0
- package/dist/titlebar.js.map +1 -0
- package/dist/todo/index.d.ts +3 -0
- package/dist/todo/index.d.ts.map +1 -0
- package/dist/todo/index.js +3 -0
- package/dist/todo/index.js.map +1 -0
- package/dist/todo/store.d.ts +6 -0
- package/dist/todo/store.d.ts.map +1 -0
- package/dist/todo/store.js +43 -0
- package/dist/todo/store.js.map +1 -0
- package/dist/todo/types.d.ts +13 -0
- package/dist/todo/types.d.ts.map +1 -0
- package/dist/todo/types.js +2 -0
- package/dist/todo/types.js.map +1 -0
- package/package.json +44 -0
- package/src/chain-preview.ts +621 -0
- package/src/client.ts +515 -0
- package/src/commands.ts +132 -0
- package/src/footer.ts +305 -0
- package/src/handlers.ts +113 -0
- package/src/hub-overlay.ts +2324 -0
- package/src/index.ts +1907 -0
- package/src/output-viewer.ts +480 -0
- package/src/overlay.ts +294 -0
- package/src/protocol.ts +157 -0
- package/src/remote-session.ts +800 -0
- package/src/remote-tui.ts +707 -0
- package/src/renderers.ts +740 -0
- package/src/review.ts +201 -0
- package/src/titlebar.ts +63 -0
- package/src/todo/index.ts +2 -0
- package/src/todo/store.ts +49 -0
- package/src/todo/types.ts +14 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA0B1E,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,QAAQ,CAAC;AAmBvF,qBAAa,SAAS;IACrB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,wBAAwB,CAA+C;IAC/E,OAAO,CAAC,OAAO,CAOX;IAEG,eAAe,EAAE,eAAe,CAAY;IAC5C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3D,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;IAC1D,0FAA0F;IACnF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAEpE,+EAA+E;IAExE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,oBAAoB;YAQd,UAAU;IAyBxB,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,kBAAkB;YA+DZ,eAAe;IAkHvB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAyB9F,OAAO,CAAC,iBAAiB;IA4BzB,MAAM,IAAI,MAAM;IAIV,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAiCrD,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAezD,kBAAkB,CAAC,SAAS,SAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,KAAK,IAAI,IAAI;IA6Bb,IAAI,SAAS,IAAI,OAAO,CAEvB;CACD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/** How long to wait for a response before rejecting the pending promise (ms). */
|
|
2
|
+
const SEND_TIMEOUT_MS = 30_000;
|
|
3
|
+
/** How long to wait for the init message after connecting (ms). */
|
|
4
|
+
const CONNECT_TIMEOUT_MS = 30_000;
|
|
5
|
+
/** Reconnect backoff starts at 1s and doubles per attempt, capped at 30s. */
|
|
6
|
+
const RECONNECT_BASE_DELAY_MS = 1_000;
|
|
7
|
+
const RECONNECT_MAX_DELAY_MS = 30_000;
|
|
8
|
+
const RECONNECT_MAX_ATTEMPTS = 10;
|
|
9
|
+
const RECONNECT_JITTER_MAX_MS = 1_000;
|
|
10
|
+
/** Bound queue growth while disconnected. */
|
|
11
|
+
const MAX_QUEUED_MESSAGES = 1_000;
|
|
12
|
+
/** How long queued requests may wait for reconnection before failing. */
|
|
13
|
+
const QUEUED_REQUEST_TIMEOUT_MS = 120_000;
|
|
14
|
+
const DEBUG = !!process.env['AGENTUITY_DEBUG'];
|
|
15
|
+
function log(message) {
|
|
16
|
+
if (DEBUG)
|
|
17
|
+
console.error(`[agentuity-coder] ${message}`);
|
|
18
|
+
}
|
|
19
|
+
export class HubClient {
|
|
20
|
+
ws = null;
|
|
21
|
+
reconnectAttempts = 0;
|
|
22
|
+
reconnectTimer = null;
|
|
23
|
+
intentionallyClosed = false;
|
|
24
|
+
lastConnectUrl = null;
|
|
25
|
+
queue = [];
|
|
26
|
+
connectionStateListeners = new Set();
|
|
27
|
+
pending = new Map();
|
|
28
|
+
connectionState = 'closed';
|
|
29
|
+
onConnectionStateChange;
|
|
30
|
+
onBeforeReconnect;
|
|
31
|
+
onInitMessage;
|
|
32
|
+
/** Called when an unsolicited server message arrives (broadcast, presence, hydration). */
|
|
33
|
+
onServerMessage;
|
|
34
|
+
/** API key for Hub authentication (sent as x-agentuity-auth-api-key header) */
|
|
35
|
+
// TODO: Remove/Change when we get Agentuity service level auth enabled, this is just temporary
|
|
36
|
+
apiKey = null;
|
|
37
|
+
setConnectionState(state) {
|
|
38
|
+
if (this.connectionState === state)
|
|
39
|
+
return;
|
|
40
|
+
this.connectionState = state;
|
|
41
|
+
this.onConnectionStateChange?.(state);
|
|
42
|
+
for (const listener of this.connectionStateListeners)
|
|
43
|
+
listener(state);
|
|
44
|
+
}
|
|
45
|
+
buildWebSocketUrl(url) {
|
|
46
|
+
let wsUrl = url;
|
|
47
|
+
if (wsUrl.startsWith('http://')) {
|
|
48
|
+
wsUrl = 'ws://' + wsUrl.slice(7);
|
|
49
|
+
}
|
|
50
|
+
else if (wsUrl.startsWith('https://')) {
|
|
51
|
+
wsUrl = 'wss://' + wsUrl.slice(8);
|
|
52
|
+
}
|
|
53
|
+
else if (!wsUrl.startsWith('ws://') && !wsUrl.startsWith('wss://')) {
|
|
54
|
+
wsUrl = 'ws://' + wsUrl;
|
|
55
|
+
}
|
|
56
|
+
return wsUrl;
|
|
57
|
+
}
|
|
58
|
+
enqueue(message) {
|
|
59
|
+
if (this.queue.length >= MAX_QUEUED_MESSAGES) {
|
|
60
|
+
const dropped = this.queue.shift();
|
|
61
|
+
if (dropped?.kind === 'request') {
|
|
62
|
+
clearTimeout(dropped.queueTimer);
|
|
63
|
+
dropped.reject(new Error('Dropped queued request because queue reached maximum capacity'));
|
|
64
|
+
}
|
|
65
|
+
log(`Queue full (${MAX_QUEUED_MESSAGES}); dropping oldest queued message`);
|
|
66
|
+
}
|
|
67
|
+
this.queue.push(message);
|
|
68
|
+
}
|
|
69
|
+
sendRequestNow(request) {
|
|
70
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
71
|
+
return Promise.reject(new Error('WebSocket is not connected'));
|
|
72
|
+
}
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const timer = setTimeout(() => {
|
|
75
|
+
const entry = this.pending.get(request.id);
|
|
76
|
+
if (entry) {
|
|
77
|
+
this.pending.delete(request.id);
|
|
78
|
+
entry.reject(new Error(`Hub response timeout after ${SEND_TIMEOUT_MS}ms for request ${request.id}`));
|
|
79
|
+
}
|
|
80
|
+
}, SEND_TIMEOUT_MS);
|
|
81
|
+
this.pending.set(request.id, { resolve, reject, timer });
|
|
82
|
+
this.ws.send(JSON.stringify(request));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
sendFireAndForgetNow(message) {
|
|
86
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
87
|
+
this.enqueue({ kind: 'fire-and-forget', message });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.ws.send(JSON.stringify(message));
|
|
91
|
+
}
|
|
92
|
+
async flushQueue() {
|
|
93
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
94
|
+
return;
|
|
95
|
+
if (this.queue.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
const items = this.queue;
|
|
98
|
+
this.queue = [];
|
|
99
|
+
log(`Replaying ${items.length} queued message(s)`);
|
|
100
|
+
for (let i = 0; i < items.length; i++) {
|
|
101
|
+
const item = items[i];
|
|
102
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
103
|
+
this.queue = items.slice(i).concat(this.queue);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (item.kind === 'fire-and-forget') {
|
|
107
|
+
this.ws.send(JSON.stringify(item.message));
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
clearTimeout(item.queueTimer);
|
|
111
|
+
this.sendRequestNow(item.request).then(item.resolve).catch(item.reject);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
handleUnexpectedClose() {
|
|
115
|
+
for (const [id, entry] of this.pending) {
|
|
116
|
+
clearTimeout(entry.timer);
|
|
117
|
+
entry.reject(new Error('WebSocket closed while request in-flight'));
|
|
118
|
+
this.pending.delete(id);
|
|
119
|
+
}
|
|
120
|
+
this.ws = null;
|
|
121
|
+
if (this.intentionallyClosed) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.setConnectionState('disconnected');
|
|
125
|
+
this.startReconnectLoop();
|
|
126
|
+
}
|
|
127
|
+
clearReconnectTimer() {
|
|
128
|
+
if (this.reconnectTimer) {
|
|
129
|
+
clearTimeout(this.reconnectTimer);
|
|
130
|
+
this.reconnectTimer = null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
rejectQueuedRequests(reason) {
|
|
134
|
+
for (const item of this.queue) {
|
|
135
|
+
if (item.kind !== 'request')
|
|
136
|
+
continue;
|
|
137
|
+
clearTimeout(item.queueTimer);
|
|
138
|
+
item.reject(new Error(reason));
|
|
139
|
+
}
|
|
140
|
+
this.queue = [];
|
|
141
|
+
}
|
|
142
|
+
startReconnectLoop() {
|
|
143
|
+
if (this.reconnectTimer || this.intentionallyClosed)
|
|
144
|
+
return;
|
|
145
|
+
if (!this.lastConnectUrl) {
|
|
146
|
+
log('Cannot reconnect: missing previous connection URL');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const attemptReconnect = () => {
|
|
150
|
+
if (this.intentionallyClosed) {
|
|
151
|
+
this.reconnectTimer = null;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (this.reconnectAttempts >= RECONNECT_MAX_ATTEMPTS) {
|
|
155
|
+
log(`Reconnect failed after ${RECONNECT_MAX_ATTEMPTS} attempts; giving up`);
|
|
156
|
+
this.reconnectTimer = null;
|
|
157
|
+
this.setConnectionState('disconnected');
|
|
158
|
+
this.rejectQueuedRequests('Reconnect attempts exhausted before queued request could be sent');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const attempt = this.reconnectAttempts + 1;
|
|
162
|
+
const delay = Math.min(RECONNECT_MAX_DELAY_MS, RECONNECT_BASE_DELAY_MS * 2 ** this.reconnectAttempts);
|
|
163
|
+
const jitter = Math.floor(Math.random() * (RECONNECT_JITTER_MAX_MS + 1));
|
|
164
|
+
const waitMs = delay + jitter;
|
|
165
|
+
this.setConnectionState('reconnecting');
|
|
166
|
+
log(`Reconnect attempt ${attempt}/${RECONNECT_MAX_ATTEMPTS} in ${waitMs}ms ` +
|
|
167
|
+
`(base=${delay}ms, jitter=${jitter}ms)`);
|
|
168
|
+
this.reconnectTimer = setTimeout(async () => {
|
|
169
|
+
this.reconnectTimer = null;
|
|
170
|
+
if (this.intentionallyClosed)
|
|
171
|
+
return;
|
|
172
|
+
try {
|
|
173
|
+
if (this.onBeforeReconnect) {
|
|
174
|
+
await this.onBeforeReconnect();
|
|
175
|
+
}
|
|
176
|
+
await this.connectInternal(this.lastConnectUrl, true);
|
|
177
|
+
this.reconnectAttempts = 0;
|
|
178
|
+
log('Reconnected to Hub successfully');
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
this.reconnectAttempts += 1;
|
|
182
|
+
log(`Reconnect attempt ${attempt} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
183
|
+
attemptReconnect();
|
|
184
|
+
}
|
|
185
|
+
}, waitMs);
|
|
186
|
+
};
|
|
187
|
+
attemptReconnect();
|
|
188
|
+
}
|
|
189
|
+
async connectInternal(url, isReconnect = false) {
|
|
190
|
+
const wsUrl = this.buildWebSocketUrl(url);
|
|
191
|
+
// TODO: Remove/Change when we get Agentuity service level auth enabled, this is just temporary
|
|
192
|
+
// Bun extension: custom headers on WebSocket upgrade request
|
|
193
|
+
const ws = this.apiKey
|
|
194
|
+
? new WebSocket(wsUrl, { headers: { 'x-agentuity-auth-api-key': this.apiKey } })
|
|
195
|
+
: new WebSocket(wsUrl);
|
|
196
|
+
this.ws = ws;
|
|
197
|
+
return new Promise((resolve, reject) => {
|
|
198
|
+
let initResolved = false;
|
|
199
|
+
const connectTimer = setTimeout(() => {
|
|
200
|
+
if (!initResolved) {
|
|
201
|
+
reject(new Error(`Hub did not send init message within ${CONNECT_TIMEOUT_MS}ms`));
|
|
202
|
+
this.ws?.close();
|
|
203
|
+
}
|
|
204
|
+
}, CONNECT_TIMEOUT_MS);
|
|
205
|
+
ws.onmessage = (event) => {
|
|
206
|
+
let data;
|
|
207
|
+
try {
|
|
208
|
+
const raw = typeof event.data === 'string'
|
|
209
|
+
? event.data
|
|
210
|
+
: new TextDecoder().decode(event.data);
|
|
211
|
+
data = JSON.parse(raw);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Malformed or non-JSON frame — ignore
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// First message should be init
|
|
218
|
+
if (data.type === 'init' && !initResolved) {
|
|
219
|
+
initResolved = true;
|
|
220
|
+
clearTimeout(connectTimer);
|
|
221
|
+
const initMessage = data;
|
|
222
|
+
this.onInitMessage?.(initMessage);
|
|
223
|
+
this.setConnectionState('connected');
|
|
224
|
+
void this.flushQueue();
|
|
225
|
+
resolve(initMessage);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Explicit server-side rejection before init (expired session, duplicate lead, etc.)
|
|
229
|
+
if (!initResolved && data.type === 'connection_rejected') {
|
|
230
|
+
clearTimeout(connectTimer);
|
|
231
|
+
this.intentionallyClosed = true;
|
|
232
|
+
const code = typeof data.code === 'string' ? data.code : 'unknown';
|
|
233
|
+
const message = typeof data.message === 'string' ? data.message : 'Connection rejected';
|
|
234
|
+
reject(new Error(`Hub rejected connection (${code}): ${message}`));
|
|
235
|
+
try {
|
|
236
|
+
this.ws?.close();
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
/* ignore */
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Unsolicited server messages (broadcast, presence, hydration)
|
|
244
|
+
// These have a `type` field but no `id` matching a pending request.
|
|
245
|
+
const msgType = data.type;
|
|
246
|
+
if (msgType === 'broadcast' ||
|
|
247
|
+
msgType === 'presence' ||
|
|
248
|
+
msgType === 'session_hydration' ||
|
|
249
|
+
msgType === 'rpc_event' ||
|
|
250
|
+
msgType === 'rpc_response' ||
|
|
251
|
+
msgType === 'rpc_ui_request') {
|
|
252
|
+
this.onServerMessage?.(data);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
// Otherwise it's a response to a pending request
|
|
256
|
+
const response = data;
|
|
257
|
+
const entry = this.pending.get(response.id);
|
|
258
|
+
if (entry) {
|
|
259
|
+
clearTimeout(entry.timer);
|
|
260
|
+
this.pending.delete(response.id);
|
|
261
|
+
entry.resolve(response);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
ws.onerror = (err) => {
|
|
265
|
+
if (initResolved)
|
|
266
|
+
return;
|
|
267
|
+
const message = 'message' in err && typeof err.message === 'string'
|
|
268
|
+
? err.message
|
|
269
|
+
: `connection to ${wsUrl} failed`;
|
|
270
|
+
clearTimeout(connectTimer);
|
|
271
|
+
reject(new Error(`WebSocket error: ${message}`));
|
|
272
|
+
};
|
|
273
|
+
ws.onclose = (event) => {
|
|
274
|
+
clearTimeout(connectTimer);
|
|
275
|
+
if (!initResolved) {
|
|
276
|
+
const reason = event.reason ? ` (${event.reason})` : '';
|
|
277
|
+
reject(new Error(`WebSocket closed before init message received (code ${event.code})${reason}`));
|
|
278
|
+
}
|
|
279
|
+
if (isReconnect) {
|
|
280
|
+
this.setConnectionState('disconnected');
|
|
281
|
+
}
|
|
282
|
+
this.handleUnexpectedClose();
|
|
283
|
+
};
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async connect(url, opts) {
|
|
287
|
+
if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
|
|
288
|
+
throw new Error('Already connected or connecting — call close() first');
|
|
289
|
+
}
|
|
290
|
+
this.intentionallyClosed = false;
|
|
291
|
+
// Append query params for session/role targeting
|
|
292
|
+
let connectUrl = url;
|
|
293
|
+
if (opts?.sessionId) {
|
|
294
|
+
const separator = connectUrl.includes('?') ? '&' : '?';
|
|
295
|
+
connectUrl = `${connectUrl}${separator}sessionId=${encodeURIComponent(opts.sessionId)}`;
|
|
296
|
+
}
|
|
297
|
+
if (opts?.role) {
|
|
298
|
+
const separator = connectUrl.includes('?') ? '&' : '?';
|
|
299
|
+
connectUrl = `${connectUrl}${separator}role=${encodeURIComponent(opts.role)}`;
|
|
300
|
+
}
|
|
301
|
+
this.lastConnectUrl = connectUrl;
|
|
302
|
+
this.reconnectAttempts = 0;
|
|
303
|
+
this.clearReconnectTimer();
|
|
304
|
+
return this.connectInternal(connectUrl, false);
|
|
305
|
+
}
|
|
306
|
+
waitForConnection(timeoutMs) {
|
|
307
|
+
if (this.connected)
|
|
308
|
+
return Promise.resolve();
|
|
309
|
+
if (this.connectionState === 'disconnected') {
|
|
310
|
+
this.startReconnectLoop();
|
|
311
|
+
}
|
|
312
|
+
return new Promise((resolve, reject) => {
|
|
313
|
+
const timer = setTimeout(() => {
|
|
314
|
+
cleanup();
|
|
315
|
+
reject(new Error(`Timed out waiting for Hub reconnection after ${timeoutMs}ms`));
|
|
316
|
+
}, timeoutMs);
|
|
317
|
+
const listener = (state) => {
|
|
318
|
+
if (state !== 'connected')
|
|
319
|
+
return;
|
|
320
|
+
cleanup();
|
|
321
|
+
resolve();
|
|
322
|
+
};
|
|
323
|
+
const cleanup = () => {
|
|
324
|
+
clearTimeout(timer);
|
|
325
|
+
this.connectionStateListeners.delete(listener);
|
|
326
|
+
};
|
|
327
|
+
this.connectionStateListeners.add(listener);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
nextId() {
|
|
331
|
+
return crypto.randomUUID();
|
|
332
|
+
}
|
|
333
|
+
async send(request) {
|
|
334
|
+
if (this.connectionState === 'closed') {
|
|
335
|
+
throw new Error('WebSocket client is closed');
|
|
336
|
+
}
|
|
337
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
338
|
+
return new Promise((resolve, reject) => {
|
|
339
|
+
const queuedEntry = {
|
|
340
|
+
kind: 'request',
|
|
341
|
+
request,
|
|
342
|
+
resolve,
|
|
343
|
+
reject,
|
|
344
|
+
queueTimer: setTimeout(() => {
|
|
345
|
+
this.queue = this.queue.filter((item) => item !== queuedEntry);
|
|
346
|
+
reject(new Error(`Timed out waiting ${QUEUED_REQUEST_TIMEOUT_MS}ms for Hub reconnection`));
|
|
347
|
+
}, QUEUED_REQUEST_TIMEOUT_MS),
|
|
348
|
+
};
|
|
349
|
+
this.enqueue(queuedEntry);
|
|
350
|
+
if (this.connectionState === 'disconnected') {
|
|
351
|
+
this.startReconnectLoop();
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return this.sendRequestNow(request);
|
|
356
|
+
}
|
|
357
|
+
sendNoWait(message) {
|
|
358
|
+
if (this.connectionState === 'closed') {
|
|
359
|
+
log('Dropping fire-and-forget message because client is closed');
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
this.sendFireAndForgetNow(message);
|
|
363
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
364
|
+
if (this.connectionState === 'disconnected') {
|
|
365
|
+
this.startReconnectLoop();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async waitUntilConnected(timeoutMs = CONNECT_TIMEOUT_MS) {
|
|
370
|
+
await this.waitForConnection(timeoutMs);
|
|
371
|
+
}
|
|
372
|
+
close() {
|
|
373
|
+
this.intentionallyClosed = true;
|
|
374
|
+
this.setConnectionState('closed');
|
|
375
|
+
this.clearReconnectTimer();
|
|
376
|
+
for (const item of this.queue) {
|
|
377
|
+
if (item.kind !== 'request')
|
|
378
|
+
continue;
|
|
379
|
+
clearTimeout(item.queueTimer);
|
|
380
|
+
item.reject(new Error('WebSocket client closed before queued request was sent'));
|
|
381
|
+
}
|
|
382
|
+
this.queue = [];
|
|
383
|
+
for (const [id, entry] of this.pending) {
|
|
384
|
+
clearTimeout(entry.timer);
|
|
385
|
+
entry.reject(new Error('WebSocket client closed'));
|
|
386
|
+
this.pending.delete(id);
|
|
387
|
+
}
|
|
388
|
+
if (this.ws) {
|
|
389
|
+
// Detach handlers so the stale onclose doesn't trigger reconnect
|
|
390
|
+
// after a subsequent connect() resets intentionallyClosed.
|
|
391
|
+
this.ws.onclose = null;
|
|
392
|
+
this.ws.onerror = null;
|
|
393
|
+
this.ws.onmessage = null;
|
|
394
|
+
this.ws.close();
|
|
395
|
+
this.ws = null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
get connected() {
|
|
399
|
+
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,mEAAmE;AACnE,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,6EAA6E;AAC7E,MAAM,uBAAuB,GAAG,KAAK,CAAC;AACtC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC,6CAA6C;AAC7C,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAElC,yEAAyE;AACzE,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAE1C,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAE/C,SAAS,GAAG,CAAC,OAAe;IAC3B,IAAI,KAAK;QAAE,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC;AAqBD,MAAM,OAAO,SAAS;IACb,EAAE,GAAqB,IAAI,CAAC;IAC5B,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAAyC,IAAI,CAAC;IAC5D,mBAAmB,GAAG,KAAK,CAAC;IAC5B,cAAc,GAAkB,IAAI,CAAC;IACrC,KAAK,GAAoB,EAAE,CAAC;IAC5B,wBAAwB,GAAG,IAAI,GAAG,EAAoC,CAAC;IACvE,OAAO,GAAG,IAAI,GAAG,EAOtB,CAAC;IAEG,eAAe,GAAoB,QAAQ,CAAC;IAC5C,uBAAuB,CAAoC;IAC3D,iBAAiB,CAAuB;IACxC,aAAa,CAAsC;IAC1D,0FAA0F;IACnF,eAAe,CAA8C;IAEpE,+EAA+E;IAC/E,+FAA+F;IACxF,MAAM,GAAkB,IAAI,CAAC;IAE5B,kBAAkB,CAAC,KAAsB;QAChD,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK;YAAE,OAAO;QAC3C,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,uBAAuB,EAAE,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,wBAAwB;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvE,CAAC;IAEO,iBAAiB,CAAC,GAAW;QACpC,IAAI,KAAK,GAAG,GAAG,CAAC;QAChB,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtE,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;QACzB,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,OAAO,CAAC,OAAsB;QACrC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,OAAO,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACjC,OAAO,CAAC,MAAM,CACb,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAC1E,CAAC;YACH,CAAC;YACD,GAAG,CAAC,eAAe,mBAAmB,mCAAmC,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAEO,cAAc,CAAC,OAAmB;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACvD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC3C,IAAI,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBAChC,KAAK,CAAC,MAAM,CACX,IAAI,KAAK,CACR,8BAA8B,eAAe,kBAAkB,OAAO,CAAC,EAAE,EAAE,CAC3E,CACD,CAAC;gBACH,CAAC;YACF,CAAC,EAAE,eAAe,CAAC,CAAC;YAEpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,oBAAoB,CAAC,OAA6B;QACzD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,CAAC;YACnD,OAAO;QACR,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,UAAU;QACvB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC9D,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,aAAa,KAAK,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAEnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBACvD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACrC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC3C,SAAS;YACV,CAAC;YAED,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;IAEO,qBAAqB;QAC5B,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QAEf,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO;QACR,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;QACxC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC3B,CAAC;IAEO,mBAAmB;QAC1B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC5B,CAAC;IACF,CAAC;IAEO,oBAAoB,CAAC,MAAc;QAC1C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS;YACtC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IACjB,CAAC;IAEO,kBAAkB;QACzB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,mBAAmB;YAAE,OAAO;QAC5D,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACzD,OAAO;QACR,CAAC;QAED,MAAM,gBAAgB,GAAG,GAAS,EAAE;YACnC,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC9B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,OAAO;YACR,CAAC;YAED,IAAI,IAAI,CAAC,iBAAiB,IAAI,sBAAsB,EAAE,CAAC;gBACtD,GAAG,CAAC,0BAA0B,sBAAsB,sBAAsB,CAAC,CAAC;gBAC5E,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;gBACxC,IAAI,CAAC,oBAAoB,CACxB,kEAAkE,CAClE,CAAC;gBACF,OAAO;YACR,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACrB,sBAAsB,EACtB,uBAAuB,GAAG,CAAC,IAAI,IAAI,CAAC,iBAAiB,CACrD,CAAC;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,uBAAuB,GAAG,CAAC,CAAC,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;YAE9B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;YACxC,GAAG,CACF,qBAAqB,OAAO,IAAI,sBAAsB,OAAO,MAAM,KAAK;gBACvE,SAAS,KAAK,cAAc,MAAM,KAAK,CACxC,CAAC;YAEF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;gBAC3C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,IAAI,IAAI,CAAC,mBAAmB;oBAAE,OAAO;gBAErC,IAAI,CAAC;oBACJ,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAC5B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAChC,CAAC;oBACD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAe,EAAE,IAAI,CAAC,CAAC;oBACvD,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;oBAC3B,GAAG,CAAC,iCAAiC,CAAC,CAAC;gBACxC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;oBAC5B,GAAG,CACF,qBAAqB,OAAO,YAC3B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAChD,EAAE,CACF,CAAC;oBACF,gBAAgB,EAAE,CAAC;gBACpB,CAAC;YACF,CAAC,EAAE,MAAM,CAAC,CAAC;QACZ,CAAC,CAAC;QAEF,gBAAgB,EAAE,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,GAAW,EAAE,WAAW,GAAG,KAAK;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC1C,+FAA+F;QAC/F,6DAA6D;QAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM;YACrB,CAAC,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,0BAA0B,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAChF,CAAC,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,YAAY,GAAG,KAAK,CAAC;YAEzB,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;gBACpC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,wCAAwC,kBAAkB,IAAI,CAAC,CAAC,CAAC;oBAClF,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;gBAClB,CAAC;YACF,CAAC,EAAE,kBAAkB,CAAC,CAAC;YAEvB,EAAE,CAAC,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;gBACtC,IAAI,IAA6B,CAAC;gBAClC,IAAI,CAAC;oBACJ,MAAM,GAAG,GACR,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;wBAC7B,CAAC,CAAC,KAAK,CAAC,IAAI;wBACZ,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAmB,CAAC,CAAC;oBACxD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACR,uCAAuC;oBACvC,OAAO;gBACR,CAAC;gBAED,+BAA+B;gBAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC3C,YAAY,GAAG,IAAI,CAAC;oBACpB,YAAY,CAAC,YAAY,CAAC,CAAC;oBAC3B,MAAM,WAAW,GAAG,IAA8B,CAAC;oBACnD,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,CAAC,CAAC;oBAClC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;oBACrC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;oBACvB,OAAO,CAAC,WAAW,CAAC,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,qFAAqF;gBACrF,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;oBAC1D,YAAY,CAAC,YAAY,CAAC,CAAC;oBAC3B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;oBAChC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;oBACnE,MAAM,OAAO,GACZ,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;oBACzE,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC;oBACnE,IAAI,CAAC;wBACJ,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;oBAClB,CAAC;oBAAC,MAAM,CAAC;wBACR,YAAY;oBACb,CAAC;oBACD,OAAO;gBACR,CAAC;gBAED,+DAA+D;gBAC/D,oEAAoE;gBACpE,MAAM,OAAO,GAAG,IAAI,CAAC,IAA0B,CAAC;gBAChD,IACC,OAAO,KAAK,WAAW;oBACvB,OAAO,KAAK,UAAU;oBACtB,OAAO,KAAK,mBAAmB;oBAC/B,OAAO,KAAK,WAAW;oBACvB,OAAO,KAAK,cAAc;oBAC1B,OAAO,KAAK,gBAAgB,EAC3B,CAAC;oBACF,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC;oBAC7B,OAAO;gBACR,CAAC;gBAED,iDAAiD;gBACjD,MAAM,QAAQ,GAAG,IAA8B,CAAC;gBAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC5C,IAAI,KAAK,EAAE,CAAC;oBACX,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;oBACjC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;YACF,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;gBAC3B,IAAI,YAAY;oBAAE,OAAO;gBAEzB,MAAM,OAAO,GACZ,SAAS,IAAI,GAAG,IAAI,OAAQ,GAAkB,CAAC,OAAO,KAAK,QAAQ;oBAClE,CAAC,CAAE,GAAkB,CAAC,OAAO;oBAC7B,CAAC,CAAC,iBAAiB,KAAK,SAAS,CAAC;gBACpC,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC,CAAC;YAClD,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,CAAC,KAAiB,EAAE,EAAE;gBAClC,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,MAAM,CACL,IAAI,KAAK,CACR,uDAAuD,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,CAC7E,CACD,CAAC;gBACH,CAAC;gBACD,IAAI,WAAW,EAAE,CAAC;oBACjB,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;gBACzC,CAAC;gBACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC9B,CAAC,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,IAA4C;QACtE,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QAEjC,iDAAiD;QACjD,IAAI,UAAU,GAAG,GAAG,CAAC;QACrB,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACvD,UAAU,GAAG,GAAG,UAAU,GAAG,SAAS,aAAa,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzF,CAAC;QACD,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACvD,UAAU,GAAG,GAAG,UAAU,GAAG,SAAS,QAAQ,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/E,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC;QACjC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAEO,iBAAiB,CAAC,SAAiB;QAC1C,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAE7C,IAAI,IAAI,CAAC,eAAe,KAAK,cAAc,EAAE,CAAC;YAC7C,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC7B,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,SAAS,IAAI,CAAC,CAAC,CAAC;YAClF,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,MAAM,QAAQ,GAAG,CAAC,KAAsB,EAAQ,EAAE;gBACjD,IAAI,KAAK,KAAK,WAAW;oBAAE,OAAO;gBAClC,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;YACX,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,GAAS,EAAE;gBAC1B,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChD,CAAC,CAAC;YAEF,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM;QACL,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC7B,IAAI,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACvD,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnD,MAAM,WAAW,GAAyB;oBACzC,IAAI,EAAE,SAAS;oBACf,OAAO;oBACP,OAAO;oBACP,MAAM;oBACN,UAAU,EAAE,UAAU,CAAC,GAAG,EAAE;wBAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;wBAC/D,MAAM,CACL,IAAI,KAAK,CACR,qBAAqB,yBAAyB,yBAAyB,CACvE,CACD,CAAC;oBACH,CAAC,EAAE,yBAAyB,CAAC;iBAC7B,CAAC;gBAEF,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAE1B,IAAI,IAAI,CAAC,eAAe,KAAK,cAAc,EAAE,CAAC;oBAC7C,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC3B,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,UAAU,CAAC,OAA6C;QACvD,IAAI,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YACvC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YACjE,OAAO;QACR,CAAC;QAED,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,IAAI,CAAC,eAAe,KAAK,cAAc,EAAE,CAAC;gBAC7C,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC3B,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,SAAS,GAAG,kBAAkB;QACtD,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS;YACtC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAEhB,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,iEAAiE;YACjE,2DAA2D;YAC3D,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QAChB,CAAC;IACF,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,CAAC;IAClE,CAAC;CACD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slash commands for routing to specific Coder Hub agents.
|
|
3
|
+
*
|
|
4
|
+
* Registers /lead, /memory, /product, etc. that prefix the user's
|
|
5
|
+
* message with routing instructions so the lead agent delegates
|
|
6
|
+
* to the specified agent.
|
|
7
|
+
*
|
|
8
|
+
* When the user types `/memory what happened last session`, the command
|
|
9
|
+
* handler sends a user message with a routing prefix that the lead agent
|
|
10
|
+
* recognizes and delegates accordingly.
|
|
11
|
+
*/
|
|
12
|
+
import type { ExtensionAPI, ExtensionCommandContext } from '@mariozechner/pi-coding-agent';
|
|
13
|
+
import type { AgentDefinition } from './protocol.ts';
|
|
14
|
+
type HubStatus = 'connected' | 'reconnecting' | 'offline';
|
|
15
|
+
/**
|
|
16
|
+
* Register slash commands for each Hub agent.
|
|
17
|
+
* When invoked, the command sends a user message prefixed with a routing directive
|
|
18
|
+
* so the lead agent knows to delegate to the specified agent.
|
|
19
|
+
*/
|
|
20
|
+
export declare function registerAgentCommands(pi: ExtensionAPI, agents: AgentDefinition[], getHubStatus: () => HubStatus, openAgentManager?: (ctx: ExtensionCommandContext) => Promise<void>, openChainEditor?: (ctx: ExtensionCommandContext, initialAgents: string[]) => Promise<void>): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,KAAK,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,CAAC;AAQ1D;;;;GAIG;AACH,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,eAAe,EAAE,EACzB,YAAY,EAAE,MAAM,SAAS,EAC7B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,EAClE,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GACxF,IAAI,CAiGN"}
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { handleReview } from "./review.js";
|
|
2
|
+
const DEBUG = !!process.env['AGENTUITY_DEBUG'];
|
|
3
|
+
function log(msg) {
|
|
4
|
+
if (DEBUG)
|
|
5
|
+
console.error(`[agentuity-coder] ${msg}`);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Register slash commands for each Hub agent.
|
|
9
|
+
* When invoked, the command sends a user message prefixed with a routing directive
|
|
10
|
+
* so the lead agent knows to delegate to the specified agent.
|
|
11
|
+
*/
|
|
12
|
+
export function registerAgentCommands(pi, agents, getHubStatus, openAgentManager, openChainEditor) {
|
|
13
|
+
for (const agent of agents) {
|
|
14
|
+
const name = agent.name;
|
|
15
|
+
log(`Registering command: /${name}`);
|
|
16
|
+
pi.registerCommand(name, {
|
|
17
|
+
description: `Route to ${name} agent: ${agent.description}`,
|
|
18
|
+
handler: async (args, ctx) => {
|
|
19
|
+
const trimmed = args.trim();
|
|
20
|
+
if (!trimmed) {
|
|
21
|
+
if (ctx.hasUI) {
|
|
22
|
+
ctx.ui.notify(`Usage: /${name} <message>`, 'info');
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Send a user message with routing prefix.
|
|
27
|
+
// The lead agent's system prompt recognizes [ROUTE TO: <agent>]
|
|
28
|
+
// and delegates to that agent.
|
|
29
|
+
pi.sendUserMessage(`@${name} ${trimmed}`, { deliverAs: 'followUp' });
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Register the /agents command that lists all available agents
|
|
34
|
+
pi.registerCommand('agents', {
|
|
35
|
+
description: 'List all available Coder Hub agents',
|
|
36
|
+
handler: async (_args, ctx) => {
|
|
37
|
+
if (ctx.hasUI && openAgentManager) {
|
|
38
|
+
await openAgentManager(ctx);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const lines = agents.map((a) => {
|
|
42
|
+
const model = a.model ? ` [${a.model}]` : '';
|
|
43
|
+
const caps = a.capabilities?.length ? ` (${a.capabilities.join(', ')})` : '';
|
|
44
|
+
const readOnly = a.readOnly ? ' [read-only]' : '';
|
|
45
|
+
return ` ${a.name}${model}${readOnly}\n ${a.description}${caps}`;
|
|
46
|
+
});
|
|
47
|
+
const message = `Available agents:\n${lines.join('\n')}`;
|
|
48
|
+
if (ctx.hasUI) {
|
|
49
|
+
ctx.ui.notify(message, 'info');
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
pi.registerCommand('chain', {
|
|
54
|
+
description: 'Open chain editor to compose multi-agent execution',
|
|
55
|
+
handler: async (args, ctx) => {
|
|
56
|
+
if (!ctx.hasUI || !openChainEditor) {
|
|
57
|
+
if (ctx.hasUI) {
|
|
58
|
+
ctx.ui.notify('Chain editor requires an interactive UI session.', 'warning');
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const initialAgents = args
|
|
63
|
+
.split(/\s+/)
|
|
64
|
+
.map((part) => part.trim())
|
|
65
|
+
.filter((part) => part.length > 0);
|
|
66
|
+
await openChainEditor(ctx, initialAgents);
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
// Register the /status command that shows current session status
|
|
70
|
+
pi.registerCommand('status', {
|
|
71
|
+
description: 'Show current session status',
|
|
72
|
+
handler: async (_args, ctx) => {
|
|
73
|
+
const hubStatus = getHubStatus();
|
|
74
|
+
const lines = [];
|
|
75
|
+
lines.push('Coder Hub Status');
|
|
76
|
+
lines.push(` Hub: ${hubStatus}`);
|
|
77
|
+
lines.push(` Agents: ${agents.length} available`);
|
|
78
|
+
lines.push(` ${agents
|
|
79
|
+
.map((a) => {
|
|
80
|
+
const model = a.model || 'default';
|
|
81
|
+
return `${a.name} [${model}]`;
|
|
82
|
+
})
|
|
83
|
+
.join(', ')}`);
|
|
84
|
+
const message = lines.join('\n');
|
|
85
|
+
if (ctx.hasUI) {
|
|
86
|
+
ctx.ui.notify(message, 'info');
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
// Register /review command for interactive code reviews
|
|
91
|
+
pi.registerCommand('review', {
|
|
92
|
+
description: 'Launch interactive code review',
|
|
93
|
+
handler: async (args, ctx) => {
|
|
94
|
+
await handleReview(args, ctx, pi);
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
log(`Registered ${agents.length} agent commands + /agents + /chain + /status + /review`);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/footer.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coder footer for the Pi TUI.
|
|
3
|
+
*
|
|
4
|
+
* Uses transparent backgrounds with foreground-only ANSI true-color text.
|
|
5
|
+
* Includes a braille spinner animation when an agent is actively working.
|
|
6
|
+
*
|
|
7
|
+
* Layout:
|
|
8
|
+
* [brand] [branch] > [model/agent] [hub] | [N] label token-stats
|
|
9
|
+
*
|
|
10
|
+
* Observer awareness (ASCII only):
|
|
11
|
+
* [3] SwiftRaven — 3 observers watching, session label "SwiftRaven"
|
|
12
|
+
*/
|
|
13
|
+
import type { ExtensionContext } from '@mariozechner/pi-coding-agent';
|
|
14
|
+
type HubStatus = 'connected' | 'reconnecting' | 'offline';
|
|
15
|
+
/** Observer state provided by the extension's presence tracking. */
|
|
16
|
+
export interface ObserverState {
|
|
17
|
+
/** Number of observers watching this session (excludes lead + sub-agents). */
|
|
18
|
+
count: number;
|
|
19
|
+
/** Human-readable session label (e.g. "SwiftRaven"). */
|
|
20
|
+
label: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Set up the Coder footer (transparent bg, foreground-colored text).
|
|
24
|
+
* Call this once with the extension context to replace Pi's default footer.
|
|
25
|
+
*
|
|
26
|
+
* Includes a braille spinner animation when an agent is actively working.
|
|
27
|
+
*
|
|
28
|
+
* @param ctx Extension context with UI access
|
|
29
|
+
* @param getHubStatus Callback that returns current Hub connection status
|
|
30
|
+
* @param getObserverState Optional callback that returns observer count + session label
|
|
31
|
+
*/
|
|
32
|
+
export declare function setupCoderFooter(ctx: ExtensionContext, getHubStatus: () => HubStatus, getObserverState?: () => ObserverState): void;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=footer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../src/footer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAA8B,MAAM,+BAA+B,CAAC;AA4BlG,KAAK,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,CAAC;AAE1D,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC7B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;CACd;AAoID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,MAAM,SAAS,EAC7B,gBAAgB,CAAC,EAAE,MAAM,aAAa,GACpC,IAAI,CA6GN"}
|