@sonde/agent 0.0.0

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 (149) hide show
  1. package/dist/cli/packs.d.ts +23 -0
  2. package/dist/cli/packs.d.ts.map +1 -0
  3. package/dist/cli/packs.js +172 -0
  4. package/dist/cli/packs.js.map +1 -0
  5. package/dist/cli/packs.test.d.ts +2 -0
  6. package/dist/cli/packs.test.d.ts.map +1 -0
  7. package/dist/cli/packs.test.js +171 -0
  8. package/dist/cli/packs.test.js.map +1 -0
  9. package/dist/config.d.ts +18 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +38 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/index.d.ts +13 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +191 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/runtime/attestation.d.ts +9 -0
  18. package/dist/runtime/attestation.d.ts.map +1 -0
  19. package/dist/runtime/attestation.js +32 -0
  20. package/dist/runtime/attestation.js.map +1 -0
  21. package/dist/runtime/attestation.test.d.ts +2 -0
  22. package/dist/runtime/attestation.test.d.ts.map +1 -0
  23. package/dist/runtime/attestation.test.js +59 -0
  24. package/dist/runtime/attestation.test.js.map +1 -0
  25. package/dist/runtime/audit.d.ts +19 -0
  26. package/dist/runtime/audit.d.ts.map +1 -0
  27. package/dist/runtime/audit.js +52 -0
  28. package/dist/runtime/audit.js.map +1 -0
  29. package/dist/runtime/audit.test.d.ts +2 -0
  30. package/dist/runtime/audit.test.d.ts.map +1 -0
  31. package/dist/runtime/audit.test.js +53 -0
  32. package/dist/runtime/audit.test.js.map +1 -0
  33. package/dist/runtime/connection.d.ts +55 -0
  34. package/dist/runtime/connection.d.ts.map +1 -0
  35. package/dist/runtime/connection.js +325 -0
  36. package/dist/runtime/connection.js.map +1 -0
  37. package/dist/runtime/connection.test.d.ts +2 -0
  38. package/dist/runtime/connection.test.d.ts.map +1 -0
  39. package/dist/runtime/connection.test.js +221 -0
  40. package/dist/runtime/connection.test.js.map +1 -0
  41. package/dist/runtime/executor.d.ts +21 -0
  42. package/dist/runtime/executor.d.ts.map +1 -0
  43. package/dist/runtime/executor.js +89 -0
  44. package/dist/runtime/executor.js.map +1 -0
  45. package/dist/runtime/executor.test.d.ts +2 -0
  46. package/dist/runtime/executor.test.d.ts.map +1 -0
  47. package/dist/runtime/executor.test.js +88 -0
  48. package/dist/runtime/executor.test.js.map +1 -0
  49. package/dist/runtime/privilege.d.ts +9 -0
  50. package/dist/runtime/privilege.d.ts.map +1 -0
  51. package/dist/runtime/privilege.js +35 -0
  52. package/dist/runtime/privilege.js.map +1 -0
  53. package/dist/runtime/privilege.test.d.ts +2 -0
  54. package/dist/runtime/privilege.test.d.ts.map +1 -0
  55. package/dist/runtime/privilege.test.js +22 -0
  56. package/dist/runtime/privilege.test.js.map +1 -0
  57. package/dist/runtime/scrubber.d.ts +17 -0
  58. package/dist/runtime/scrubber.d.ts.map +1 -0
  59. package/dist/runtime/scrubber.js +84 -0
  60. package/dist/runtime/scrubber.js.map +1 -0
  61. package/dist/runtime/scrubber.test.d.ts +2 -0
  62. package/dist/runtime/scrubber.test.d.ts.map +1 -0
  63. package/dist/runtime/scrubber.test.js +72 -0
  64. package/dist/runtime/scrubber.test.js.map +1 -0
  65. package/dist/system/scanner.d.ts +32 -0
  66. package/dist/system/scanner.d.ts.map +1 -0
  67. package/dist/system/scanner.js +90 -0
  68. package/dist/system/scanner.js.map +1 -0
  69. package/dist/system/scanner.test.d.ts +2 -0
  70. package/dist/system/scanner.test.d.ts.map +1 -0
  71. package/dist/system/scanner.test.js +121 -0
  72. package/dist/system/scanner.test.js.map +1 -0
  73. package/dist/tui/installer/InstallerApp.d.ts +11 -0
  74. package/dist/tui/installer/InstallerApp.d.ts.map +1 -0
  75. package/dist/tui/installer/InstallerApp.js +32 -0
  76. package/dist/tui/installer/InstallerApp.js.map +1 -0
  77. package/dist/tui/installer/StepComplete.d.ts +9 -0
  78. package/dist/tui/installer/StepComplete.d.ts.map +1 -0
  79. package/dist/tui/installer/StepComplete.js +46 -0
  80. package/dist/tui/installer/StepComplete.js.map +1 -0
  81. package/dist/tui/installer/StepHub.d.ts +8 -0
  82. package/dist/tui/installer/StepHub.d.ts.map +1 -0
  83. package/dist/tui/installer/StepHub.js +65 -0
  84. package/dist/tui/installer/StepHub.js.map +1 -0
  85. package/dist/tui/installer/StepPacks.d.ts +9 -0
  86. package/dist/tui/installer/StepPacks.d.ts.map +1 -0
  87. package/dist/tui/installer/StepPacks.js +35 -0
  88. package/dist/tui/installer/StepPacks.js.map +1 -0
  89. package/dist/tui/installer/StepPermissions.d.ts +9 -0
  90. package/dist/tui/installer/StepPermissions.d.ts.map +1 -0
  91. package/dist/tui/installer/StepPermissions.js +39 -0
  92. package/dist/tui/installer/StepPermissions.js.map +1 -0
  93. package/dist/tui/installer/StepScan.d.ts +7 -0
  94. package/dist/tui/installer/StepScan.d.ts.map +1 -0
  95. package/dist/tui/installer/StepScan.js +38 -0
  96. package/dist/tui/installer/StepScan.js.map +1 -0
  97. package/dist/tui/manager/ActivityLog.d.ts +7 -0
  98. package/dist/tui/manager/ActivityLog.d.ts.map +1 -0
  99. package/dist/tui/manager/ActivityLog.js +25 -0
  100. package/dist/tui/manager/ActivityLog.js.map +1 -0
  101. package/dist/tui/manager/AuditView.d.ts +7 -0
  102. package/dist/tui/manager/AuditView.d.ts.map +1 -0
  103. package/dist/tui/manager/AuditView.js +32 -0
  104. package/dist/tui/manager/AuditView.js.map +1 -0
  105. package/dist/tui/manager/ManagerApp.d.ts +20 -0
  106. package/dist/tui/manager/ManagerApp.d.ts.map +1 -0
  107. package/dist/tui/manager/ManagerApp.js +79 -0
  108. package/dist/tui/manager/ManagerApp.js.map +1 -0
  109. package/dist/tui/manager/PackManager.d.ts +7 -0
  110. package/dist/tui/manager/PackManager.d.ts.map +1 -0
  111. package/dist/tui/manager/PackManager.js +22 -0
  112. package/dist/tui/manager/PackManager.js.map +1 -0
  113. package/dist/tui/manager/StatusView.d.ts +15 -0
  114. package/dist/tui/manager/StatusView.d.ts.map +1 -0
  115. package/dist/tui/manager/StatusView.js +10 -0
  116. package/dist/tui/manager/StatusView.js.map +1 -0
  117. package/package.json +45 -0
  118. package/scripts/install.sh +11 -0
  119. package/src/cli/packs.test.ts +213 -0
  120. package/src/cli/packs.ts +214 -0
  121. package/src/config.ts +62 -0
  122. package/src/index.ts +218 -0
  123. package/src/runtime/attestation.test.ts +69 -0
  124. package/src/runtime/attestation.ts +36 -0
  125. package/src/runtime/audit.test.ts +64 -0
  126. package/src/runtime/audit.ts +70 -0
  127. package/src/runtime/connection.test.ts +303 -0
  128. package/src/runtime/connection.ts +389 -0
  129. package/src/runtime/executor.test.ts +112 -0
  130. package/src/runtime/executor.ts +107 -0
  131. package/src/runtime/privilege.test.ts +25 -0
  132. package/src/runtime/privilege.ts +36 -0
  133. package/src/runtime/scrubber.test.ts +84 -0
  134. package/src/runtime/scrubber.ts +96 -0
  135. package/src/system/scanner.test.ts +154 -0
  136. package/src/system/scanner.ts +133 -0
  137. package/src/tui/installer/InstallerApp.tsx +86 -0
  138. package/src/tui/installer/StepComplete.tsx +94 -0
  139. package/src/tui/installer/StepHub.tsx +111 -0
  140. package/src/tui/installer/StepPacks.tsx +73 -0
  141. package/src/tui/installer/StepPermissions.tsx +104 -0
  142. package/src/tui/installer/StepScan.tsx +82 -0
  143. package/src/tui/manager/ActivityLog.tsx +57 -0
  144. package/src/tui/manager/AuditView.tsx +73 -0
  145. package/src/tui/manager/ManagerApp.tsx +157 -0
  146. package/src/tui/manager/PackManager.tsx +71 -0
  147. package/src/tui/manager/StatusView.tsx +103 -0
  148. package/tsconfig.json +13 -0
  149. package/vitest.config.ts +8 -0
