@openclaw-cloud/agent-controller 0.1.8 → 0.2.1

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 (42) hide show
  1. package/CLAUDE.md +9 -8
  2. package/__tests__/api.test.ts +60 -0
  3. package/__tests__/board-handler.test.ts +2 -0
  4. package/__tests__/connection.test.ts +25 -4
  5. package/__tests__/heartbeat.test.ts +22 -29
  6. package/bin/agent-controller.js +6 -0
  7. package/dist/api.d.ts +2 -0
  8. package/dist/api.js +12 -0
  9. package/dist/api.js.map +1 -1
  10. package/dist/commands/install.d.ts +1 -0
  11. package/dist/commands/install.js +45 -0
  12. package/dist/commands/install.js.map +1 -0
  13. package/dist/commands/uninstall.d.ts +1 -0
  14. package/dist/commands/uninstall.js +22 -0
  15. package/dist/commands/uninstall.js.map +1 -0
  16. package/dist/connection.d.ts +2 -0
  17. package/dist/connection.js +3 -3
  18. package/dist/connection.js.map +1 -1
  19. package/dist/heartbeat.d.ts +2 -2
  20. package/dist/heartbeat.js +4 -29
  21. package/dist/heartbeat.js.map +1 -1
  22. package/dist/index.js +28 -41
  23. package/dist/index.js.map +1 -1
  24. package/dist/platform/linux.d.ts +8 -0
  25. package/dist/platform/linux.js +96 -0
  26. package/dist/platform/linux.js.map +1 -0
  27. package/dist/platform/macos.d.ts +8 -0
  28. package/dist/platform/macos.js +109 -0
  29. package/dist/platform/macos.js.map +1 -0
  30. package/dist/platform/windows.d.ts +8 -0
  31. package/dist/platform/windows.js +77 -0
  32. package/dist/platform/windows.js.map +1 -0
  33. package/package.json +1 -1
  34. package/src/api.ts +14 -0
  35. package/src/commands/install.ts +50 -0
  36. package/src/commands/uninstall.ts +19 -0
  37. package/src/connection.ts +5 -3
  38. package/src/heartbeat.ts +6 -30
  39. package/src/index.ts +29 -42
  40. package/src/platform/linux.ts +108 -0
  41. package/src/platform/macos.ts +122 -0
  42. package/src/platform/windows.ts +92 -0
package/CLAUDE.md CHANGED
@@ -91,7 +91,7 @@ src/
91
91
 
92
92
  ### Command dispatch flow
93
93
  ```
94
- Centrifugo WS message → connection.ts (handler map) → handlers/<type>.ts → AgentResponse → publish back
94
+ Centrifugo WS message → connection.ts (handler map) → handlers/<type>.ts → AgentResponse → POST /api/internal/agent-response
95
95
  ```
96
96
 
97
97
  Handler map in `connection.ts`:
@@ -132,13 +132,16 @@ Agent-controller is a Node.js process that runs inside every agent container (K8
132
132
  ### Communication Flow
133
133
  ```
134
134
  Backend → Centrifugo WS (port 8000) → agent-controller → local agent process
135
- agent-controller → Centrifugo HTTP API (port 9000) Backend (heartbeat processing)
135
+ agent-controller → Backend HTTP API → /api/internal/agent-response (command responses)
136
+ agent-controller → Backend HTTP API → /api/internal/agent-heartbeat (heartbeat)
136
137
  ```
137
138
 
139
+ Centrifugo WS is **read-only** from agent-controller's perspective — all outbound traffic goes through the backend HTTP API, not directly to Centrifugo.
140
+
138
141
  ### Key Components
139
- - **WebSocket client** — Connects to Centrifugo, subscribes to agent channel
140
- - **Heartbeat publisher** — Sends periodic heartbeats via Centrifugo HTTP API (server-side publish)
141
- - **Command handlers** — Processes commands from backend (backup, reconfigure, etc.)
142
+ - **WebSocket client** — Connects to Centrifugo, subscribes to agent channel (read-only)
143
+ - **Heartbeat publisher** — Sends periodic heartbeats via `POST /api/internal/agent-heartbeat`
144
+ - **Command handlers** — Processes commands from backend, sends responses via `POST /api/internal/agent-response`
142
145
  - **Board handler** — Kanban board integration (claim cards, move cards, report status)
143
146
  - **JWT auth** — Fetches JWT from backend's `/api/internal/centrifugo-token` endpoint, auto-refreshes before expiry (24h TTL)
144
147
 
@@ -146,9 +149,7 @@ agent-controller → Centrifugo HTTP API (port 9000) → Backend (heartbeat proc
146
149
  - `AGENT_ID` — UUID of this agent
147
150
  - `AGENT_TOKEN` — Internal auth token
148
151
  - `CENTRIFUGO_URL` — WebSocket URL (port 8000, converted from http→ws)
149
- - `CENTRIFUGO_INTERNAL_URL` — HTTP API URL (port 9000) for server-side publish
150
- - `CENTRIFUGO_API_KEY` — API key for HTTP API auth
151
- - `API_BASE_URL` — Backend API URL for JWT fetch
152
+ - `API_BASE_URL` — Backend API URL (JWT fetch, agent responses, heartbeat)
152
153
 
153
154
  ### Deployment
154
155
 
@@ -121,3 +121,63 @@ describe('createAgentApi – post()', () => {
121
121
  await expect(api.post('/endpoint')).rejects.toThrow('timeout');
122
122
  });
123
123
  });
124
+
125
+ describe('createAgentApi – publishResponse()', () => {
126
+ it('POSTs to /api/internal/agent-response with agentId and data', async () => {
127
+ const api = createAgentApi('http://backend', 'tok');
128
+ mockFetch.mockResolvedValue(makeOkResponse(null));
129
+
130
+ await api.publishResponse('agent-1', { id: 'cmd-1', type: 'exec', success: true });
131
+
132
+ const [url, init] = mockFetch.mock.calls[0];
133
+ expect(url).toBe('http://backend/api/internal/agent-response');
134
+ expect(init.method).toBe('POST');
135
+ expect(JSON.parse(init.body)).toEqual({
136
+ agentId: 'agent-1',
137
+ data: { id: 'cmd-1', type: 'exec', success: true },
138
+ });
139
+ });
140
+
141
+ it('throws when response is not ok', async () => {
142
+ const api = createAgentApi('http://backend', 'tok');
143
+ mockFetch.mockResolvedValue(makeErrorResponse(503));
144
+
145
+ await expect(api.publishResponse('agent-1', {})).rejects.toThrow('HTTP 503');
146
+ });
147
+
148
+ it('propagates network errors', async () => {
149
+ const api = createAgentApi('http://backend', 'tok');
150
+ mockFetch.mockRejectedValue(new Error('ECONNREFUSED'));
151
+
152
+ await expect(api.publishResponse('agent-1', {})).rejects.toThrow('ECONNREFUSED');
153
+ });
154
+ });
155
+
156
+ describe('createAgentApi – publishHeartbeat()', () => {
157
+ it('POSTs to /api/internal/agent-heartbeat with agentId and payload', async () => {
158
+ const api = createAgentApi('http://backend', 'tok');
159
+ mockFetch.mockResolvedValue(makeOkResponse(null));
160
+
161
+ const payload = { type: 'heartbeat', agentId: 'agent-1', ts: 123, metrics: {} };
162
+ await api.publishHeartbeat('agent-1', payload);
163
+
164
+ const [url, init] = mockFetch.mock.calls[0];
165
+ expect(url).toBe('http://backend/api/internal/agent-heartbeat');
166
+ expect(init.method).toBe('POST');
167
+ expect(JSON.parse(init.body)).toEqual({ agentId: 'agent-1', payload });
168
+ });
169
+
170
+ it('throws when response is not ok', async () => {
171
+ const api = createAgentApi('http://backend', 'tok');
172
+ mockFetch.mockResolvedValue(makeErrorResponse(500));
173
+
174
+ await expect(api.publishHeartbeat('agent-1', {})).rejects.toThrow('HTTP 500');
175
+ });
176
+
177
+ it('propagates network errors', async () => {
178
+ const api = createAgentApi('http://backend', 'tok');
179
+ mockFetch.mockRejectedValue(new Error('timeout'));
180
+
181
+ await expect(api.publishHeartbeat('agent-1', {})).rejects.toThrow('timeout');
182
+ });
183
+ });
@@ -10,6 +10,8 @@ function mockApi(overrides: Partial<AgentApi> = {}): AgentApi {
10
10
  return {
11
11
  get: jest.fn(),
12
12
  post: jest.fn(),
13
+ publishResponse: jest.fn().mockResolvedValue(undefined),
14
+ publishHeartbeat: jest.fn().mockResolvedValue(undefined),
13
15
  ...overrides,
14
16
  };
15
17
  }
