@tjamescouch/agentchat 0.22.1 → 0.23.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.
- package/Dockerfile +1 -1
- package/dist/bin/agentchat.d.ts +7 -0
- package/dist/bin/agentchat.d.ts.map +1 -0
- package/dist/bin/agentchat.js +1511 -0
- package/dist/bin/agentchat.js.map +1 -0
- package/dist/lib/allowlist.d.ts +77 -0
- package/dist/lib/allowlist.d.ts.map +1 -0
- package/dist/lib/allowlist.js +151 -0
- package/dist/lib/allowlist.js.map +1 -0
- package/dist/lib/client.d.ts +147 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +704 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/daemon.d.ts +122 -0
- package/dist/lib/daemon.d.ts.map +1 -0
- package/dist/lib/daemon.js +523 -0
- package/dist/lib/daemon.js.map +1 -0
- package/dist/lib/deploy/akash.d.ts +271 -0
- package/dist/lib/deploy/akash.d.ts.map +1 -0
- package/dist/lib/deploy/akash.js +671 -0
- package/dist/lib/deploy/akash.js.map +1 -0
- package/dist/lib/deploy/config.d.ts +62 -0
- package/dist/lib/deploy/config.d.ts.map +1 -0
- package/dist/lib/deploy/config.js +116 -0
- package/dist/lib/deploy/config.js.map +1 -0
- package/dist/lib/deploy/docker.d.ts +37 -0
- package/dist/lib/deploy/docker.d.ts.map +1 -0
- package/dist/lib/deploy/docker.js +122 -0
- package/dist/lib/deploy/docker.js.map +1 -0
- package/dist/lib/deploy/index.d.ts +11 -0
- package/dist/lib/deploy/index.d.ts.map +1 -0
- package/dist/lib/deploy/index.js +11 -0
- package/dist/lib/deploy/index.js.map +1 -0
- package/dist/lib/escrow-hooks.d.ts +199 -0
- package/dist/lib/escrow-hooks.d.ts.map +1 -0
- package/dist/lib/escrow-hooks.js +221 -0
- package/dist/lib/escrow-hooks.js.map +1 -0
- package/dist/lib/identity.d.ts +134 -0
- package/dist/lib/identity.d.ts.map +1 -0
- package/dist/lib/identity.js +334 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/jitter.d.ts +42 -0
- package/dist/lib/jitter.d.ts.map +1 -0
- package/{lib/jitter.ts → dist/lib/jitter.js} +10 -18
- package/dist/lib/jitter.js.map +1 -0
- package/dist/lib/proposals.d.ts +223 -0
- package/dist/lib/proposals.d.ts.map +1 -0
- package/dist/lib/proposals.js +379 -0
- package/dist/lib/proposals.js.map +1 -0
- package/dist/lib/protocol.d.ts +220 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +507 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/receipts.d.ts +134 -0
- package/dist/lib/receipts.d.ts.map +1 -0
- package/dist/lib/receipts.js +270 -0
- package/dist/lib/receipts.js.map +1 -0
- package/dist/lib/reputation.d.ts +250 -0
- package/dist/lib/reputation.d.ts.map +1 -0
- package/dist/lib/reputation.js +586 -0
- package/dist/lib/reputation.js.map +1 -0
- package/dist/lib/security.d.ts +27 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +150 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/server/handlers/admin.d.ts +26 -0
- package/dist/lib/server/handlers/admin.d.ts.map +1 -0
- package/dist/lib/server/handlers/admin.js +76 -0
- package/dist/lib/server/handlers/admin.js.map +1 -0
- package/dist/lib/server/handlers/identity.d.ts +36 -0
- package/dist/lib/server/handlers/identity.d.ts.map +1 -0
- package/dist/lib/server/handlers/identity.js +330 -0
- package/dist/lib/server/handlers/identity.js.map +1 -0
- package/dist/lib/server/handlers/index.d.ts +10 -0
- package/dist/lib/server/handlers/index.d.ts.map +1 -0
- package/dist/lib/server/handlers/index.js +15 -0
- package/dist/lib/server/handlers/index.js.map +1 -0
- package/dist/lib/server/handlers/message.d.ts +47 -0
- package/dist/lib/server/handlers/message.d.ts.map +1 -0
- package/dist/lib/server/handlers/message.js +265 -0
- package/dist/lib/server/handlers/message.js.map +1 -0
- package/dist/lib/server/handlers/presence.d.ts +18 -0
- package/dist/lib/server/handlers/presence.d.ts.map +1 -0
- package/dist/lib/server/handlers/presence.js +35 -0
- package/dist/lib/server/handlers/presence.js.map +1 -0
- package/dist/lib/server/handlers/proposal.d.ts +38 -0
- package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
- package/dist/lib/server/handlers/proposal.js +273 -0
- package/dist/lib/server/handlers/proposal.js.map +1 -0
- package/dist/lib/server/handlers/skills.d.ts +22 -0
- package/dist/lib/server/handlers/skills.d.ts.map +1 -0
- package/dist/lib/server/handlers/skills.js +119 -0
- package/dist/lib/server/handlers/skills.js.map +1 -0
- package/dist/lib/server-directory.d.ts +85 -0
- package/dist/lib/server-directory.d.ts.map +1 -0
- package/dist/lib/server-directory.js +177 -0
- package/dist/lib/server-directory.js.map +1 -0
- package/dist/lib/server.d.ts +162 -0
- package/dist/lib/server.d.ts.map +1 -0
- package/dist/lib/server.js +602 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/lib/types.d.ts +461 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +98 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +22 -13
- package/bin/agentchat.js +0 -1617
- package/bin/agentchat.ts +0 -1812
- package/lib/allowlist.js +0 -162
- package/lib/chat.py +0 -241
- package/lib/client.js +0 -821
- package/lib/client.ts +0 -877
- package/lib/daemon.js +0 -562
- package/lib/daemon.ts +0 -662
- package/lib/deploy/akash.js +0 -811
- package/lib/deploy/config.js +0 -128
- package/lib/deploy/docker.js +0 -132
- package/lib/deploy/index.js +0 -24
- package/lib/elo_swarm.py +0 -569
- package/lib/escrow-hooks.js +0 -237
- package/lib/escrow-hooks.ts +0 -391
- package/lib/identity.js +0 -376
- package/lib/identity.ts +0 -412
- package/lib/jitter.js +0 -54
- package/lib/proposals.js +0 -426
- package/lib/proposals.ts +0 -612
- package/lib/protocol.js +0 -516
- package/lib/receipts.js +0 -294
- package/lib/receipts.ts +0 -359
- package/lib/reputation.js +0 -664
- package/lib/reputation.ts +0 -790
- package/lib/security.js +0 -183
- package/lib/server/handlers/admin.js +0 -94
- package/lib/server/handlers/identity.js +0 -258
- package/lib/server/handlers/index.js +0 -42
- package/lib/server/handlers/message.js +0 -319
- package/lib/server/handlers/presence.js +0 -45
- package/lib/server/handlers/proposal.js +0 -358
- package/lib/server/handlers/skills.js +0 -141
- package/lib/server-directory.js +0 -190
- package/lib/server-directory.ts +0 -232
- package/lib/server.js +0 -633
- package/lib/server.ts +0 -698
- package/lib/supervisor/USAGE.md +0 -110
- package/lib/supervisor/agent-health.sh +0 -107
- package/lib/supervisor/agent-monitor.sh +0 -123
- package/lib/supervisor/agent-supervisor.sh +0 -135
- package/lib/supervisor/agentctl.sh +0 -266
- package/lib/supervisor/god-backup.sh +0 -126
- package/lib/supervisor/god-watchdog.sh +0 -107
- package/lib/supervisor/killswitch.sh +0 -43
- package/lib/supervisor/notify.sh +0 -19
- package/lib/types.ts +0 -433
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentChat Daemon
|
|
3
|
+
* Persistent connection with file-based inbox/outbox
|
|
4
|
+
* Supports multiple instances with different identities
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import fsp from 'fs/promises';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { AgentChatClient } from './client.js';
|
|
10
|
+
import { DEFAULT_IDENTITY_PATH } from './identity.js';
|
|
11
|
+
import { appendReceipt, shouldStoreReceipt, DEFAULT_RECEIPTS_PATH } from './receipts.js';
|
|
12
|
+
import { enforceDirectorySafety } from './security.js';
|
|
13
|
+
// ============ Constants ============
|
|
14
|
+
// Base directory (cwd-relative for project-local storage)
|
|
15
|
+
const AGENTCHAT_DIR = path.join(process.cwd(), '.agentchat');
|
|
16
|
+
const DAEMONS_DIR = path.join(AGENTCHAT_DIR, 'daemons');
|
|
17
|
+
// Default instance name
|
|
18
|
+
const DEFAULT_INSTANCE = 'default';
|
|
19
|
+
const DEFAULT_CHANNELS = ['#general', '#agents', '#code-review', '#servers'];
|
|
20
|
+
const MAX_INBOX_LINES = 1000;
|
|
21
|
+
const RECONNECT_DELAY = 5000; // 5 seconds
|
|
22
|
+
const MAX_RECONNECT_TIME = 10 * 60 * 1000; // 10 minutes default
|
|
23
|
+
const OUTBOX_POLL_INTERVAL = 500; // 500ms
|
|
24
|
+
// ============ Helper Functions ============
|
|
25
|
+
/**
|
|
26
|
+
* Validate instance name to prevent path traversal
|
|
27
|
+
* Only allows alphanumeric, hyphens, and underscores
|
|
28
|
+
*/
|
|
29
|
+
function validateInstanceName(name) {
|
|
30
|
+
if (!name || typeof name !== 'string') {
|
|
31
|
+
return 'default';
|
|
32
|
+
}
|
|
33
|
+
// Strip any path separators and dangerous characters
|
|
34
|
+
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
35
|
+
return sanitized || 'default';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get paths for a daemon instance
|
|
39
|
+
*/
|
|
40
|
+
export function getDaemonPaths(instanceName = DEFAULT_INSTANCE) {
|
|
41
|
+
const safeName = validateInstanceName(instanceName);
|
|
42
|
+
const instanceDir = path.join(DAEMONS_DIR, safeName);
|
|
43
|
+
return {
|
|
44
|
+
dir: instanceDir,
|
|
45
|
+
inbox: path.join(instanceDir, 'inbox.jsonl'),
|
|
46
|
+
outbox: path.join(instanceDir, 'outbox.jsonl'),
|
|
47
|
+
log: path.join(instanceDir, 'daemon.log'),
|
|
48
|
+
pid: path.join(instanceDir, 'daemon.pid'),
|
|
49
|
+
newdata: path.join(instanceDir, 'newdata') // Semaphore for new messages
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// ============ AgentChatDaemon Class ============
|
|
53
|
+
export class AgentChatDaemon {
|
|
54
|
+
server;
|
|
55
|
+
identityPath;
|
|
56
|
+
channels;
|
|
57
|
+
instanceName;
|
|
58
|
+
maxReconnectTime;
|
|
59
|
+
paths;
|
|
60
|
+
client;
|
|
61
|
+
running;
|
|
62
|
+
reconnecting;
|
|
63
|
+
reconnectStartTime;
|
|
64
|
+
outboxWatcher;
|
|
65
|
+
outboxPollInterval;
|
|
66
|
+
lastOutboxSize;
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this.server = options.server;
|
|
69
|
+
this.identityPath = options.identity || DEFAULT_IDENTITY_PATH;
|
|
70
|
+
this.channels = options.channels || DEFAULT_CHANNELS;
|
|
71
|
+
this.instanceName = options.name || DEFAULT_INSTANCE;
|
|
72
|
+
this.maxReconnectTime = options.maxReconnectTime || MAX_RECONNECT_TIME;
|
|
73
|
+
// Get instance-specific paths
|
|
74
|
+
this.paths = getDaemonPaths(this.instanceName);
|
|
75
|
+
this.client = null;
|
|
76
|
+
this.running = false;
|
|
77
|
+
this.reconnecting = false;
|
|
78
|
+
this.reconnectStartTime = null;
|
|
79
|
+
this.outboxWatcher = null;
|
|
80
|
+
this.outboxPollInterval = null;
|
|
81
|
+
this.lastOutboxSize = 0;
|
|
82
|
+
}
|
|
83
|
+
async _ensureDir() {
|
|
84
|
+
await fsp.mkdir(this.paths.dir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
_log(level, message) {
|
|
87
|
+
const timestamp = new Date().toISOString();
|
|
88
|
+
const line = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
|
|
89
|
+
// Append to log file
|
|
90
|
+
try {
|
|
91
|
+
fs.appendFileSync(this.paths.log, line);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Directory might not exist yet
|
|
95
|
+
}
|
|
96
|
+
// Also output to console if not background
|
|
97
|
+
if (level === 'error') {
|
|
98
|
+
console.error(line.trim());
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
console.log(line.trim());
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async _appendToInbox(msg) {
|
|
105
|
+
const line = JSON.stringify(msg) + '\n';
|
|
106
|
+
// Append to inbox
|
|
107
|
+
await fsp.appendFile(this.paths.inbox, line);
|
|
108
|
+
// Touch semaphore file to signal new data
|
|
109
|
+
await fsp.writeFile(this.paths.newdata, Date.now().toString());
|
|
110
|
+
// Check if we need to truncate (ring buffer)
|
|
111
|
+
await this._truncateInbox();
|
|
112
|
+
}
|
|
113
|
+
async _truncateInbox() {
|
|
114
|
+
try {
|
|
115
|
+
const content = await fsp.readFile(this.paths.inbox, 'utf-8');
|
|
116
|
+
const lines = content.trim().split('\n');
|
|
117
|
+
if (lines.length > MAX_INBOX_LINES) {
|
|
118
|
+
// Keep only the last MAX_INBOX_LINES
|
|
119
|
+
const newLines = lines.slice(-MAX_INBOX_LINES);
|
|
120
|
+
await fsp.writeFile(this.paths.inbox, newLines.join('\n') + '\n');
|
|
121
|
+
this._log('info', `Truncated inbox to ${MAX_INBOX_LINES} lines`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
const error = err;
|
|
126
|
+
if (error.code !== 'ENOENT') {
|
|
127
|
+
this._log('error', `Failed to truncate inbox: ${error.message}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async _saveReceiptIfParty(completeMsg) {
|
|
132
|
+
try {
|
|
133
|
+
// Get our agent ID
|
|
134
|
+
const ourAgentId = this.client?.agentId;
|
|
135
|
+
if (!ourAgentId) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Check if we should store this receipt
|
|
139
|
+
if (shouldStoreReceipt(completeMsg, ourAgentId)) {
|
|
140
|
+
await appendReceipt(completeMsg, DEFAULT_RECEIPTS_PATH);
|
|
141
|
+
this._log('info', `Saved receipt for proposal ${completeMsg.proposal_id}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
const error = err;
|
|
146
|
+
this._log('error', `Failed to save receipt: ${error.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async _processOutbox() {
|
|
150
|
+
try {
|
|
151
|
+
// Check if outbox exists
|
|
152
|
+
try {
|
|
153
|
+
await fsp.access(this.paths.outbox);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return; // No outbox file
|
|
157
|
+
}
|
|
158
|
+
const content = await fsp.readFile(this.paths.outbox, 'utf-8');
|
|
159
|
+
if (!content.trim())
|
|
160
|
+
return;
|
|
161
|
+
const lines = content.trim().split('\n');
|
|
162
|
+
for (const line of lines) {
|
|
163
|
+
if (!line.trim())
|
|
164
|
+
continue;
|
|
165
|
+
try {
|
|
166
|
+
const msg = JSON.parse(line);
|
|
167
|
+
if (msg.to && msg.content) {
|
|
168
|
+
// Join channel if needed
|
|
169
|
+
if (msg.to.startsWith('#') && this.client && !this.client.channels.has(msg.to)) {
|
|
170
|
+
await this.client.join(msg.to);
|
|
171
|
+
this._log('info', `Joined ${msg.to} for outbound message`);
|
|
172
|
+
}
|
|
173
|
+
if (this.client) {
|
|
174
|
+
await this.client.send(msg.to, msg.content);
|
|
175
|
+
this._log('info', `Sent message to ${msg.to}: ${msg.content.substring(0, 50)}...`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this._log('warn', `Invalid outbox message: ${line}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
const error = err;
|
|
184
|
+
this._log('error', `Failed to process outbox line: ${error.message}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Truncate outbox after processing
|
|
188
|
+
await fsp.writeFile(this.paths.outbox, '');
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
const error = err;
|
|
192
|
+
if (error.code !== 'ENOENT') {
|
|
193
|
+
this._log('error', `Outbox error: ${error.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
_startOutboxWatcher() {
|
|
198
|
+
// Use polling instead of fs.watch for reliability
|
|
199
|
+
this.outboxPollInterval = setInterval(() => {
|
|
200
|
+
if (this.client && this.client.connected) {
|
|
201
|
+
this._processOutbox();
|
|
202
|
+
}
|
|
203
|
+
}, OUTBOX_POLL_INTERVAL);
|
|
204
|
+
// Also try fs.watch for immediate response (may not work on all platforms)
|
|
205
|
+
try {
|
|
206
|
+
// Ensure outbox file exists
|
|
207
|
+
if (!fs.existsSync(this.paths.outbox)) {
|
|
208
|
+
fs.writeFileSync(this.paths.outbox, '');
|
|
209
|
+
}
|
|
210
|
+
this.outboxWatcher = fs.watch(this.paths.outbox, (eventType) => {
|
|
211
|
+
if (eventType === 'change' && this.client && this.client.connected) {
|
|
212
|
+
this._processOutbox();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
const error = err;
|
|
218
|
+
this._log('warn', `fs.watch not available, using polling only: ${error.message}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
_stopOutboxWatcher() {
|
|
222
|
+
if (this.outboxPollInterval) {
|
|
223
|
+
clearInterval(this.outboxPollInterval);
|
|
224
|
+
this.outboxPollInterval = null;
|
|
225
|
+
}
|
|
226
|
+
if (this.outboxWatcher) {
|
|
227
|
+
this.outboxWatcher.close();
|
|
228
|
+
this.outboxWatcher = null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async _connect() {
|
|
232
|
+
this._log('info', `Connecting to ${this.server}...`);
|
|
233
|
+
this.client = new AgentChatClient({
|
|
234
|
+
server: this.server,
|
|
235
|
+
identity: this.identityPath
|
|
236
|
+
});
|
|
237
|
+
// Set up event handlers
|
|
238
|
+
this.client.on('message', async (msg) => {
|
|
239
|
+
await this._appendToInbox(msg);
|
|
240
|
+
});
|
|
241
|
+
this.client.on('agent_joined', async (msg) => {
|
|
242
|
+
await this._appendToInbox(msg);
|
|
243
|
+
});
|
|
244
|
+
this.client.on('agent_left', async (msg) => {
|
|
245
|
+
await this._appendToInbox(msg);
|
|
246
|
+
});
|
|
247
|
+
this.client.on('proposal', async (msg) => {
|
|
248
|
+
await this._appendToInbox(msg);
|
|
249
|
+
});
|
|
250
|
+
this.client.on('accept', async (msg) => {
|
|
251
|
+
await this._appendToInbox(msg);
|
|
252
|
+
});
|
|
253
|
+
this.client.on('reject', async (msg) => {
|
|
254
|
+
await this._appendToInbox(msg);
|
|
255
|
+
});
|
|
256
|
+
this.client.on('complete', async (msg) => {
|
|
257
|
+
await this._appendToInbox(msg);
|
|
258
|
+
// Save receipt if we're a party to this completion
|
|
259
|
+
await this._saveReceiptIfParty(msg);
|
|
260
|
+
});
|
|
261
|
+
this.client.on('dispute', async (msg) => {
|
|
262
|
+
await this._appendToInbox(msg);
|
|
263
|
+
});
|
|
264
|
+
this.client.on('disconnect', () => {
|
|
265
|
+
this._log('warn', 'Disconnected from server');
|
|
266
|
+
if (this.running && !this.reconnecting) {
|
|
267
|
+
this._scheduleReconnect();
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
this.client.on('error', (err) => {
|
|
271
|
+
const message = err instanceof Error ? err.message : (err.message || JSON.stringify(err));
|
|
272
|
+
this._log('error', `Client error: ${message}`);
|
|
273
|
+
});
|
|
274
|
+
try {
|
|
275
|
+
await this.client.connect();
|
|
276
|
+
this._log('info', `Connected as ${this.client.agentId}`);
|
|
277
|
+
// Join channels
|
|
278
|
+
for (const channel of this.channels) {
|
|
279
|
+
try {
|
|
280
|
+
await this.client.join(channel);
|
|
281
|
+
this._log('info', `Joined ${channel}`);
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
const error = err;
|
|
285
|
+
this._log('error', `Failed to join ${channel}: ${error.message}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
const error = err;
|
|
292
|
+
this._log('error', `Connection failed: ${error.message}`);
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
_scheduleReconnect() {
|
|
297
|
+
if (!this.running || this.reconnecting)
|
|
298
|
+
return;
|
|
299
|
+
// Start tracking reconnect time if this is the first attempt
|
|
300
|
+
if (!this.reconnectStartTime) {
|
|
301
|
+
this.reconnectStartTime = Date.now();
|
|
302
|
+
}
|
|
303
|
+
// Check if we've exceeded max reconnect time
|
|
304
|
+
const elapsed = Date.now() - this.reconnectStartTime;
|
|
305
|
+
if (elapsed >= this.maxReconnectTime) {
|
|
306
|
+
this._log('error', `Max reconnect time (${this.maxReconnectTime / 1000 / 60} minutes) exceeded. Giving up.`);
|
|
307
|
+
this._log('info', 'Daemon will exit. Restart manually or use a process manager.');
|
|
308
|
+
this.stop();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
this.reconnecting = true;
|
|
312
|
+
const remaining = Math.round((this.maxReconnectTime - elapsed) / 1000);
|
|
313
|
+
this._log('info', `Reconnecting in ${RECONNECT_DELAY / 1000} seconds... (${remaining}s until timeout)`);
|
|
314
|
+
setTimeout(async () => {
|
|
315
|
+
this.reconnecting = false;
|
|
316
|
+
if (this.running) {
|
|
317
|
+
const connected = await this._connect();
|
|
318
|
+
if (connected) {
|
|
319
|
+
// Reset reconnect timer on successful connection
|
|
320
|
+
this.reconnectStartTime = null;
|
|
321
|
+
this._log('info', 'Reconnected successfully');
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
this._scheduleReconnect();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}, RECONNECT_DELAY);
|
|
328
|
+
}
|
|
329
|
+
async start() {
|
|
330
|
+
// Security check: prevent running in root/system directories
|
|
331
|
+
enforceDirectorySafety(process.cwd(), { allowWarnings: true, silent: false });
|
|
332
|
+
this.running = true;
|
|
333
|
+
// Ensure instance directory exists
|
|
334
|
+
await this._ensureDir();
|
|
335
|
+
// Write PID file
|
|
336
|
+
await fsp.writeFile(this.paths.pid, process.pid.toString());
|
|
337
|
+
this._log('info', `Daemon starting (PID: ${process.pid}, instance: ${this.instanceName})`);
|
|
338
|
+
// Initialize inbox if it doesn't exist
|
|
339
|
+
try {
|
|
340
|
+
await fsp.access(this.paths.inbox);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
await fsp.writeFile(this.paths.inbox, '');
|
|
344
|
+
}
|
|
345
|
+
// Connect to server
|
|
346
|
+
const connected = await this._connect();
|
|
347
|
+
if (!connected) {
|
|
348
|
+
this._scheduleReconnect();
|
|
349
|
+
}
|
|
350
|
+
// Start watching outbox
|
|
351
|
+
this._startOutboxWatcher();
|
|
352
|
+
// Handle shutdown signals
|
|
353
|
+
process.on('SIGINT', () => this.stop());
|
|
354
|
+
process.on('SIGTERM', () => this.stop());
|
|
355
|
+
this._log('info', 'Daemon started');
|
|
356
|
+
this._log('info', `Inbox: ${this.paths.inbox}`);
|
|
357
|
+
this._log('info', `Outbox: ${this.paths.outbox}`);
|
|
358
|
+
this._log('info', `Log: ${this.paths.log}`);
|
|
359
|
+
}
|
|
360
|
+
async stop() {
|
|
361
|
+
this._log('info', 'Daemon stopping...');
|
|
362
|
+
this.running = false;
|
|
363
|
+
this._stopOutboxWatcher();
|
|
364
|
+
if (this.client) {
|
|
365
|
+
this.client.disconnect();
|
|
366
|
+
}
|
|
367
|
+
// Remove PID file
|
|
368
|
+
try {
|
|
369
|
+
await fsp.unlink(this.paths.pid);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// Ignore if already gone
|
|
373
|
+
}
|
|
374
|
+
this._log('info', 'Daemon stopped');
|
|
375
|
+
process.exit(0);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// ============ Utility Functions ============
|
|
379
|
+
/**
|
|
380
|
+
* Check if daemon instance is running
|
|
381
|
+
*/
|
|
382
|
+
export async function isDaemonRunning(instanceName = DEFAULT_INSTANCE) {
|
|
383
|
+
const paths = getDaemonPaths(instanceName);
|
|
384
|
+
try {
|
|
385
|
+
const pid = await fsp.readFile(paths.pid, 'utf-8');
|
|
386
|
+
const pidNum = parseInt(pid.trim());
|
|
387
|
+
// Check if process is running
|
|
388
|
+
try {
|
|
389
|
+
process.kill(pidNum, 0);
|
|
390
|
+
return { running: true, pid: pidNum, instance: instanceName };
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Process not running, clean up stale PID file
|
|
394
|
+
await fsp.unlink(paths.pid);
|
|
395
|
+
return { running: false, instance: instanceName };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
return { running: false, instance: instanceName };
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Stop a daemon instance
|
|
404
|
+
*/
|
|
405
|
+
export async function stopDaemon(instanceName = DEFAULT_INSTANCE) {
|
|
406
|
+
const status = await isDaemonRunning(instanceName);
|
|
407
|
+
if (!status.running) {
|
|
408
|
+
return { stopped: false, reason: 'Daemon not running', instance: instanceName };
|
|
409
|
+
}
|
|
410
|
+
const paths = getDaemonPaths(instanceName);
|
|
411
|
+
try {
|
|
412
|
+
process.kill(status.pid, 'SIGTERM');
|
|
413
|
+
// Wait a bit for clean shutdown
|
|
414
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
415
|
+
// Check if still running
|
|
416
|
+
try {
|
|
417
|
+
process.kill(status.pid, 0);
|
|
418
|
+
// Still running, force kill
|
|
419
|
+
process.kill(status.pid, 'SIGKILL');
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
// Process gone, good
|
|
423
|
+
}
|
|
424
|
+
// Clean up PID file
|
|
425
|
+
try {
|
|
426
|
+
await fsp.unlink(paths.pid);
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// Ignore
|
|
430
|
+
}
|
|
431
|
+
return { stopped: true, pid: status.pid, instance: instanceName };
|
|
432
|
+
}
|
|
433
|
+
catch (err) {
|
|
434
|
+
const error = err;
|
|
435
|
+
return { stopped: false, reason: error.message, instance: instanceName };
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get daemon instance status
|
|
440
|
+
*/
|
|
441
|
+
export async function getDaemonStatus(instanceName = DEFAULT_INSTANCE) {
|
|
442
|
+
const status = await isDaemonRunning(instanceName);
|
|
443
|
+
const paths = getDaemonPaths(instanceName);
|
|
444
|
+
if (!status.running) {
|
|
445
|
+
return {
|
|
446
|
+
running: false,
|
|
447
|
+
instance: instanceName
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
// Get additional info
|
|
451
|
+
let inboxLines = 0;
|
|
452
|
+
let lastMessage = null;
|
|
453
|
+
try {
|
|
454
|
+
const content = await fsp.readFile(paths.inbox, 'utf-8');
|
|
455
|
+
const lines = content.trim().split('\n').filter(l => l);
|
|
456
|
+
inboxLines = lines.length;
|
|
457
|
+
if (lines.length > 0) {
|
|
458
|
+
try {
|
|
459
|
+
lastMessage = JSON.parse(lines[lines.length - 1]);
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// Ignore parse errors
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
// No inbox
|
|
468
|
+
}
|
|
469
|
+
return {
|
|
470
|
+
running: true,
|
|
471
|
+
instance: instanceName,
|
|
472
|
+
pid: status.pid,
|
|
473
|
+
inboxPath: paths.inbox,
|
|
474
|
+
outboxPath: paths.outbox,
|
|
475
|
+
logPath: paths.log,
|
|
476
|
+
inboxLines,
|
|
477
|
+
lastMessage
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* List all daemon instances
|
|
482
|
+
*/
|
|
483
|
+
export async function listDaemons() {
|
|
484
|
+
const instances = [];
|
|
485
|
+
try {
|
|
486
|
+
const entries = await fsp.readdir(DAEMONS_DIR, { withFileTypes: true });
|
|
487
|
+
for (const entry of entries) {
|
|
488
|
+
if (entry.isDirectory()) {
|
|
489
|
+
const status = await isDaemonRunning(entry.name);
|
|
490
|
+
instances.push({
|
|
491
|
+
name: entry.name,
|
|
492
|
+
running: status.running,
|
|
493
|
+
pid: status.pid || null
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
// No daemons directory
|
|
500
|
+
}
|
|
501
|
+
return instances;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Stop all running daemons
|
|
505
|
+
*/
|
|
506
|
+
export async function stopAllDaemons() {
|
|
507
|
+
const instances = await listDaemons();
|
|
508
|
+
const results = [];
|
|
509
|
+
for (const instance of instances) {
|
|
510
|
+
if (instance.running) {
|
|
511
|
+
const result = await stopDaemon(instance.name);
|
|
512
|
+
results.push(result);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return results;
|
|
516
|
+
}
|
|
517
|
+
// Export for CLI (backwards compatibility with default paths)
|
|
518
|
+
export const INBOX_PATH = getDaemonPaths(DEFAULT_INSTANCE).inbox;
|
|
519
|
+
export const OUTBOX_PATH = getDaemonPaths(DEFAULT_INSTANCE).outbox;
|
|
520
|
+
export const LOG_PATH = getDaemonPaths(DEFAULT_INSTANCE).log;
|
|
521
|
+
export const PID_PATH = getDaemonPaths(DEFAULT_INSTANCE).pid;
|
|
522
|
+
export { DEFAULT_CHANNELS, DEFAULT_INSTANCE };
|
|
523
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../lib/daemon.ts"],"names":[],"mappings":"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"}
|