@@ -0,0 +1,325 @@
1
+ import fs from 'node:fs';
2
+ import { HEARTBEAT_INTERVAL_MS, MessageEnvelope as MessageEnvelopeSchema, ProbeRequest as ProbeRequestSchema, signPayload, verifyPayload, } from '@sonde/shared';
3
+ import WebSocket from 'ws';
4
+ import { saveCerts } from '../config.js';
5
+ import { generateAttestation } from './attestation.js';
6
+ import { AgentAuditLog } from './audit.js';
7
+ /** Minimum/maximum reconnect delays */
8
+ const MIN_RECONNECT_MS = 1_000;
9
+ const MAX_RECONNECT_MS = 60_000;
10
+ const ENROLL_TIMEOUT_MS = 10_000;
11
+ /**
12
+ * One-shot enrollment: connect to hub, register, get agentId, disconnect.
13
+ * If enrollmentToken is set in config, includes it in registration for cert-based enrollment.
14
+ * Returns { agentId, certIssued } — certIssued is true if certs were saved.
15
+ */
16
+ export function enrollWithHub(config, executor) {
17
+ return new Promise((resolve, reject) => {
18
+ const wsUrl = `${config.hubUrl.replace(/^http/, 'ws')}/ws/agent`;
19
+ const ws = new WebSocket(wsUrl, {
20
+ headers: { Authorization: `Bearer ${config.apiKey}` },
21
+ });
22
+ const timeout = setTimeout(() => {
23
+ ws.close();
24
+ reject(new Error('Enrollment timed out waiting for hub acknowledgement'));
25
+ }, ENROLL_TIMEOUT_MS);
26
+ ws.on('open', () => {
27
+ const payload = {
28
+ name: config.agentName,
29
+ os: `${process.platform} ${process.arch}`,
30
+ agentVersion: '0.1.0',
31
+ packs: executor.getLoadedPacks(),
32
+ attestation: generateAttestation(config, executor),
33
+ };
34
+ if (config.enrollmentToken) {
35
+ payload.enrollmentToken = config.enrollmentToken;
36
+ }
37
+ ws.send(JSON.stringify({
38
+ id: crypto.randomUUID(),
39
+ type: 'agent.register',
40
+ timestamp: new Date().toISOString(),
41
+ signature: '',
42
+ payload,
43
+ }));
44
+ });
45
+ ws.on('message', (data) => {
46
+ let envelope;
47
+ try {
48
+ envelope = MessageEnvelopeSchema.parse(JSON.parse(data.toString()));
49
+ }
50
+ catch {
51
+ return;
52
+ }
53
+ if (envelope.type === 'hub.ack') {
54
+ clearTimeout(timeout);
55
+ const ackPayload = envelope.payload;
56
+ ws.close();
57
+ if (ackPayload.error) {
58
+ reject(new Error(ackPayload.error));
59
+ return;
60
+ }
61
+ const agentId = ackPayload.agentId;
62
+ if (!agentId) {
63
+ reject(new Error('Hub ack did not contain agentId'));
64
+ return;
65
+ }
66
+ // If hub issued certs, save them
67
+ let certIssued = false;
68
+ if (ackPayload.certPem && ackPayload.keyPem && ackPayload.caCertPem) {
69
+ saveCerts(config, ackPayload.certPem, ackPayload.keyPem, ackPayload.caCertPem);
70
+ certIssued = true;
71
+ }
72
+ resolve({ agentId, certIssued });
73
+ }
74
+ });
75
+ ws.on('error', (err) => {
76
+ clearTimeout(timeout);
77
+ reject(err);
78
+ });
79
+ });
80
+ }
81
+ /** Build WebSocket options, including TLS client cert if available. */
82
+ function buildWsOptions(config) {
83
+ const options = {
84
+ headers: {
85
+ Authorization: `Bearer ${config.apiKey}`,
86
+ },
87
+ };
88
+ if (config.certPath && config.keyPath && config.caCertPath) {
89
+ try {
90
+ options.cert = fs.readFileSync(config.certPath, 'utf-8');
91
+ options.key = fs.readFileSync(config.keyPath, 'utf-8');
92
+ options.ca = [fs.readFileSync(config.caCertPath, 'utf-8')];
93
+ options.rejectUnauthorized = false; // Hub uses self-signed CA cert
94
+ }
95
+ catch {
96
+ // Cert files missing or unreadable — fall back to API key only
97
+ }
98
+ }
99
+ return options;
100
+ }
101
+ export class AgentConnection {
102
+ config;
103
+ executor;
104
+ events;
105
+ ws = null;
106
+ heartbeatTimer = null;
107
+ reconnectTimer = null;
108
+ reconnectAttempts = 0;
109
+ agentId;
110
+ running = false;
111
+ privateKeyPem;
112
+ caCertPem;
113
+ auditLog = new AgentAuditLog();
114
+ constructor(config, executor, events = {}) {
115
+ this.config = config;
116
+ this.executor = executor;
117
+ this.events = events;
118
+ // Load private key for signing outbound messages
119
+ if (config.keyPath) {
120
+ try {
121
+ this.privateKeyPem = fs.readFileSync(config.keyPath, 'utf-8');
122
+ }
123
+ catch {
124
+ // Key not available — messages will be sent unsigned
125
+ }
126
+ }
127
+ // Load CA cert for verifying hub messages
128
+ if (config.caCertPath) {
129
+ try {
130
+ this.caCertPem = fs.readFileSync(config.caCertPath, 'utf-8');
131
+ }
132
+ catch {
133
+ // CA cert not available — skip verification
134
+ }
135
+ }
136
+ }
137
+ /** Start the connection (connect + auto-reconnect loop) */
138
+ start() {
139
+ this.running = true;
140
+ this.connect();
141
+ }
142
+ /** Stop the connection cleanly */
143
+ stop() {
144
+ this.running = false;
145
+ this.clearTimers();
146
+ if (this.ws) {
147
+ this.ws.close(1000, 'Agent shutting down');
148
+ this.ws = null;
149
+ }
150
+ }
151
+ /** Whether we're currently connected */
152
+ isConnected() {
153
+ return this.ws?.readyState === WebSocket.OPEN;
154
+ }
155
+ /** Get the assigned agent ID (set after registration) */
156
+ getAgentId() {
157
+ return this.agentId;
158
+ }
159
+ connect() {
160
+ const wsUrl = `${this.config.hubUrl.replace(/^http/, 'ws')}/ws/agent`;
161
+ const options = buildWsOptions(this.config);
162
+ this.ws = new WebSocket(wsUrl, options);
163
+ this.ws.on('open', () => {
164
+ this.reconnectAttempts = 0;
165
+ this.sendRegister();
166
+ this.startHeartbeat();
167
+ });
168
+ this.ws.on('message', (data) => {
169
+ this.handleMessage(data.toString());
170
+ });
171
+ this.ws.on('close', () => {
172
+ this.clearTimers();
173
+ this.events.onDisconnected?.();
174
+ if (this.running) {
175
+ this.scheduleReconnect();
176
+ }
177
+ });
178
+ this.ws.on('error', (err) => {
179
+ this.events.onError?.(err);
180
+ });
181
+ }
182
+ handleMessage(raw) {
183
+ let envelope;
184
+ try {
185
+ envelope = MessageEnvelopeSchema.parse(JSON.parse(raw));
186
+ }
187
+ catch {
188
+ return; // Invalid message, ignore
189
+ }
190
+ // Verify hub signature if we have a CA cert and the message is signed
191
+ if (this.caCertPem && envelope.signature !== '') {
192
+ const valid = verifyPayload(envelope.payload, envelope.signature, this.caCertPem);
193
+ if (!valid) {
194
+ this.events.onError?.(new Error(`Signature verification failed for ${envelope.type}`));
195
+ return;
196
+ }
197
+ }
198
+ switch (envelope.type) {
199
+ case 'hub.ack':
200
+ this.handleAck(envelope);
201
+ break;
202
+ case 'probe.request':
203
+ this.handleProbeRequest(envelope);
204
+ break;
205
+ default:
206
+ break;
207
+ }
208
+ }
209
+ handleAck(envelope) {
210
+ const payload = envelope.payload;
211
+ if (payload.agentId) {
212
+ this.agentId = payload.agentId;
213
+ this.events.onRegistered?.(this.agentId);
214
+ }
215
+ this.events.onConnected?.(this.agentId ?? '');
216
+ }
217
+ async handleProbeRequest(envelope) {
218
+ if (!this.agentId)
219
+ return;
220
+ let request;
221
+ try {
222
+ request = ProbeRequestSchema.parse(envelope.payload);
223
+ }
224
+ catch {
225
+ this.sendError(envelope.id, 'Invalid probe request payload');
226
+ return;
227
+ }
228
+ const response = await this.executor.execute(request);
229
+ this.auditLog.log(request.probe, response.status, response.durationMs);
230
+ this.events.onProbeCompleted?.(request.probe, response.status, response.durationMs);
231
+ this.send({
232
+ id: crypto.randomUUID(),
233
+ type: response.status === 'success' ? 'probe.response' : 'probe.error',
234
+ timestamp: new Date().toISOString(),
235
+ agentId: this.agentId,
236
+ signature: '',
237
+ payload: response,
238
+ });
239
+ }
240
+ /** Get the agent-side audit log (for testing/inspection) */
241
+ getAuditLog() {
242
+ return this.auditLog;
243
+ }
244
+ sendRegister() {
245
+ this.send({
246
+ id: crypto.randomUUID(),
247
+ type: 'agent.register',
248
+ timestamp: new Date().toISOString(),
249
+ signature: '',
250
+ payload: {
251
+ name: this.config.agentName,
252
+ os: `${process.platform} ${process.arch}`,
253
+ agentVersion: '0.1.0',
254
+ packs: this.executor.getLoadedPacks(),
255
+ attestation: generateAttestation(this.config, this.executor),
256
+ },
257
+ });
258
+ }
259
+ startHeartbeat() {
260
+ this.heartbeatTimer = setInterval(() => {
261
+ if (!this.agentId)
262
+ return;
263
+ this.send({
264
+ id: crypto.randomUUID(),
265
+ type: 'agent.heartbeat',
266
+ timestamp: new Date().toISOString(),
267
+ agentId: this.agentId,
268
+ signature: '',
269
+ payload: {},
270
+ });
271
+ }, HEARTBEAT_INTERVAL_MS);
272
+ }
273
+ sendError(requestId, message) {
274
+ if (!this.agentId)
275
+ return;
276
+ this.send({
277
+ id: crypto.randomUUID(),
278
+ type: 'probe.error',
279
+ timestamp: new Date().toISOString(),
280
+ agentId: this.agentId,
281
+ signature: '',
282
+ payload: {
283
+ probe: 'unknown',
284
+ status: 'error',
285
+ data: { error: message },
286
+ durationMs: 0,
287
+ metadata: {
288
+ agentVersion: '0.1.0',
289
+ packName: 'unknown',
290
+ packVersion: '0.0.0',
291
+ capabilityLevel: 'observe',
292
+ },
293
+ },
294
+ });
295
+ }
296
+ send(envelope) {
297
+ if (this.ws?.readyState === WebSocket.OPEN) {
298
+ // Sign the payload if we have a private key
299
+ if (this.privateKeyPem && envelope.signature === '') {
300
+ envelope.signature = signPayload(envelope.payload, this.privateKeyPem);
301
+ }
302
+ this.ws.send(JSON.stringify(envelope));
303
+ }
304
+ }
305
+ scheduleReconnect() {
306
+ const delay = Math.min(MIN_RECONNECT_MS * 2 ** this.reconnectAttempts, MAX_RECONNECT_MS);
307
+ this.reconnectAttempts++;
308
+ this.reconnectTimer = setTimeout(() => {
309
+ if (this.running) {
310
+ this.connect();
311
+ }
312
+ }, delay);
313
+ }
314
+ clearTimers() {
315
+ if (this.heartbeatTimer) {
316
+ clearInterval(this.heartbeatTimer);
317
+ this.heartbeatTimer = null;
318
+ }
319
+ if (this.reconnectTimer) {
320
+ clearTimeout(this.reconnectTimer);
321
+ this.reconnectTimer = null;
322
+ }
323
+ }
324
+ }
325
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/runtime/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=connection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.test.d.ts","sourceRoot":"","sources":["../../src/runtime/connection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,221 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { AgentConnection, enrollWithHub } from './connection.js';
3
+ import { ProbeExecutor } from './executor.js';
4
+ // Mock WebSocket
5
+ const mockWsInstances = [];
6
+ vi.mock('ws', () => {
7
+ const OPEN = 1;
8
+ const CLOSED = 3;
9
+ class MockWebSocket {
10
+ url;
11
+ readyState;
12
+ send = vi.fn();
13
+ close = vi.fn();
14
+ handlers = {};
15
+ constructor(url, _opts) {
16
+ this.url = url;
17
+ this.readyState = OPEN;
18
+ mockWsInstances.push({
19
+ url,
20
+ handlers: this.handlers,
21
+ send: this.send,
22
+ close: this.close,
23
+ readyState: this.readyState,
24
+ });
25
+ }
26
+ on(event, handler) {
27
+ this.handlers[event] = handler;
28
+ }
29
+ // Helper: simulate receiving events from tests
30
+ _emit(event, ...args) {
31
+ this.handlers[event]?.(...args);
32
+ }
33
+ }
34
+ // Attach static constants
35
+ MockWebSocket.OPEN = OPEN;
36
+ MockWebSocket.CLOSED = CLOSED;
37
+ return { default: MockWebSocket, WebSocket: MockWebSocket };
38
+ });
39
+ function createConfig() {
40
+ return {
41
+ hubUrl: 'http://localhost:3000',
42
+ apiKey: 'test-key',
43
+ agentName: 'test-agent',
44
+ };
45
+ }
46
+ function createExecutor() {
47
+ return new ProbeExecutor(new Map());
48
+ }
49
+ describe('AgentConnection', () => {
50
+ beforeEach(() => {
51
+ mockWsInstances.length = 0;
52
+ vi.useFakeTimers();
53
+ });
54
+ afterEach(() => {
55
+ vi.useRealTimers();
56
+ });
57
+ it('connects to the correct WebSocket URL', () => {
58
+ const conn = new AgentConnection(createConfig(), createExecutor());
59
+ conn.start();
60
+ expect(mockWsInstances).toHaveLength(1);
61
+ expect(mockWsInstances[0]?.url).toBe('ws://localhost:3000/ws/agent');
62
+ conn.stop();
63
+ });
64
+ it('converts https hub URL to wss', () => {
65
+ const config = createConfig();
66
+ config.hubUrl = 'https://hub.example.com';
67
+ const conn = new AgentConnection(config, createExecutor());
68
+ conn.start();
69
+ expect(mockWsInstances[0]?.url).toBe('wss://hub.example.com/ws/agent');
70
+ conn.stop();
71
+ });
72
+ it('sends register message on open', () => {
73
+ const conn = new AgentConnection(createConfig(), createExecutor());
74
+ conn.start();
75
+ // Simulate WebSocket open
76
+ const ws = mockWsInstances[0];
77
+ ws?.handlers.open?.();
78
+ expect(ws?.send).toHaveBeenCalledOnce();
79
+ const sent = JSON.parse(ws?.send.mock.calls[0]?.[0]);
80
+ expect(sent.type).toBe('agent.register');
81
+ expect(sent.payload.name).toBe('test-agent');
82
+ conn.stop();
83
+ });
84
+ it('stores agentId from hub.ack', () => {
85
+ const onRegistered = vi.fn();
86
+ const conn = new AgentConnection(createConfig(), createExecutor(), { onRegistered });
87
+ conn.start();
88
+ const ws = mockWsInstances[0];
89
+ ws?.handlers.open?.();
90
+ // Simulate hub.ack
91
+ ws?.handlers.message?.(JSON.stringify({
92
+ id: '00000000-0000-0000-0000-000000000001',
93
+ type: 'hub.ack',
94
+ timestamp: new Date().toISOString(),
95
+ agentId: 'assigned-id',
96
+ signature: '',
97
+ payload: { agentId: 'assigned-id' },
98
+ }));
99
+ expect(onRegistered).toHaveBeenCalledWith('assigned-id');
100
+ expect(conn.getAgentId()).toBe('assigned-id');
101
+ conn.stop();
102
+ });
103
+ it('sends heartbeats on interval', () => {
104
+ const conn = new AgentConnection(createConfig(), createExecutor());
105
+ conn.start();
106
+ const ws = mockWsInstances[0];
107
+ ws?.handlers.open?.();
108
+ // Simulate hub.ack to set agentId
109
+ ws?.handlers.message?.(JSON.stringify({
110
+ id: '00000000-0000-0000-0000-000000000001',
111
+ type: 'hub.ack',
112
+ timestamp: new Date().toISOString(),
113
+ agentId: 'agent-1',
114
+ signature: '',
115
+ payload: { agentId: 'agent-1' },
116
+ }));
117
+ // Register sends one message, ack handler sends another (onConnected)
118
+ const callsBeforeHeartbeat = ws?.send.mock.calls.length ?? 0;
119
+ // Advance time by 30 seconds (HEARTBEAT_INTERVAL_MS)
120
+ vi.advanceTimersByTime(30_000);
121
+ const heartbeatCalls = (ws?.send.mock.calls.length ?? 0) - callsBeforeHeartbeat;
122
+ expect(heartbeatCalls).toBe(1);
123
+ const lastCall = ws?.send.mock.calls.at(-1)?.[0];
124
+ const msg = JSON.parse(lastCall);
125
+ expect(msg.type).toBe('agent.heartbeat');
126
+ expect(msg.agentId).toBe('agent-1');
127
+ conn.stop();
128
+ });
129
+ it('schedules reconnect with exponential backoff on close', () => {
130
+ const onDisconnected = vi.fn();
131
+ const conn = new AgentConnection(createConfig(), createExecutor(), { onDisconnected });
132
+ conn.start();
133
+ const ws = mockWsInstances[0];
134
+ // First disconnect
135
+ ws?.handlers.close?.();
136
+ expect(onDisconnected).toHaveBeenCalledOnce();
137
+ expect(mockWsInstances).toHaveLength(1); // Not reconnected yet
138
+ // Advance past first reconnect delay (1s)
139
+ vi.advanceTimersByTime(1_000);
140
+ expect(mockWsInstances).toHaveLength(2); // Reconnected
141
+ // Second disconnect
142
+ mockWsInstances[1]?.handlers.close?.();
143
+ // Advance 1s — should NOT reconnect yet (backoff is 2s)
144
+ vi.advanceTimersByTime(1_000);
145
+ expect(mockWsInstances).toHaveLength(2);
146
+ // Advance another 1s (total 2s) — should reconnect
147
+ vi.advanceTimersByTime(1_000);
148
+ expect(mockWsInstances).toHaveLength(3);
149
+ conn.stop();
150
+ });
151
+ it('does not reconnect after stop()', () => {
152
+ const conn = new AgentConnection(createConfig(), createExecutor());
153
+ conn.start();
154
+ conn.stop();
155
+ const ws = mockWsInstances[0];
156
+ ws?.handlers.close?.();
157
+ vi.advanceTimersByTime(60_000);
158
+ expect(mockWsInstances).toHaveLength(1); // No reconnect
159
+ });
160
+ });
161
+ describe('enrollWithHub', () => {
162
+ beforeEach(() => {
163
+ mockWsInstances.length = 0;
164
+ vi.useFakeTimers();
165
+ });
166
+ afterEach(() => {
167
+ vi.useRealTimers();
168
+ });
169
+ it('connects to correct URL and sends register', () => {
170
+ const promise = enrollWithHub(createConfig(), createExecutor());
171
+ expect(mockWsInstances).toHaveLength(1);
172
+ expect(mockWsInstances[0]?.url).toBe('ws://localhost:3000/ws/agent');
173
+ const ws = mockWsInstances[0];
174
+ ws?.handlers.open?.();
175
+ expect(ws?.send).toHaveBeenCalledOnce();
176
+ const sent = JSON.parse(ws?.send.mock.calls[0]?.[0]);
177
+ expect(sent.type).toBe('agent.register');
178
+ expect(sent.payload.name).toBe('test-agent');
179
+ // Send ack to resolve and avoid dangling promise
180
+ ws?.handlers.message?.(JSON.stringify({
181
+ id: '00000000-0000-0000-0000-000000000001',
182
+ type: 'hub.ack',
183
+ timestamp: new Date().toISOString(),
184
+ agentId: 'enrolled-id',
185
+ signature: '',
186
+ payload: { agentId: 'enrolled-id' },
187
+ }));
188
+ return promise;
189
+ });
190
+ it('returns agentId from hub.ack', async () => {
191
+ const promise = enrollWithHub(createConfig(), createExecutor());
192
+ const ws = mockWsInstances[0];
193
+ ws?.handlers.open?.();
194
+ ws?.handlers.message?.(JSON.stringify({
195
+ id: '00000000-0000-0000-0000-000000000001',
196
+ type: 'hub.ack',
197
+ timestamp: new Date().toISOString(),
198
+ agentId: 'enrolled-id',
199
+ signature: '',
200
+ payload: { agentId: 'enrolled-id' },
201
+ }));
202
+ const result = await promise;
203
+ expect(result.agentId).toBe('enrolled-id');
204
+ expect(result.certIssued).toBe(false);
205
+ });
206
+ it('rejects on timeout when no ack received', async () => {
207
+ const promise = enrollWithHub(createConfig(), createExecutor());
208
+ const ws = mockWsInstances[0];
209
+ ws?.handlers.open?.();
210
+ // Advance past the 10s timeout
211
+ vi.advanceTimersByTime(10_000);
212
+ await expect(promise).rejects.toThrow('Enrollment timed out');
213
+ });
214
+ it('rejects on WebSocket error', async () => {
215
+ const promise = enrollWithHub(createConfig(), createExecutor());
216
+ const ws = mockWsInstances[0];
217
+ ws?.handlers.error?.(new Error('Connection refused'));
218
+ await expect(promise).rejects.toThrow('Connection refused');
219
+ });
220
+ });
221
+ //# sourceMappingURL=connection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../../src/runtime/connection.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type ExecFn, type Pack } from '@sonde/packs';
2
+ import type { ProbeRequest, ProbeResponse } from '@sonde/shared';
3
+ import { type ScrubPattern } from './scrubber.js';
4
+ export declare class ProbeExecutor {
5
+ private packs;
6
+ private exec;
7
+ private scrubPatterns;
8
+ constructor(packs?: ReadonlyMap<string, Pack>, exec?: ExecFn, scrubPatterns?: ScrubPattern[]);
9
+ /** Get list of loaded packs with status info */
10
+ getLoadedPacks(): Array<{
11
+ name: string;
12
+ version: string;
13
+ status: string;
14
+ }>;
15
+ /** Get a pack by name */
16
+ getPackByName(name: string): Pack | undefined;
17
+ /** Execute a probe request and return a probe response */
18
+ execute(request: ProbeRequest): Promise<ProbeResponse>;
19
+ private errorResponse;
20
+ }
21
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/runtime/executor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAgB,MAAM,cAAc,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,KAAK,YAAY,EAA4B,MAAM,eAAe,CAAC;AAe5E,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAiB;gBAE1B,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,YAAY,EAAE;IAM5F,gDAAgD;IAChD,cAAc,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ1E,yBAAyB;IACzB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAI7C,0DAA0D;IACpD,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA0C5D,OAAO,CAAC,aAAa;CAmBtB"}