agent-relay 0.1.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 (143) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +22 -0
  3. package/PROTOCOL.md +319 -0
  4. package/README.md +791 -0
  5. package/dist/cli/index.d.ts +7 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +1591 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/daemon/connection.d.ts +60 -0
  10. package/dist/daemon/connection.d.ts.map +1 -0
  11. package/dist/daemon/connection.js +245 -0
  12. package/dist/daemon/connection.js.map +1 -0
  13. package/dist/daemon/index.d.ts +4 -0
  14. package/dist/daemon/index.d.ts.map +1 -0
  15. package/dist/daemon/index.js +4 -0
  16. package/dist/daemon/index.js.map +1 -0
  17. package/dist/daemon/router.d.ts +72 -0
  18. package/dist/daemon/router.d.ts.map +1 -0
  19. package/dist/daemon/router.js +183 -0
  20. package/dist/daemon/router.js.map +1 -0
  21. package/dist/daemon/server.d.ts +52 -0
  22. package/dist/daemon/server.d.ts.map +1 -0
  23. package/dist/daemon/server.js +186 -0
  24. package/dist/daemon/server.js.map +1 -0
  25. package/dist/dashboard/public/index.html +690 -0
  26. package/dist/dashboard/server.d.ts +2 -0
  27. package/dist/dashboard/server.d.ts.map +1 -0
  28. package/dist/dashboard/server.js +220 -0
  29. package/dist/dashboard/server.js.map +1 -0
  30. package/dist/games/index.d.ts +2 -0
  31. package/dist/games/index.d.ts.map +1 -0
  32. package/dist/games/index.js +2 -0
  33. package/dist/games/index.js.map +1 -0
  34. package/dist/games/tictactoe.d.ts +24 -0
  35. package/dist/games/tictactoe.d.ts.map +1 -0
  36. package/dist/games/tictactoe.js +160 -0
  37. package/dist/games/tictactoe.js.map +1 -0
  38. package/dist/hooks/inbox-check/hook.d.ts +28 -0
  39. package/dist/hooks/inbox-check/hook.d.ts.map +1 -0
  40. package/dist/hooks/inbox-check/hook.js +97 -0
  41. package/dist/hooks/inbox-check/hook.js.map +1 -0
  42. package/dist/hooks/inbox-check/index.d.ts +8 -0
  43. package/dist/hooks/inbox-check/index.d.ts.map +1 -0
  44. package/dist/hooks/inbox-check/index.js +8 -0
  45. package/dist/hooks/inbox-check/index.js.map +1 -0
  46. package/dist/hooks/inbox-check/types.d.ts +31 -0
  47. package/dist/hooks/inbox-check/types.d.ts.map +1 -0
  48. package/dist/hooks/inbox-check/types.js +5 -0
  49. package/dist/hooks/inbox-check/types.js.map +1 -0
  50. package/dist/hooks/inbox-check/utils.d.ts +44 -0
  51. package/dist/hooks/inbox-check/utils.d.ts.map +1 -0
  52. package/dist/hooks/inbox-check/utils.js +107 -0
  53. package/dist/hooks/inbox-check/utils.js.map +1 -0
  54. package/dist/index.d.ts +10 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +10 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/protocol/framing.d.ts +32 -0
  59. package/dist/protocol/framing.d.ts.map +1 -0
  60. package/dist/protocol/framing.js +71 -0
  61. package/dist/protocol/framing.js.map +1 -0
  62. package/dist/protocol/index.d.ts +3 -0
  63. package/dist/protocol/index.d.ts.map +1 -0
  64. package/dist/protocol/index.js +3 -0
  65. package/dist/protocol/index.js.map +1 -0
  66. package/dist/protocol/types.d.ts +104 -0
  67. package/dist/protocol/types.d.ts.map +1 -0
  68. package/dist/protocol/types.js +6 -0
  69. package/dist/protocol/types.js.map +1 -0
  70. package/dist/state/agent-state.d.ts +40 -0
  71. package/dist/state/agent-state.d.ts.map +1 -0
  72. package/dist/state/agent-state.js +120 -0
  73. package/dist/state/agent-state.js.map +1 -0
  74. package/dist/storage/adapter.d.ts +29 -0
  75. package/dist/storage/adapter.d.ts.map +1 -0
  76. package/dist/storage/adapter.js +2 -0
  77. package/dist/storage/adapter.js.map +1 -0
  78. package/dist/storage/sqlite-adapter.d.ts +15 -0
  79. package/dist/storage/sqlite-adapter.d.ts.map +1 -0
  80. package/dist/storage/sqlite-adapter.js +116 -0
  81. package/dist/storage/sqlite-adapter.js.map +1 -0
  82. package/dist/supervisor/inbox.d.ts +38 -0
  83. package/dist/supervisor/inbox.d.ts.map +1 -0
  84. package/dist/supervisor/inbox.js +162 -0
  85. package/dist/supervisor/inbox.js.map +1 -0
  86. package/dist/supervisor/index.d.ts +10 -0
  87. package/dist/supervisor/index.d.ts.map +1 -0
  88. package/dist/supervisor/index.js +10 -0
  89. package/dist/supervisor/index.js.map +1 -0
  90. package/dist/supervisor/spawner.d.ts +54 -0
  91. package/dist/supervisor/spawner.d.ts.map +1 -0
  92. package/dist/supervisor/spawner.js +282 -0
  93. package/dist/supervisor/spawner.js.map +1 -0
  94. package/dist/supervisor/state.d.ts +132 -0
  95. package/dist/supervisor/state.d.ts.map +1 -0
  96. package/dist/supervisor/state.js +465 -0
  97. package/dist/supervisor/state.js.map +1 -0
  98. package/dist/supervisor/supervisor.d.ts +67 -0
  99. package/dist/supervisor/supervisor.d.ts.map +1 -0
  100. package/dist/supervisor/supervisor.js +263 -0
  101. package/dist/supervisor/supervisor.js.map +1 -0
  102. package/dist/supervisor/types.d.ts +139 -0
  103. package/dist/supervisor/types.d.ts.map +1 -0
  104. package/dist/supervisor/types.js +12 -0
  105. package/dist/supervisor/types.js.map +1 -0
  106. package/dist/utils/index.d.ts +2 -0
  107. package/dist/utils/index.d.ts.map +1 -0
  108. package/dist/utils/index.js +2 -0
  109. package/dist/utils/index.js.map +1 -0
  110. package/dist/utils/name-generator.d.ts +17 -0
  111. package/dist/utils/name-generator.d.ts.map +1 -0
  112. package/dist/utils/name-generator.js +52 -0
  113. package/dist/utils/name-generator.js.map +1 -0
  114. package/dist/webhook/spawner.d.ts +79 -0
  115. package/dist/webhook/spawner.d.ts.map +1 -0
  116. package/dist/webhook/spawner.js +288 -0
  117. package/dist/webhook/spawner.js.map +1 -0
  118. package/dist/wrapper/client.d.ts +72 -0
  119. package/dist/wrapper/client.d.ts.map +1 -0
  120. package/dist/wrapper/client.js +306 -0
  121. package/dist/wrapper/client.js.map +1 -0
  122. package/dist/wrapper/inbox.d.ts +37 -0
  123. package/dist/wrapper/inbox.d.ts.map +1 -0
  124. package/dist/wrapper/inbox.js +73 -0
  125. package/dist/wrapper/inbox.js.map +1 -0
  126. package/dist/wrapper/index.d.ts +4 -0
  127. package/dist/wrapper/index.d.ts.map +1 -0
  128. package/dist/wrapper/index.js +7 -0
  129. package/dist/wrapper/index.js.map +1 -0
  130. package/dist/wrapper/parser.d.ts +94 -0
  131. package/dist/wrapper/parser.d.ts.map +1 -0
  132. package/dist/wrapper/parser.js +360 -0
  133. package/dist/wrapper/parser.js.map +1 -0
  134. package/dist/wrapper/pty-wrapper.d.ts +125 -0
  135. package/dist/wrapper/pty-wrapper.d.ts.map +1 -0
  136. package/dist/wrapper/pty-wrapper.js +494 -0
  137. package/dist/wrapper/pty-wrapper.js.map +1 -0
  138. package/dist/wrapper/tmux-wrapper.d.ts +131 -0
  139. package/dist/wrapper/tmux-wrapper.d.ts.map +1 -0
  140. package/dist/wrapper/tmux-wrapper.js +427 -0
  141. package/dist/wrapper/tmux-wrapper.js.map +1 -0
  142. package/install.sh +69 -0
  143. package/package.json +82 -0
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Message router for the agent relay daemon.
3
+ * Handles routing messages between agents, topic subscriptions, and broadcast.
4
+ */
5
+ import { v4 as uuid } from 'uuid';
6
+ import { PROTOCOL_VERSION, } from '../protocol/types.js';
7
+ export class Router {
8
+ storage;
9
+ connections = new Map(); // connectionId -> Connection
10
+ agents = new Map(); // agentName -> Connection
11
+ subscriptions = new Map(); // topic -> Set<agentName>
12
+ constructor(options = {}) {
13
+ this.storage = options.storage;
14
+ }
15
+ /**
16
+ * Register a connection after successful handshake.
17
+ */
18
+ register(connection) {
19
+ this.connections.set(connection.id, connection);
20
+ if (connection.agentName) {
21
+ // Handle existing connection with same name (disconnect old)
22
+ const existing = this.agents.get(connection.agentName);
23
+ if (existing && existing.id !== connection.id) {
24
+ existing.close();
25
+ this.connections.delete(existing.id);
26
+ }
27
+ this.agents.set(connection.agentName, connection);
28
+ }
29
+ }
30
+ /**
31
+ * Unregister a connection.
32
+ */
33
+ unregister(connection) {
34
+ this.connections.delete(connection.id);
35
+ if (connection.agentName) {
36
+ const current = this.agents.get(connection.agentName);
37
+ if (current?.id === connection.id) {
38
+ this.agents.delete(connection.agentName);
39
+ }
40
+ // Remove from all subscriptions
41
+ for (const subscribers of this.subscriptions.values()) {
42
+ subscribers.delete(connection.agentName);
43
+ }
44
+ }
45
+ }
46
+ /**
47
+ * Subscribe an agent to a topic.
48
+ */
49
+ subscribe(agentName, topic) {
50
+ let subscribers = this.subscriptions.get(topic);
51
+ if (!subscribers) {
52
+ subscribers = new Set();
53
+ this.subscriptions.set(topic, subscribers);
54
+ }
55
+ subscribers.add(agentName);
56
+ }
57
+ /**
58
+ * Unsubscribe an agent from a topic.
59
+ */
60
+ unsubscribe(agentName, topic) {
61
+ const subscribers = this.subscriptions.get(topic);
62
+ if (subscribers) {
63
+ subscribers.delete(agentName);
64
+ if (subscribers.size === 0) {
65
+ this.subscriptions.delete(topic);
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Route a SEND message to its destination(s).
71
+ */
72
+ route(from, envelope) {
73
+ const senderName = from.agentName;
74
+ if (!senderName) {
75
+ console.log(`[router] Dropping message - sender has no name`);
76
+ return;
77
+ }
78
+ const to = envelope.to;
79
+ const topic = envelope.topic;
80
+ console.log(`[router] ${senderName} -> ${to}: ${envelope.payload.body?.substring(0, 50)}...`);
81
+ if (to === '*') {
82
+ // Broadcast to all (except sender)
83
+ this.broadcast(senderName, envelope, topic);
84
+ }
85
+ else if (to) {
86
+ // Direct message
87
+ this.sendDirect(senderName, to, envelope);
88
+ }
89
+ }
90
+ /**
91
+ * Send a direct message to a specific agent.
92
+ */
93
+ sendDirect(from, to, envelope) {
94
+ const target = this.agents.get(to);
95
+ if (!target) {
96
+ console.log(`[router] Target "${to}" not found. Available agents: ${Array.from(this.agents.keys()).join(', ')}`);
97
+ return false;
98
+ }
99
+ const deliver = this.createDeliverEnvelope(from, to, envelope, target);
100
+ const sent = target.send(deliver);
101
+ console.log(`[router] Delivered to ${to}: ${sent ? 'success' : 'failed'}`);
102
+ this.persistDeliverEnvelope(deliver);
103
+ return sent;
104
+ }
105
+ /**
106
+ * Broadcast to all agents (optionally filtered by topic subscription).
107
+ */
108
+ broadcast(from, envelope, topic) {
109
+ const recipients = topic
110
+ ? this.subscriptions.get(topic) ?? new Set()
111
+ : new Set(this.agents.keys());
112
+ for (const agentName of recipients) {
113
+ if (agentName === from)
114
+ continue; // Don't send to self
115
+ const target = this.agents.get(agentName);
116
+ if (target) {
117
+ const deliver = this.createDeliverEnvelope(from, agentName, envelope, target);
118
+ target.send(deliver);
119
+ this.persistDeliverEnvelope(deliver);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Create a DELIVER envelope from a SEND.
125
+ */
126
+ createDeliverEnvelope(from, to, original, target) {
127
+ return {
128
+ v: PROTOCOL_VERSION,
129
+ type: 'DELIVER',
130
+ id: uuid(),
131
+ ts: Date.now(),
132
+ from,
133
+ to,
134
+ topic: original.topic,
135
+ payload: original.payload,
136
+ delivery: {
137
+ seq: target.getNextSeq(original.topic ?? 'default', from),
138
+ session_id: target.sessionId,
139
+ },
140
+ };
141
+ }
142
+ /**
143
+ * Persist a delivered message if storage is configured.
144
+ */
145
+ persistDeliverEnvelope(envelope) {
146
+ if (!this.storage)
147
+ return;
148
+ this.storage.saveMessage({
149
+ id: envelope.id,
150
+ ts: envelope.ts,
151
+ from: envelope.from ?? 'unknown',
152
+ to: envelope.to ?? 'unknown',
153
+ topic: envelope.topic,
154
+ kind: envelope.payload.kind,
155
+ body: envelope.payload.body,
156
+ data: envelope.payload.data,
157
+ deliverySeq: envelope.delivery.seq,
158
+ deliverySessionId: envelope.delivery.session_id,
159
+ sessionId: envelope.delivery.session_id,
160
+ }).catch((err) => {
161
+ console.error('[router] Failed to persist message', err);
162
+ });
163
+ }
164
+ /**
165
+ * Get list of connected agent names.
166
+ */
167
+ getAgents() {
168
+ return Array.from(this.agents.keys());
169
+ }
170
+ /**
171
+ * Get connection by agent name.
172
+ */
173
+ getConnection(agentName) {
174
+ return this.agents.get(agentName);
175
+ }
176
+ /**
177
+ * Get number of active connections.
178
+ */
179
+ get connectionCount() {
180
+ return this.connections.size;
181
+ }
182
+ }
183
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/daemon/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Agent Relay Daemon Server
3
+ * Main entry point for the relay daemon.
4
+ */
5
+ import { type ConnectionConfig } from './connection.js';
6
+ import type { StorageAdapter } from '../storage/adapter.js';
7
+ export interface DaemonConfig extends ConnectionConfig {
8
+ socketPath: string;
9
+ pidFilePath: string;
10
+ storagePath?: string;
11
+ storageAdapter?: StorageAdapter;
12
+ }
13
+ export declare const DEFAULT_SOCKET_PATH = "/tmp/agent-relay.sock";
14
+ export declare const DEFAULT_DAEMON_CONFIG: DaemonConfig;
15
+ export declare class Daemon {
16
+ private server;
17
+ private router;
18
+ private config;
19
+ private running;
20
+ private connections;
21
+ private storage?;
22
+ constructor(config?: Partial<DaemonConfig>);
23
+ /**
24
+ * Start the daemon.
25
+ */
26
+ start(): Promise<void>;
27
+ /**
28
+ * Stop the daemon.
29
+ */
30
+ stop(): Promise<void>;
31
+ /**
32
+ * Handle new connection.
33
+ */
34
+ private handleConnection;
35
+ /**
36
+ * Handle incoming message from a connection.
37
+ */
38
+ private handleMessage;
39
+ /**
40
+ * Get list of connected agents.
41
+ */
42
+ getAgents(): string[];
43
+ /**
44
+ * Get connection count.
45
+ */
46
+ get connectionCount(): number;
47
+ /**
48
+ * Check if daemon is running.
49
+ */
50
+ get isRunning(): boolean;
51
+ }
52
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAc,KAAK,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AAIpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AAEF,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,OAAO,CAAC,CAAiB;gBAErB,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAW9C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;CACF"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Agent Relay Daemon Server
3
+ * Main entry point for the relay daemon.
4
+ */
5
+ import net from 'node:net';
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import { Connection, DEFAULT_CONFIG } from './connection.js';
9
+ import { Router } from './router.js';
10
+ import { SqliteStorageAdapter } from '../storage/sqlite-adapter.js';
11
+ export const DEFAULT_SOCKET_PATH = '/tmp/agent-relay.sock';
12
+ export const DEFAULT_DAEMON_CONFIG = {
13
+ ...DEFAULT_CONFIG,
14
+ socketPath: DEFAULT_SOCKET_PATH,
15
+ pidFilePath: `${DEFAULT_SOCKET_PATH}.pid`,
16
+ };
17
+ export class Daemon {
18
+ server;
19
+ router;
20
+ config;
21
+ running = false;
22
+ connections = new Set();
23
+ storage;
24
+ constructor(config = {}) {
25
+ this.config = { ...DEFAULT_DAEMON_CONFIG, ...config };
26
+ if (config.socketPath && !config.pidFilePath) {
27
+ this.config.pidFilePath = `${config.socketPath}.pid`;
28
+ }
29
+ const storagePath = this.config.storagePath ?? path.join(path.dirname(this.config.socketPath), 'agent-relay.sqlite');
30
+ this.storage = this.config.storageAdapter ?? new SqliteStorageAdapter({ dbPath: storagePath });
31
+ this.router = new Router({ storage: this.storage });
32
+ this.server = net.createServer(this.handleConnection.bind(this));
33
+ }
34
+ /**
35
+ * Start the daemon.
36
+ */
37
+ async start() {
38
+ if (this.running)
39
+ return;
40
+ // Initialize storage
41
+ if (this.storage) {
42
+ await this.storage.init();
43
+ }
44
+ // Clean up stale socket (only if it's actually a socket)
45
+ if (fs.existsSync(this.config.socketPath)) {
46
+ const stat = fs.lstatSync(this.config.socketPath);
47
+ if (!stat.isSocket()) {
48
+ throw new Error(`Refusing to unlink non-socket at ${this.config.socketPath}`);
49
+ }
50
+ fs.unlinkSync(this.config.socketPath);
51
+ }
52
+ // Ensure directory exists
53
+ const socketDir = path.dirname(this.config.socketPath);
54
+ if (!fs.existsSync(socketDir)) {
55
+ fs.mkdirSync(socketDir, { recursive: true });
56
+ }
57
+ return new Promise((resolve, reject) => {
58
+ this.server.on('error', reject);
59
+ this.server.listen(this.config.socketPath, () => {
60
+ this.running = true;
61
+ // Set restrictive permissions
62
+ fs.chmodSync(this.config.socketPath, 0o600);
63
+ fs.writeFileSync(this.config.pidFilePath, `${process.pid}\n`, 'utf-8');
64
+ console.log(`[daemon] Listening on ${this.config.socketPath}`);
65
+ resolve();
66
+ });
67
+ });
68
+ }
69
+ /**
70
+ * Stop the daemon.
71
+ */
72
+ async stop() {
73
+ if (!this.running)
74
+ return;
75
+ // Close all active connections
76
+ for (const connection of this.connections) {
77
+ connection.close();
78
+ }
79
+ this.connections.clear();
80
+ return new Promise((resolve) => {
81
+ this.server.close(() => {
82
+ this.running = false;
83
+ // Clean up socket file
84
+ if (fs.existsSync(this.config.socketPath)) {
85
+ fs.unlinkSync(this.config.socketPath);
86
+ }
87
+ // Clean up pid file
88
+ if (fs.existsSync(this.config.pidFilePath)) {
89
+ fs.unlinkSync(this.config.pidFilePath);
90
+ }
91
+ if (this.storage?.close) {
92
+ this.storage.close().catch((err) => {
93
+ console.error('[daemon] Failed to close storage', err);
94
+ });
95
+ }
96
+ console.log('[daemon] Stopped');
97
+ resolve();
98
+ });
99
+ });
100
+ }
101
+ /**
102
+ * Handle new connection.
103
+ */
104
+ handleConnection(socket) {
105
+ console.log('[daemon] New connection');
106
+ const connection = new Connection(socket, this.config);
107
+ this.connections.add(connection);
108
+ connection.onMessage = (envelope) => {
109
+ this.handleMessage(connection, envelope);
110
+ };
111
+ // Register agent when connection becomes active (after successful handshake)
112
+ connection.onActive = () => {
113
+ if (connection.agentName) {
114
+ this.router.register(connection);
115
+ console.log(`[daemon] Agent registered: ${connection.agentName}`);
116
+ }
117
+ };
118
+ connection.onClose = () => {
119
+ console.log(`[daemon] Connection closed: ${connection.agentName ?? connection.id}`);
120
+ this.connections.delete(connection);
121
+ this.router.unregister(connection);
122
+ };
123
+ connection.onError = (error) => {
124
+ console.error(`[daemon] Connection error: ${error.message}`);
125
+ this.connections.delete(connection);
126
+ this.router.unregister(connection);
127
+ };
128
+ }
129
+ /**
130
+ * Handle incoming message from a connection.
131
+ */
132
+ handleMessage(connection, envelope) {
133
+ switch (envelope.type) {
134
+ case 'SEND':
135
+ this.router.route(connection, envelope);
136
+ break;
137
+ case 'SUBSCRIBE':
138
+ if (connection.agentName && envelope.topic) {
139
+ this.router.subscribe(connection.agentName, envelope.topic);
140
+ }
141
+ break;
142
+ case 'UNSUBSCRIBE':
143
+ if (connection.agentName && envelope.topic) {
144
+ this.router.unsubscribe(connection.agentName, envelope.topic);
145
+ }
146
+ break;
147
+ }
148
+ }
149
+ /**
150
+ * Get list of connected agents.
151
+ */
152
+ getAgents() {
153
+ return this.router.getAgents();
154
+ }
155
+ /**
156
+ * Get connection count.
157
+ */
158
+ get connectionCount() {
159
+ return this.router.connectionCount;
160
+ }
161
+ /**
162
+ * Check if daemon is running.
163
+ */
164
+ get isRunning() {
165
+ return this.running;
166
+ }
167
+ }
168
+ // Run as standalone if executed directly
169
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`;
170
+ if (isMainModule) {
171
+ const daemon = new Daemon();
172
+ process.on('SIGINT', async () => {
173
+ console.log('\n[daemon] Shutting down...');
174
+ await daemon.stop();
175
+ process.exit(0);
176
+ });
177
+ process.on('SIGTERM', async () => {
178
+ await daemon.stop();
179
+ process.exit(0);
180
+ });
181
+ daemon.start().catch((err) => {
182
+ console.error('[daemon] Failed to start:', err);
183
+ process.exit(1);
184
+ });
185
+ }
186
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}