@@ -1,4 +1,5 @@
1
1
  import { Centrifuge } from 'centrifuge';
2
+ import type { AgentApi } from '../src/api';
2
3
 
3
4
  jest.mock('centrifuge');
4
5
  jest.mock('ws', () => jest.fn());
@@ -34,6 +35,15 @@ function createMockClient(mockSubs: ReturnType<typeof createMockSubscription>[])
34
35
  };
35
36
  }
36
37
 
38
+ function makeApi(): AgentApi & { publishResponse: jest.Mock } {
39
+ return {
40
+ get: jest.fn(),
41
+ post: jest.fn(),
42
+ publishResponse: jest.fn().mockResolvedValue(undefined),
43
+ publishHeartbeat: jest.fn().mockResolvedValue(undefined),
44
+ } as unknown as AgentApi & { publishResponse: jest.Mock };
45
+ }
46
+
37
47
  function mockFetchOk(token = JWT) {
38
48
  global.fetch = jest.fn().mockResolvedValue({
39
49
  ok: true,
@@ -59,6 +69,7 @@ describe('createConnection', () => {
59
69
  token: AGENT_TOKEN,
60
70
  agentId: AGENT_ID,
61
71
  backendUrl: BACKEND_URL,
72
+ api: makeApi(),
62
73
  });
63
74
 
64
75
  expect(MockCentrifuge).toHaveBeenCalledWith(
@@ -91,6 +102,7 @@ describe('createConnection', () => {
91
102
  token: AGENT_TOKEN,
92
103
  agentId: AGENT_ID,
93
104
  backendUrl: BACKEND_URL,
105
+ api: makeApi(),
94
106
  });
95
107
 
96
108
  expect(capturedGetToken).toBeDefined();
@@ -135,6 +147,7 @@ describe('createConnection', () => {
135
147
  token: AGENT_TOKEN,
136
148
  agentId: AGENT_ID,
137
149
  backendUrl: BACKEND_URL,
150
+ api: makeApi(),
138
151
  });
139
152
 
140
153
  const result = await capturedGetToken!();
@@ -167,6 +180,7 @@ describe('createConnection', () => {
167
180
  token: AGENT_TOKEN,
168
181
  agentId: AGENT_ID,
169
182
  backendUrl: BACKEND_URL,
183
+ api: makeApi(),
170
184
  });
171
185
 
172
186
  await expect(capturedGetToken!()).rejects.toThrow('network down');
@@ -197,6 +211,7 @@ describe('createConnection', () => {
197
211
  token: AGENT_TOKEN,
198
212
  agentId: AGENT_ID,
199
213
  backendUrl: BACKEND_URL,
214
+ api: makeApi(),
200
215
  });
201
216
 
202
217
  await expect(capturedGetToken!()).rejects.toThrow('HTTP 401');
@@ -205,7 +220,7 @@ describe('createConnection', () => {
205
220
  consoleSpy.mockRestore();
206
221
  });
207
222
 
208
- it('routes exec command to handler', async () => {
223
+ it('routes exec command to handler and publishes via api.publishResponse', async () => {
209
224
  const commandSub = createMockSubscription(`agent:${AGENT_ID}`);
210
225
  const mockClient = createMockClient([commandSub]);
211
226
  MockCentrifuge.mockImplementation(() => mockClient as any);
@@ -216,12 +231,14 @@ describe('createConnection', () => {
216
231
  }),
217
232
  }));
218
233
 
234
+ const api = makeApi();
219
235
  const { createConnection } = await import('../src/connection');
220
236
  createConnection({
221
237
  url: 'ws://localhost:8000/connection/websocket',
222
238
  token: AGENT_TOKEN,
223
239
  agentId: AGENT_ID,
224
240
  backendUrl: BACKEND_URL,
241
+ api,
225
242
  });
226
243
 
227
244
  // Simulate a publication on the command channel
@@ -233,9 +250,10 @@ describe('createConnection', () => {
233
250
  channel: `agent:${AGENT_ID}`,
234
251
  });
235
252
 
236
- // Should have published a response to the agent channel
237
- expect(mockClient.publish).toHaveBeenCalledWith(
238
- `agent:${AGENT_ID}`,
253
+ // Should have published a response via api, not client.publish
254
+ expect(mockClient.publish).not.toHaveBeenCalled();
255
+ expect(api.publishResponse).toHaveBeenCalledWith(
256
+ AGENT_ID,
239
257
  expect.objectContaining({ id: 'cmd-1', type: 'exec' })
240
258
  );
241
259
  });
@@ -247,12 +265,14 @@ describe('createConnection', () => {
247
265
 
248
266
  const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
249
267
 
268
+ const api = makeApi();
250
269
  const { createConnection } = await import('../src/connection');
251
270
  createConnection({
252
271
  url: 'ws://localhost:8000/connection/websocket',
253
272
  token: AGENT_TOKEN,
254
273
  agentId: AGENT_ID,
255
274
  backendUrl: BACKEND_URL,
275
+ api,
256
276
  });
257
277
 
258
278
  const publicationHandler = commandSub._handlers['publication'];
@@ -263,6 +283,7 @@ describe('createConnection', () => {
263
283
 
264
284
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Unknown command type'));
265
285
  expect(mockClient.publish).not.toHaveBeenCalled();
286
+ expect(api.publishResponse).not.toHaveBeenCalled();
266
287
  consoleSpy.mockRestore();
267
288
  });
268
289
  });
@@ -1,6 +1,7 @@
1
1
  import os from 'node:os';
2
2
 
3
3
  import { getMetrics, startHeartbeat } from '../src/heartbeat';
4
+ import type { AgentApi } from '../src/api';
4
5
 
5
6
  describe('getMetrics', () => {
6
7
  it('returns cpu, mem, uptime', () => {
@@ -18,60 +19,52 @@ describe('getMetrics', () => {
18
19
  });
19
20
  });
20
21
 
21
- describe('startHeartbeat', () => {
22
- let fetchSpy: jest.SpyInstance;
22
+ function makeApi(publishHeartbeat = jest.fn().mockResolvedValue(undefined)): AgentApi {
23
+ return {
24
+ get: jest.fn(),
25
+ post: jest.fn(),
26
+ publishResponse: jest.fn(),
27
+ publishHeartbeat,
28
+ } as unknown as AgentApi;
29
+ }
23
30
 
31
+ describe('startHeartbeat', () => {
24
32
  beforeEach(() => {
25
33
  jest.useFakeTimers();
26
- fetchSpy = jest.spyOn(globalThis, 'fetch').mockResolvedValue(
27
- new Response('{}', { status: 200 }),
28
- );
29
34
  });
30
35
 
31
36
  afterEach(() => {
32
37
  jest.useRealTimers();
33
- fetchSpy.mockRestore();
34
38
  });
35
39
 
36
- const opts = {
37
- centrifugoInternalUrl: 'http://centrifugo-internal:9000',
38
- centrifugoApiKey: 'test-key',
39
- agentId: 'agent-42',
40
- };
41
-
42
40
  it('publishes heartbeat immediately and at intervals', () => {
43
- const timer = startHeartbeat(opts);
41
+ const publishHeartbeat = jest.fn().mockResolvedValue(undefined);
42
+ const api = makeApi(publishHeartbeat);
43
+
44
+ const timer = startHeartbeat({ api, agentId: 'agent-42' });
44
45
 
45
46
  // Immediate call
46
- expect(fetchSpy).toHaveBeenCalledTimes(1);
47
- expect(fetchSpy).toHaveBeenCalledWith(
48
- 'http://centrifugo-internal:9000/api/publish',
47
+ expect(publishHeartbeat).toHaveBeenCalledTimes(1);
48
+ expect(publishHeartbeat).toHaveBeenCalledWith(
49
+ 'agent-42',
49
50
  expect.objectContaining({
50
- method: 'POST',
51
- headers: expect.objectContaining({
52
- 'Authorization': 'apikey test-key',
53
- }),
51
+ agentId: 'agent-42',
52
+ type: 'heartbeat',
54
53
  }),
55
54
  );
56
55
 
57
- // Check body contains correct channel and agent data
58
- const body = JSON.parse(fetchSpy.mock.calls[0][1].body);
59
- expect(body.channel).toBe('heartbeat:data');
60
- expect(body.data.agentId).toBe('agent-42');
61
- expect(body.data.type).toBe('heartbeat');
62
-
63
56
  // After 30s
64
57
  jest.advanceTimersByTime(30_000);
65
- expect(fetchSpy).toHaveBeenCalledTimes(2);
58
+ expect(publishHeartbeat).toHaveBeenCalledTimes(2);
66
59
 
67
60
  clearInterval(timer);
68
61
  });
69
62
 
70
63
  it('handles publish errors gracefully', () => {
71
64
  const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
72
- fetchSpy.mockRejectedValue(new Error('network fail'));
65
+ const api = makeApi(jest.fn().mockRejectedValue(new Error('network fail')));
73
66
 
74
- const timer = startHeartbeat(opts);
67
+ const timer = startHeartbeat({ api, agentId: 'agent-42' });
75
68
 
76
69
  // Should not throw
77
70
  clearInterval(timer);
@@ -14,6 +14,12 @@ if (command === '--version' || command === '-v') {
14
14
  } else if (command === 'self-update') {
15
15
  const { selfUpdate } = await import('../dist/commands/self-update.js');
16
16
  await selfUpdate(pkg.version);
17
+ } else if (command === 'install') {
18
+ const { install } = await import('../dist/commands/install.js');
19
+ await install();
20
+ } else if (command === 'uninstall') {
21
+ const { uninstall } = await import('../dist/commands/uninstall.js');
22
+ await uninstall();
17
23
  } else {
18
24
  const { main } = await import('../dist/index.js');
19
25
  main();
package/dist/api.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export interface AgentApi {
2
2
  get(path: string): Promise<unknown>;
3
3
  post(path: string, body?: unknown): Promise<Response>;
4
+ publishResponse(agentId: string, data: unknown): Promise<void>;
5
+ publishHeartbeat(agentId: string, payload: unknown): Promise<void>;
4
6
  }
5
7
  export declare function createAgentApi(backendUrl: string, agentToken: string): AgentApi;
package/dist/api.js CHANGED
@@ -37,6 +37,18 @@ export function createAgentApi(backendUrl, agentToken) {
37
37
  async post(path, body) {
38
38
  return request('POST', path, body);
39
39
  },
40
+ async publishResponse(agentId, data) {
41
+ const res = await request('POST', '/api/internal/agent-response', { agentId, data });
42
+ if (!res.ok) {
43
+ throw new Error(`publishResponse failed: HTTP ${res.status}`);
44
+ }
45
+ },
46
+ async publishHeartbeat(agentId, payload) {
47
+ const res = await request('POST', '/api/internal/agent-heartbeat', { agentId, payload });
48
+ if (!res.ok) {
49
+ throw new Error(`publishHeartbeat failed: HTTP ${res.status}`);
50
+ }
51
+ },
40
52
  };
41
53
  }
42
54
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,OAAO,GAAG,MAAM,CAAC;AAOvB,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,UAAkB;IACnE,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,IAAY,EAAE,IAAc;QACjE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,GAAG,IAAI,EAAE,EAAE;gBAC9C,MAAM;gBACN,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,eAAe,EAAE,UAAU,UAAU,EAAE;iBACxC;gBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACpD,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,IAAY;YACpB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAc;YACrC,OAAO,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,OAAO,GAAG,MAAM,CAAC;AASvB,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,UAAkB;IACnE,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,IAAY,EAAE,IAAc;QACjE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,GAAG,IAAI,EAAE,EAAE;gBAC9C,MAAM;gBACN,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,eAAe,EAAE,UAAU,UAAU,EAAE;iBACxC;gBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACpD,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,IAAY;YACpB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAc;YACrC,OAAO,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,OAAe,EAAE,IAAa;YAClD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,8BAA8B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QACD,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,OAAgB;YACtD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,+BAA+B,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACzF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function install(): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { createInterface } from 'node:readline';
2
+ async function prompt(rl, question) {
3
+ return new Promise((resolve) => {
4
+ rl.question(question, (answer) => {
5
+ resolve(answer.trim());
6
+ });
7
+ });
8
+ }
9
+ export async function install() {
10
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
11
+ console.log('OpenClaw Agent Controller — Installation Wizard');
12
+ console.log('================================================');
13
+ console.log('');
14
+ const centrifugoUrl = await prompt(rl, 'CENTRIFUGO_URL (e.g. ws://your-server:8000): ');
15
+ const agentToken = await prompt(rl, 'AGENT_TOKEN: ');
16
+ const agentId = await prompt(rl, 'AGENT_ID: ');
17
+ const backendInternalUrl = await prompt(rl, 'BACKEND_INTERNAL_URL (e.g. http://your-server:3000): ');
18
+ rl.close();
19
+ if (!centrifugoUrl || !agentToken || !agentId || !backendInternalUrl) {
20
+ console.error('All fields are required. Aborting.');
21
+ process.exit(1);
22
+ }
23
+ const config = { centrifugoUrl, agentToken, agentId, backendInternalUrl };
24
+ const platform = process.platform;
25
+ console.log('');
26
+ console.log(`Detected platform: ${platform}`);
27
+ console.log('');
28
+ if (platform === 'darwin') {
29
+ const { installMacOS } = await import('../platform/macos.js');
30
+ await installMacOS(config);
31
+ }
32
+ else if (platform === 'linux') {
33
+ const { installLinux } = await import('../platform/linux.js');
34
+ await installLinux(config);
35
+ }
36
+ else if (platform === 'win32') {
37
+ const { installWindows } = await import('../platform/windows.js');
38
+ await installWindows(config);
39
+ }
40
+ else {
41
+ console.error(`Unsupported platform: ${platform}`);
42
+ process.exit(1);
43
+ }
44
+ }
45
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,KAAK,UAAU,MAAM,CAAC,EAAsC,EAAE,QAAgB;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7E,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,+CAA+C,CAAC,CAAC;IACxF,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,kBAAkB,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,uDAAuD,CAAC,CAAC;IAErG,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACrE,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAE1E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC9D,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC9D,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QAClE,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function uninstall(): Promise<void>;
@@ -0,0 +1,22 @@
1
+ export async function uninstall() {
2
+ const platform = process.platform;
3
+ console.log(`Uninstalling Agent Controller on platform: ${platform}`);
4
+ console.log('');
5
+ if (platform === 'darwin') {
6
+ const { uninstallMacOS } = await import('../platform/macos.js');
7
+ await uninstallMacOS();
8
+ }
9
+ else if (platform === 'linux') {
10
+ const { uninstallLinux } = await import('../platform/linux.js');
11
+ await uninstallLinux();
12
+ }
13
+ else if (platform === 'win32') {
14
+ const { uninstallWindows } = await import('../platform/windows.js');
15
+ await uninstallWindows();
16
+ }
17
+ else {
18
+ console.error(`Unsupported platform: ${platform}`);
19
+ process.exit(1);
20
+ }
21
+ }
22
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,8CAA8C,QAAQ,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAChE,MAAM,cAAc,EAAE,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAChE,MAAM,cAAc,EAAE,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACpE,MAAM,gBAAgB,EAAE,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1,9 +1,11 @@
1
+ import type { AgentApi } from './api.js';
1
2
  import { Centrifuge, Subscription } from 'centrifuge';
2
3
  export interface ConnectionOptions {
3
4
  url: string;
4
5
  token: string;
5
6
  agentId: string;
6
7
  backendUrl: string;
8
+ api: AgentApi;
7
9
  }
8
10
  export declare function createConnection(opts: ConnectionOptions): {
9
11
  client: Centrifuge;
@@ -92,7 +92,7 @@ export function createConnection(opts) {
92
92
  }
93
93
  // Chat commands — handle before generic dispatch
94
94
  if (command.type === 'chat_list_sessions' || command.type === 'chat_history' || command.type === 'chat_send') {
95
- const publishFn = async (data) => { await client.publish(commandChannel, data); };
95
+ const publishFn = async (data) => { await opts.api.publishResponse(opts.agentId, data); };
96
96
  console.log(`[WS] Handling chat command: type=${command.type} id=${command.id}`);
97
97
  switch (command.type) {
98
98
  case 'chat_list_sessions':
@@ -115,7 +115,7 @@ export function createConnection(opts) {
115
115
  console.log(`[WS] Handling command: type=${command.type} id=${command.id}`);
116
116
  try {
117
117
  const response = await handler(command);
118
- await client.publish(commandChannel, response);
118
+ await opts.api.publishResponse(opts.agentId, response);
119
119
  }
120
120
  catch (err) {
121
121
  const errorResponse = {
@@ -124,7 +124,7 @@ export function createConnection(opts) {
124
124
  success: false,
125
125
  error: err instanceof Error ? err.message : String(err),
126
126
  };
127
- await client.publish(commandChannel, errorResponse);
127
+ await opts.api.publishResponse(opts.agentId, errorResponse);
128
128
  }
129
129
  });
130
130
  client.on('connected', (ctx) => {
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAgB,MAAM,YAAY,CAAC;AACtD,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAUpE,MAAM,QAAQ,GAAkE;IAC9E,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,YAAY;IACpB,eAAe,EAAE,oBAAoB;IACrC,UAAU,EAAE,eAAe;IAC3B,WAAW,EAAE,gBAAgB;IAC7B,mBAAmB,EAAE,wBAAwB;CAC9C,CAAC;AAEF,KAAK,UAAU,oBAAoB,CAAC,UAAkB,EAAE,UAAkB,EAAE,OAAe;IACzF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,gCAAgC,EAAE;YACrE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,UAAU,EAAE;aACxC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;YACjC,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAuB,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IAItD,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,KAAK,IAAqB,EAAE;QAC3C,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3F,yEAAyE;YACzE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpF,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;gBAC1C,OAAO,KAAK,CAAC;YACf,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAClG,MAAM,QAAQ,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,cAAc,GAA4B;QAC9C,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,kBAAkB;QACxB,QAAQ;QACR,iBAAiB,EAAE,IAAI;QACvB,iBAAiB,EAAE,KAAK;KACzB,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAExD,MAAM,cAAc,GAAG,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IAE1D,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACzC,OAAO,CAAC,GAAG,CAAC,4BAA4B,cAAc,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,QAAQ,CAAC,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9F,MAAM,OAAO,GAAG,GAAG,CAAC,IAAoB,CAAC;QACzC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,iDAAiD;QACjD,IAAI,OAAO,CAAC,IAAI,KAAK,oBAAoB,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7G,MAAM,SAAS,GAAG,KAAK,EAAE,IAAa,EAAiB,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClH,OAAO,CAAC,GAAG,CAAC,oCAAoC,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACjF,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACrB,KAAK,oBAAoB;oBACvB,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAChE,MAAM;gBACR,KAAK,cAAc;oBACjB,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC3D,MAAM;gBACR,KAAK,WAAW;oBACd,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACtE,MAAM;YACV,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,aAAa,GAAkB;gBACnC,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5D,QAAQ,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QAC9D,QAAQ,CAAC,YAAY,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE;QAC9B,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QAC5D,QAAQ,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE;QAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,cAAc,eAAe,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC;QACrF,QAAQ,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;QACnC,OAAO,CAAC,GAAG,CAAC,uBAAuB,cAAc,KAAK,GAAG,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QACvF,QAAQ,CAAC,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QAC7B,OAAO,CAAC,KAAK,CAAC,8BAA8B,cAAc,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,0BAA0B,cAAc,KAAK,GAAG,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,SAAS,EAAE,CAAC;IACvB,MAAM,CAAC,OAAO,EAAE,CAAC;IAEjB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
@@ -1,7 +1,7 @@
1
+ import type { AgentApi } from './api.js';
1
2
  import type { BoardState, HeartbeatPayload } from './types.js';
2
3
  export interface HeartbeatOptions {
3
- centrifugoInternalUrl: string;
4
- centrifugoApiKey: string;
4
+ api: AgentApi;
5
5
  agentId: string;
6
6
  getBoardStatus?: () => BoardState;
7
7
  }
package/dist/heartbeat.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import os from 'node:os';
2
2
  import { debugLog } from './debug.js';
3
3
  const HEARTBEAT_INTERVAL = 30_000;
4
- const HEARTBEAT_CHANNEL = 'heartbeat:data';
5
4
  function getMetrics() {
6
5
  const cpus = os.cpus();
7
6
  const cpuUsage = cpus.reduce((acc, cpu) => {
@@ -24,38 +23,14 @@ async function publishHeartbeat(opts) {
24
23
  metrics: getMetrics(),
25
24
  ...(opts.getBoardStatus ? { boardStatus: opts.getBoardStatus() } : {}),
26
25
  };
27
- const controller = new AbortController();
28
- const timeout = setTimeout(() => controller.abort(), 5000);
29
26
  try {
30
27
  debugLog('heartbeat', '→ sending', opts.agentId, JSON.stringify(payload).slice(0, 500));
31
- const res = await fetch(`${opts.centrifugoInternalUrl}/api/publish`, {
32
- method: 'POST',
33
- headers: {
34
- 'Content-Type': 'application/json',
35
- 'Authorization': `apikey ${opts.centrifugoApiKey}`,
36
- },
37
- body: JSON.stringify({ channel: HEARTBEAT_CHANNEL, data: payload }),
38
- signal: controller.signal,
39
- });
40
- if (!res.ok) {
41
- const body = await res.text().catch(() => '');
42
- console.error(`Heartbeat publish failed (HTTP ${res.status}): ${body}`);
43
- debugLog('heartbeat', '← error', res.status, body);
44
- }
45
- else {
46
- debugLog('heartbeat', '← ok', res.status);
47
- }
28
+ await opts.api.publishHeartbeat(opts.agentId, payload);
29
+ debugLog('heartbeat', '← ok');
48
30
  }
49
31
  catch (err) {
50
- if (err.name === 'AbortError') {
51
- console.error('Heartbeat publish timed out');
52
- }
53
- else {
54
- console.error('Heartbeat publish failed:', err instanceof Error ? err.message : err);
55
- }
56
- }
57
- finally {
58
- clearTimeout(timeout);
32
+ console.error('Heartbeat publish failed:', err instanceof Error ? err.message : err);
33
+ debugLog('heartbeat', '← error', err);
59
34
  }
60
35
  }
61
36
  export function startHeartbeat(opts) {
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAQlC,SAAS,UAAU;IACjB,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,OAAO,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;IAC5C,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAEpB,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAE7B,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG;QACrC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG;QAC9D,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE;KACpB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAsB;IACpD,MAAM,OAAO,GAAqB;QAChC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;QACd,OAAO,EAAE,UAAU,EAAE;QACrB,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;IAEF,IAAI,CAAC;QACH,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACxF,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrF,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAsB;IACnD,MAAM,IAAI,GAAG,GAAG,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC;IACP,OAAO,WAAW,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;AAC/C,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}