@calliopelabs/cli 2.3.0 → 2.5.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 (186) hide show
  1. package/README.md +17 -0
  2. package/dist/agents/agent-config-loader.js +1 -1
  3. package/dist/agents/agent-config-presets.js +13 -13
  4. package/dist/agents/agent-config-presets.js.map +1 -1
  5. package/dist/agents/agent-config-types.d.ts +1 -1
  6. package/dist/agents/agent-config-types.d.ts.map +1 -1
  7. package/dist/agents/dynamic-tools.d.ts.map +1 -1
  8. package/dist/agents/dynamic-tools.js +39 -10
  9. package/dist/agents/dynamic-tools.js.map +1 -1
  10. package/dist/agents/sdk-backend.js +1 -1
  11. package/dist/agents/sdk-backend.js.map +1 -1
  12. package/dist/api-server.d.ts +9 -0
  13. package/dist/api-server.d.ts.map +1 -1
  14. package/dist/api-server.js +74 -3
  15. package/dist/api-server.js.map +1 -1
  16. package/dist/auto-checkpoint.d.ts.map +1 -1
  17. package/dist/auto-checkpoint.js +50 -17
  18. package/dist/auto-checkpoint.js.map +1 -1
  19. package/dist/auto-compressor.d.ts.map +1 -1
  20. package/dist/auto-compressor.js +9 -5
  21. package/dist/auto-compressor.js.map +1 -1
  22. package/dist/bin.d.ts +8 -0
  23. package/dist/bin.d.ts.map +1 -1
  24. package/dist/bin.js +59 -4
  25. package/dist/bin.js.map +1 -1
  26. package/dist/branching.d.ts.map +1 -1
  27. package/dist/branching.js +14 -1
  28. package/dist/branching.js.map +1 -1
  29. package/dist/checkpoint.d.ts.map +1 -1
  30. package/dist/checkpoint.js +13 -1
  31. package/dist/checkpoint.js.map +1 -1
  32. package/dist/cli/agent.d.ts.map +1 -1
  33. package/dist/cli/agent.js +19 -3
  34. package/dist/cli/agent.js.map +1 -1
  35. package/dist/cli/commands.d.ts.map +1 -1
  36. package/dist/cli/commands.js +99 -0
  37. package/dist/cli/commands.js.map +1 -1
  38. package/dist/cli/index.d.ts.map +1 -1
  39. package/dist/cli/index.js +32 -1
  40. package/dist/cli/index.js.map +1 -1
  41. package/dist/cli/types.js +1 -1
  42. package/dist/cli/types.js.map +1 -1
  43. package/dist/config.js +2 -2
  44. package/dist/config.js.map +1 -1
  45. package/dist/diff.d.ts.map +1 -1
  46. package/dist/diff.js +42 -4
  47. package/dist/diff.js.map +1 -1
  48. package/dist/errors.d.ts.map +1 -1
  49. package/dist/errors.js +30 -3
  50. package/dist/errors.js.map +1 -1
  51. package/dist/headless.d.ts.map +1 -1
  52. package/dist/headless.js +56 -2
  53. package/dist/headless.js.map +1 -1
  54. package/dist/hooks.d.ts +8 -2
  55. package/dist/hooks.d.ts.map +1 -1
  56. package/dist/hooks.js +97 -11
  57. package/dist/hooks.js.map +1 -1
  58. package/dist/idle-eviction.d.ts.map +1 -1
  59. package/dist/idle-eviction.js +8 -1
  60. package/dist/idle-eviction.js.map +1 -1
  61. package/dist/markdown.d.ts.map +1 -1
  62. package/dist/markdown.js +32 -10
  63. package/dist/markdown.js.map +1 -1
  64. package/dist/mcp.d.ts +35 -5
  65. package/dist/mcp.d.ts.map +1 -1
  66. package/dist/mcp.js +186 -12
  67. package/dist/mcp.js.map +1 -1
  68. package/dist/model-detection.d.ts +14 -1
  69. package/dist/model-detection.d.ts.map +1 -1
  70. package/dist/model-detection.js +307 -114
  71. package/dist/model-detection.js.map +1 -1
  72. package/dist/model-router.js +7 -7
  73. package/dist/model-router.js.map +1 -1
  74. package/dist/parallel-tools.d.ts +9 -1
  75. package/dist/parallel-tools.d.ts.map +1 -1
  76. package/dist/parallel-tools.js +6 -5
  77. package/dist/parallel-tools.js.map +1 -1
  78. package/dist/plugins.d.ts +37 -0
  79. package/dist/plugins.d.ts.map +1 -1
  80. package/dist/plugins.js +87 -0
  81. package/dist/plugins.js.map +1 -1
  82. package/dist/providers/anthropic.d.ts.map +1 -1
  83. package/dist/providers/anthropic.js +36 -2
  84. package/dist/providers/anthropic.js.map +1 -1
  85. package/dist/providers/bedrock.d.ts.map +1 -1
  86. package/dist/providers/bedrock.js +81 -17
  87. package/dist/providers/bedrock.js.map +1 -1
  88. package/dist/providers/index.d.ts.map +1 -1
  89. package/dist/providers/index.js +2 -0
  90. package/dist/providers/index.js.map +1 -1
  91. package/dist/providers/types.d.ts.map +1 -1
  92. package/dist/providers/types.js +19 -10
  93. package/dist/providers/types.js.map +1 -1
  94. package/dist/risk.d.ts.map +1 -1
  95. package/dist/risk.js +15 -5
  96. package/dist/risk.js.map +1 -1
  97. package/dist/sandbox-native.d.ts +1 -0
  98. package/dist/sandbox-native.d.ts.map +1 -1
  99. package/dist/sandbox-native.js +37 -5
  100. package/dist/sandbox-native.js.map +1 -1
  101. package/dist/scope.d.ts +10 -0
  102. package/dist/scope.d.ts.map +1 -1
  103. package/dist/scope.js +75 -15
  104. package/dist/scope.js.map +1 -1
  105. package/dist/scuttlebot/client.d.ts +83 -0
  106. package/dist/scuttlebot/client.d.ts.map +1 -0
  107. package/dist/scuttlebot/client.js +350 -0
  108. package/dist/scuttlebot/client.js.map +1 -0
  109. package/dist/scuttlebot/config.d.ts +28 -0
  110. package/dist/scuttlebot/config.d.ts.map +1 -0
  111. package/dist/scuttlebot/config.js +91 -0
  112. package/dist/scuttlebot/config.js.map +1 -0
  113. package/dist/scuttlebot/http-client.d.ts +63 -0
  114. package/dist/scuttlebot/http-client.d.ts.map +1 -0
  115. package/dist/scuttlebot/http-client.js +124 -0
  116. package/dist/scuttlebot/http-client.js.map +1 -0
  117. package/dist/scuttlebot/index.d.ts +13 -0
  118. package/dist/scuttlebot/index.d.ts.map +1 -0
  119. package/dist/scuttlebot/index.js +10 -0
  120. package/dist/scuttlebot/index.js.map +1 -0
  121. package/dist/scuttlebot/irc-client.d.ts +124 -0
  122. package/dist/scuttlebot/irc-client.d.ts.map +1 -0
  123. package/dist/scuttlebot/irc-client.js +599 -0
  124. package/dist/scuttlebot/irc-client.js.map +1 -0
  125. package/dist/skills.d.ts +19 -0
  126. package/dist/skills.d.ts.map +1 -1
  127. package/dist/skills.js +98 -10
  128. package/dist/skills.js.map +1 -1
  129. package/dist/smart-router.js +4 -4
  130. package/dist/smart-router.js.map +1 -1
  131. package/dist/storage.d.ts +0 -4
  132. package/dist/storage.d.ts.map +1 -1
  133. package/dist/storage.js +81 -5
  134. package/dist/storage.js.map +1 -1
  135. package/dist/tools.d.ts.map +1 -1
  136. package/dist/tools.js +232 -38
  137. package/dist/tools.js.map +1 -1
  138. package/dist/trust.d.ts +16 -3
  139. package/dist/trust.d.ts.map +1 -1
  140. package/dist/trust.js +23 -4
  141. package/dist/trust.js.map +1 -1
  142. package/dist/types.d.ts.map +1 -1
  143. package/dist/types.js +13 -4
  144. package/dist/types.js.map +1 -1
  145. package/dist/ui/agent.d.ts +1 -1
  146. package/dist/ui/agent.d.ts.map +1 -1
  147. package/dist/ui/agent.js +35 -44
  148. package/dist/ui/agent.js.map +1 -1
  149. package/dist/ui/chat-input.d.ts +3 -1
  150. package/dist/ui/chat-input.d.ts.map +1 -1
  151. package/dist/ui/chat-input.js +82 -17
  152. package/dist/ui/chat-input.js.map +1 -1
  153. package/dist/ui/commands.d.ts +2 -0
  154. package/dist/ui/commands.d.ts.map +1 -1
  155. package/dist/ui/commands.js +318 -10
  156. package/dist/ui/commands.js.map +1 -1
  157. package/dist/ui/index.d.ts.map +1 -1
  158. package/dist/ui/index.js +236 -46
  159. package/dist/ui/index.js.map +1 -1
  160. package/dist/ui/input-utils.d.ts +20 -0
  161. package/dist/ui/input-utils.d.ts.map +1 -0
  162. package/dist/ui/input-utils.js +35 -0
  163. package/dist/ui/input-utils.js.map +1 -0
  164. package/dist/ui/messages.d.ts +6 -2
  165. package/dist/ui/messages.d.ts.map +1 -1
  166. package/dist/ui/messages.js +42 -11
  167. package/dist/ui/messages.js.map +1 -1
  168. package/dist/ui/modals.d.ts +21 -1
  169. package/dist/ui/modals.d.ts.map +1 -1
  170. package/dist/ui/modals.js +67 -5
  171. package/dist/ui/modals.js.map +1 -1
  172. package/dist/ui/status-bar.d.ts +4 -1
  173. package/dist/ui/status-bar.d.ts.map +1 -1
  174. package/dist/ui/status-bar.js +12 -1
  175. package/dist/ui/status-bar.js.map +1 -1
  176. package/dist/ui/types.d.ts +3 -0
  177. package/dist/ui/types.d.ts.map +1 -1
  178. package/package.json +4 -7
  179. package/dist/completion.d.ts +0 -75
  180. package/dist/completion.d.ts.map +0 -1
  181. package/dist/completion.js +0 -234
  182. package/dist/completion.js.map +0 -1
  183. package/dist/keyboard.d.ts +0 -57
  184. package/dist/keyboard.d.ts.map +0 -1
  185. package/dist/keyboard.js +0 -265
  186. package/dist/keyboard.js.map +0 -1
@@ -0,0 +1,599 @@
1
+ /**
2
+ * Scuttlebot IRC Client
3
+ *
4
+ * Zero-dependency IRC client using Node.js net.Socket.
5
+ * Connects directly to Ergo IRC server with SASL PLAIN auth.
6
+ * Handles the scuttlebot envelope protocol (JSON over PRIVMSG).
7
+ */
8
+ import * as net from 'node:net';
9
+ import * as tls from 'node:tls';
10
+ import * as crypto from 'node:crypto';
11
+ /** Well-known message types. */
12
+ export const MessageTypes = {
13
+ AgentHello: 'agent.hello',
14
+ AgentBye: 'agent.bye',
15
+ TaskCreate: 'task.create',
16
+ TaskUpdate: 'task.update',
17
+ TaskComplete: 'task.complete',
18
+ };
19
+ /**
20
+ * Check whether an envelope is addressed to `nick` with `agentType`.
21
+ *
22
+ * Ported from Go's protocol.MatchesRecipient:
23
+ * - empty/nil to -> true (broadcast)
24
+ * - @all -> true
25
+ * - @workers etc. -> agentType match
26
+ * - @prefix-* -> nick starts with prefix-
27
+ * - bare string -> exact nick match
28
+ */
29
+ export function matchesRecipient(env, nick, agentType) {
30
+ if (!env.to || env.to.length === 0) {
31
+ return true;
32
+ }
33
+ for (const token of env.to) {
34
+ switch (token) {
35
+ case '@all':
36
+ return true;
37
+ case '@operators':
38
+ if (agentType === 'operator')
39
+ return true;
40
+ break;
41
+ case '@orchestrators':
42
+ if (agentType === 'orchestrator')
43
+ return true;
44
+ break;
45
+ case '@workers':
46
+ if (agentType === 'worker')
47
+ return true;
48
+ break;
49
+ case '@observers':
50
+ if (agentType === 'observer')
51
+ return true;
52
+ break;
53
+ default:
54
+ if (token.startsWith('@')) {
55
+ // @prefix-* glob: strip @ and trailing *
56
+ const body = token.slice(1);
57
+ if (body.endsWith('-*')) {
58
+ const prefix = body.slice(0, -1); // keep the trailing dash
59
+ if (nick.startsWith(prefix))
60
+ return true;
61
+ }
62
+ }
63
+ else if (token === nick) {
64
+ return true;
65
+ }
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+ /** Create a new envelope with a generated ID and current timestamp. */
71
+ export function newEnvelope(type, from, opts) {
72
+ return {
73
+ v: 1,
74
+ type,
75
+ id: crypto.randomUUID(),
76
+ from,
77
+ ts: Date.now(),
78
+ ...(opts?.to ? { to: opts.to } : {}),
79
+ ...(opts?.payload !== undefined ? { payload: opts.payload } : {}),
80
+ };
81
+ }
82
+ /** Validate that a parsed object looks like a valid Envelope. */
83
+ function isEnvelope(obj) {
84
+ if (typeof obj !== 'object' || obj === null)
85
+ return false;
86
+ const e = obj;
87
+ return (e.v === 1 &&
88
+ typeof e.type === 'string' && e.type !== '' &&
89
+ typeof e.id === 'string' && e.id !== '' &&
90
+ typeof e.from === 'string' && e.from !== '' &&
91
+ typeof e.ts === 'number');
92
+ }
93
+ // ── IRC Client ───────────────────────────────────────────────────────
94
+ /** Agent nick prefixes that indicate non-human senders. */
95
+ const AGENT_PREFIXES = ['claude-', 'codex-', 'gemini-', 'calliope-'];
96
+ /** Known service bots to ignore for instruction delivery. */
97
+ const SERVICE_BOTS = new Set([
98
+ 'bridge', 'oracle', 'sentinel', 'steward', 'scribe',
99
+ 'warden', 'snitch', 'herald', 'scroll', 'systembot', 'auditbot',
100
+ ]);
101
+ export class ScuttlebotIRCClient {
102
+ opts;
103
+ agentType;
104
+ socket = null;
105
+ connected = false;
106
+ destroyed = false;
107
+ envelopeHandlers = [];
108
+ instructionHandlers = [];
109
+ // Reconnect state
110
+ reconnectTimer = null;
111
+ reconnectDelay = 2000; // ms, doubles up to 60s
112
+ shouldReconnect = true;
113
+ // Incoming data buffer (IRC lines are \r\n delimited)
114
+ buffer = '';
115
+ // SASL / registration state machine
116
+ saslState = 'none';
117
+ connectResolve = null;
118
+ connectReject = null;
119
+ connectTimeout = null;
120
+ // Client-initiated PING keepalive — detects dead TCP connections
121
+ static PING_INTERVAL_MS = 30_000;
122
+ static PING_TIMEOUT_MS = 30_000;
123
+ pingTimer = null;
124
+ pongTimer = null;
125
+ pendingPing = false;
126
+ // Signal handler registered for clean exit
127
+ exitHandler = null;
128
+ constructor(opts) {
129
+ this.opts = opts;
130
+ this.agentType = opts.agentType || 'worker';
131
+ }
132
+ /** Register a handler for incoming JSON envelopes. */
133
+ onEnvelope(handler) {
134
+ this.envelopeHandlers.push(handler);
135
+ }
136
+ /** Register a handler for human instructions (non-JSON PRIVMSG that mention our nick). */
137
+ onInstruction(handler) {
138
+ this.instructionHandlers.push(handler);
139
+ }
140
+ /**
141
+ * Connect to the IRC server. Resolves once fully registered (numeric 001 received).
142
+ * Rejects on timeout (30s) or fatal connection error during initial connect.
143
+ */
144
+ async connect() {
145
+ if (this.connected)
146
+ return;
147
+ this.destroyed = false;
148
+ this.shouldReconnect = true;
149
+ return new Promise((resolve, reject) => {
150
+ this.connectResolve = resolve;
151
+ this.connectReject = reject;
152
+ this.connectTimeout = setTimeout(() => {
153
+ if (!this.connected) {
154
+ const err = new Error('IRC connection timeout (30s)');
155
+ this.connectReject?.(err);
156
+ this.connectReject = null;
157
+ this.connectResolve = null;
158
+ this.cleanupSocket();
159
+ }
160
+ }, 30000);
161
+ this.createConnection();
162
+ });
163
+ }
164
+ /** Disconnect gracefully. Sends QUIT and closes the socket. */
165
+ async disconnect() {
166
+ this.shouldReconnect = false;
167
+ this.destroyed = true;
168
+ this.stopPingKeepalive();
169
+ this.unregisterExitHandler();
170
+ if (this.reconnectTimer) {
171
+ clearTimeout(this.reconnectTimer);
172
+ this.reconnectTimer = null;
173
+ }
174
+ if (this.connectTimeout) {
175
+ clearTimeout(this.connectTimeout);
176
+ this.connectTimeout = null;
177
+ }
178
+ if (this.socket && !this.socket.destroyed) {
179
+ this.sendRawLine('QUIT :Session ended');
180
+ // Give the server a moment to process QUIT before destroying
181
+ await new Promise((resolve) => {
182
+ const timer = setTimeout(() => {
183
+ this.cleanupSocket();
184
+ resolve();
185
+ }, 500);
186
+ this.socket?.once('close', () => {
187
+ clearTimeout(timer);
188
+ resolve();
189
+ });
190
+ });
191
+ }
192
+ this.connected = false;
193
+ }
194
+ /** Send a JSON envelope as PRIVMSG to a channel. */
195
+ sendEnvelope(channel, env) {
196
+ const full = newEnvelope(env.type, env.from, {
197
+ to: env.to,
198
+ payload: env.payload,
199
+ });
200
+ const json = JSON.stringify(full);
201
+ this.sendPrivmsg(channel, json);
202
+ }
203
+ /** Send a plain text PRIVMSG to a channel. */
204
+ sendRaw(channel, text) {
205
+ this.sendPrivmsg(channel, text);
206
+ }
207
+ /** Whether we are currently connected and registered on IRC. */
208
+ isConnected() {
209
+ return this.connected;
210
+ }
211
+ // ── Private: connection ──────────────────────────────────────────
212
+ createConnection() {
213
+ const [host, portStr] = parseHostPort(this.opts.serverAddr);
214
+ const port = parseInt(portStr, 10);
215
+ const useTLS = this.opts.tls ?? port === 6697;
216
+ this.buffer = '';
217
+ this.saslState = 'none';
218
+ const onConnect = () => {
219
+ // TCP/TLS connected — begin IRC handshake
220
+ this.saslState = 'cap-req';
221
+ this.sendRawLine('CAP REQ :sasl');
222
+ this.sendRawLine(`NICK ${this.opts.nick}`);
223
+ this.sendRawLine(`USER ${this.opts.nick} 0 * :${this.opts.nick}`);
224
+ };
225
+ const socket = useTLS
226
+ ? tls.connect({ host, port, servername: host, rejectUnauthorized: true }, onConnect)
227
+ : net.createConnection({ host, port }, onConnect);
228
+ socket.setEncoding('utf8');
229
+ socket.on('data', (data) => {
230
+ this.buffer += data;
231
+ this.processBuffer();
232
+ });
233
+ socket.on('error', (err) => {
234
+ if (this.connectReject) {
235
+ this.connectReject(err);
236
+ this.connectReject = null;
237
+ this.connectResolve = null;
238
+ if (this.connectTimeout) {
239
+ clearTimeout(this.connectTimeout);
240
+ this.connectTimeout = null;
241
+ }
242
+ }
243
+ this.connected = false;
244
+ });
245
+ socket.on('close', () => {
246
+ this.connected = false;
247
+ this.socket = null;
248
+ this.stopPingKeepalive();
249
+ this.scheduleReconnect();
250
+ });
251
+ this.socket = socket;
252
+ }
253
+ processBuffer() {
254
+ let idx;
255
+ while ((idx = this.buffer.indexOf('\r\n')) !== -1) {
256
+ const line = this.buffer.slice(0, idx);
257
+ this.buffer = this.buffer.slice(idx + 2);
258
+ if (line.length > 0) {
259
+ this.handleLine(line);
260
+ }
261
+ }
262
+ // Also handle \n-only line endings (some servers)
263
+ while ((idx = this.buffer.indexOf('\n')) !== -1) {
264
+ const line = this.buffer.slice(0, idx).replace(/\r$/, '');
265
+ this.buffer = this.buffer.slice(idx + 1);
266
+ if (line.length > 0) {
267
+ this.handleLine(line);
268
+ }
269
+ }
270
+ }
271
+ // ── Private: IRC line handling ───────────────────────────────────
272
+ handleLine(raw) {
273
+ // Strip IRCv3 message tags (we don't need them for now)
274
+ let line = raw;
275
+ if (line.startsWith('@')) {
276
+ const spaceIdx = line.indexOf(' ');
277
+ if (spaceIdx === -1)
278
+ return;
279
+ line = line.slice(spaceIdx + 1);
280
+ }
281
+ // PING must be answered immediately
282
+ if (line.startsWith('PING')) {
283
+ const payload = line.slice(5); // after "PING "
284
+ this.sendRawLine(`PONG ${payload}`);
285
+ return;
286
+ }
287
+ const parsed = parseIRCMessage(line);
288
+ if (!parsed)
289
+ return;
290
+ const { prefix, command, params } = parsed;
291
+ switch (command) {
292
+ // CAP negotiation
293
+ case 'CAP': {
294
+ // :server CAP * ACK :sasl
295
+ const subCommand = params.length >= 2 ? params[1] : '';
296
+ if (subCommand === 'ACK' && this.saslState === 'cap-req') {
297
+ this.saslState = 'cap-ack';
298
+ this.sendRawLine('AUTHENTICATE PLAIN');
299
+ }
300
+ else if (subCommand === 'NAK') {
301
+ // Server rejected SASL — try without it
302
+ this.sendRawLine('CAP END');
303
+ }
304
+ break;
305
+ }
306
+ case 'AUTHENTICATE': {
307
+ // Server sends "AUTHENTICATE +" to request the credentials
308
+ if (params[0] === '+' && this.saslState === 'cap-ack') {
309
+ const credentials = `\0${this.opts.nick}\0${this.opts.passphrase}`;
310
+ const encoded = Buffer.from(credentials).toString('base64');
311
+ this.sendRawLine(`AUTHENTICATE ${encoded}`);
312
+ this.saslState = 'auth-sent';
313
+ }
314
+ break;
315
+ }
316
+ // 903 = SASL auth successful
317
+ case '903': {
318
+ this.saslState = 'authenticated';
319
+ this.sendRawLine('CAP END');
320
+ break;
321
+ }
322
+ // 904/905 = SASL auth failed
323
+ case '904':
324
+ case '905': {
325
+ const errMsg = params.length > 1 ? params.slice(1).join(' ') : 'SASL authentication failed';
326
+ if (this.connectReject) {
327
+ this.connectReject(new Error(errMsg));
328
+ this.connectReject = null;
329
+ this.connectResolve = null;
330
+ if (this.connectTimeout) {
331
+ clearTimeout(this.connectTimeout);
332
+ this.connectTimeout = null;
333
+ }
334
+ }
335
+ this.cleanupSocket();
336
+ break;
337
+ }
338
+ // 001 = RPL_WELCOME — fully registered
339
+ case '001': {
340
+ this.connected = true;
341
+ this.saslState = 'registered';
342
+ this.reconnectDelay = 2000; // reset backoff on successful connect
343
+ // Join channels
344
+ for (const ch of this.opts.channels) {
345
+ const channelName = ch.startsWith('#') ? ch : `#${ch}`;
346
+ this.sendRawLine(`JOIN ${channelName}`);
347
+ }
348
+ // Resolve the connect() promise
349
+ if (this.connectTimeout) {
350
+ clearTimeout(this.connectTimeout);
351
+ this.connectTimeout = null;
352
+ }
353
+ if (this.connectResolve) {
354
+ this.connectResolve();
355
+ this.connectResolve = null;
356
+ this.connectReject = null;
357
+ }
358
+ // Start client-side PING keepalive and register clean-exit handler
359
+ this.startPingKeepalive();
360
+ this.registerExitHandler();
361
+ break;
362
+ }
363
+ // PONG — server responded to our keepalive PING
364
+ case 'PONG': {
365
+ if (this.pongTimer) {
366
+ clearTimeout(this.pongTimer);
367
+ this.pongTimer = null;
368
+ }
369
+ this.pendingPing = false;
370
+ break;
371
+ }
372
+ // PRIVMSG — the main message handler
373
+ case 'PRIVMSG': {
374
+ if (params.length < 2)
375
+ break;
376
+ const channel = params[0];
377
+ const text = params.slice(1).join(' ').replace(/^:/, '');
378
+ const senderNick = extractNick(prefix);
379
+ // Ignore our own messages
380
+ if (senderNick === this.opts.nick)
381
+ break;
382
+ // Try to parse as JSON envelope
383
+ try {
384
+ const obj = JSON.parse(text);
385
+ if (isEnvelope(obj)) {
386
+ // Valid envelope — check recipient addressing
387
+ if (matchesRecipient(obj, this.opts.nick, this.agentType)) {
388
+ for (const handler of this.envelopeHandlers) {
389
+ handler(obj, channel);
390
+ }
391
+ }
392
+ break;
393
+ }
394
+ }
395
+ catch {
396
+ // Not JSON — fall through to human chat handling
397
+ }
398
+ // Non-JSON PRIVMSG: potential human instruction
399
+ this.handleHumanChat(senderNick, channel, text);
400
+ break;
401
+ }
402
+ // NOTICE — system/human commentary, silently ignored per protocol spec
403
+ case 'NOTICE':
404
+ break;
405
+ // Other numerics we can safely ignore
406
+ default:
407
+ break;
408
+ }
409
+ }
410
+ /**
411
+ * Handle non-JSON PRIVMSG as potential human instructions.
412
+ * Delivers to instruction handlers if:
413
+ * - Message mentions our nick
414
+ * - Sender is not a service bot
415
+ * - Sender is not an agent (claude-/codex-/gemini-/calliope- prefix)
416
+ */
417
+ handleHumanChat(senderNick, channel, text) {
418
+ if (this.instructionHandlers.length === 0)
419
+ return;
420
+ // Skip service bots
421
+ if (SERVICE_BOTS.has(senderNick))
422
+ return;
423
+ // Skip agent nicks
424
+ for (const prefix of AGENT_PREFIXES) {
425
+ if (senderNick.startsWith(prefix))
426
+ return;
427
+ }
428
+ // Must mention our nick (case-insensitive)
429
+ if (!text.toLowerCase().includes(this.opts.nick.toLowerCase()))
430
+ return;
431
+ for (const handler of this.instructionHandlers) {
432
+ handler(text, senderNick, channel);
433
+ }
434
+ }
435
+ // ── Private: sending ─────────────────────────────────────────────
436
+ sendRawLine(line) {
437
+ if (this.socket && !this.socket.destroyed) {
438
+ this.socket.write(line + '\r\n');
439
+ }
440
+ }
441
+ sendPrivmsg(channel, text) {
442
+ if (!this.connected || !this.socket)
443
+ return;
444
+ const channelName = channel.startsWith('#') ? channel : `#${channel}`;
445
+ // IRC PRIVMSG has a ~512 byte line limit, but modern servers (Ergo) allow more.
446
+ // Split on newlines to avoid sending multiline as one IRC message.
447
+ const lines = text.split('\n');
448
+ for (const line of lines) {
449
+ if (line.length > 0) {
450
+ this.sendRawLine(`PRIVMSG ${channelName} :${line}`);
451
+ }
452
+ }
453
+ }
454
+ // ── Private: keepalive ───────────────────────────────────────────
455
+ startPingKeepalive() {
456
+ this.stopPingKeepalive();
457
+ this.pingTimer = setInterval(() => {
458
+ if (!this.connected || this.pendingPing)
459
+ return;
460
+ this.pendingPing = true;
461
+ this.sendRawLine('PING :calliope');
462
+ // If no PONG arrives within PING_TIMEOUT_MS, declare the connection dead
463
+ this.pongTimer = setTimeout(() => {
464
+ this.pongTimer = null;
465
+ this.pendingPing = false;
466
+ this.connected = false;
467
+ this.cleanupSocket();
468
+ this.scheduleReconnect();
469
+ }, ScuttlebotIRCClient.PING_TIMEOUT_MS);
470
+ }, ScuttlebotIRCClient.PING_INTERVAL_MS);
471
+ }
472
+ stopPingKeepalive() {
473
+ if (this.pingTimer) {
474
+ clearInterval(this.pingTimer);
475
+ this.pingTimer = null;
476
+ }
477
+ if (this.pongTimer) {
478
+ clearTimeout(this.pongTimer);
479
+ this.pongTimer = null;
480
+ }
481
+ this.pendingPing = false;
482
+ }
483
+ /**
484
+ * Register SIGINT/SIGTERM handlers so we send QUIT before the process exits.
485
+ * Uses a synchronous write — the OS TCP stack will flush it even if the
486
+ * event loop drains immediately afterward.
487
+ */
488
+ registerExitHandler() {
489
+ this.unregisterExitHandler();
490
+ this.exitHandler = () => {
491
+ if (this.socket && !this.socket.destroyed) {
492
+ try {
493
+ this.socket.write('QUIT :Session ended\r\n');
494
+ }
495
+ catch { /* ignore */ }
496
+ try {
497
+ this.socket.destroy();
498
+ }
499
+ catch { /* ignore */ }
500
+ }
501
+ };
502
+ process.once('SIGINT', this.exitHandler);
503
+ process.once('SIGTERM', this.exitHandler);
504
+ }
505
+ unregisterExitHandler() {
506
+ if (this.exitHandler) {
507
+ process.off('SIGINT', this.exitHandler);
508
+ process.off('SIGTERM', this.exitHandler);
509
+ this.exitHandler = null;
510
+ }
511
+ }
512
+ // ── Private: reconnection ────────────────────────────────────────
513
+ scheduleReconnect() {
514
+ if (!this.shouldReconnect || this.destroyed)
515
+ return;
516
+ this.reconnectTimer = setTimeout(() => {
517
+ this.reconnectTimer = null;
518
+ if (!this.shouldReconnect || this.destroyed)
519
+ return;
520
+ this.buffer = '';
521
+ this.saslState = 'none';
522
+ this.createConnection();
523
+ }, this.reconnectDelay);
524
+ // Exponential backoff: 2s, 4s, 8s, 16s, 32s, 60s max
525
+ this.reconnectDelay = Math.min(this.reconnectDelay * 2, 60000);
526
+ }
527
+ cleanupSocket() {
528
+ if (this.socket) {
529
+ this.socket.removeAllListeners();
530
+ if (!this.socket.destroyed) {
531
+ this.socket.destroy();
532
+ }
533
+ this.socket = null;
534
+ }
535
+ this.connected = false;
536
+ }
537
+ }
538
+ // ── Helpers ────────────────────────────────────────────────────────
539
+ function parseHostPort(addr) {
540
+ const lastColon = addr.lastIndexOf(':');
541
+ if (lastColon === -1) {
542
+ return [addr, '6667'];
543
+ }
544
+ return [addr.slice(0, lastColon), addr.slice(lastColon + 1)];
545
+ }
546
+ /** Extract nick from an IRC prefix like "nick!user@host" or just "nick". */
547
+ function extractNick(prefix) {
548
+ const bang = prefix.indexOf('!');
549
+ return bang === -1 ? prefix : prefix.slice(0, bang);
550
+ }
551
+ /**
552
+ * Parse a single IRC protocol line into prefix, command, and params.
553
+ * Handles the :prefix, trailing :param, and standard space-separated params.
554
+ */
555
+ function parseIRCMessage(line) {
556
+ let idx = 0;
557
+ let prefix = '';
558
+ // Optional prefix
559
+ if (line[0] === ':') {
560
+ const spaceIdx = line.indexOf(' ', 1);
561
+ if (spaceIdx === -1)
562
+ return null;
563
+ prefix = line.slice(1, spaceIdx);
564
+ idx = spaceIdx + 1;
565
+ }
566
+ // Skip whitespace
567
+ while (idx < line.length && line[idx] === ' ')
568
+ idx++;
569
+ // Command
570
+ const cmdEnd = line.indexOf(' ', idx);
571
+ if (cmdEnd === -1) {
572
+ return { prefix, command: line.slice(idx).toUpperCase(), params: [] };
573
+ }
574
+ const command = line.slice(idx, cmdEnd).toUpperCase();
575
+ idx = cmdEnd + 1;
576
+ // Skip whitespace
577
+ while (idx < line.length && line[idx] === ' ')
578
+ idx++;
579
+ // Parameters
580
+ const params = [];
581
+ while (idx < line.length) {
582
+ if (line[idx] === ':') {
583
+ // Trailing parameter — rest of the line
584
+ params.push(line.slice(idx + 1));
585
+ break;
586
+ }
587
+ const nextSpace = line.indexOf(' ', idx);
588
+ if (nextSpace === -1) {
589
+ params.push(line.slice(idx));
590
+ break;
591
+ }
592
+ params.push(line.slice(idx, nextSpace));
593
+ idx = nextSpace + 1;
594
+ while (idx < line.length && line[idx] === ' ')
595
+ idx++;
596
+ }
597
+ return { prefix, command, params };
598
+ }
599
+ //# sourceMappingURL=irc-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"irc-client.js","sourceRoot":"","sources":["../../src/scuttlebot/irc-client.ts"],"names":[],"mappings":"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"}
package/dist/skills.d.ts CHANGED
@@ -28,6 +28,25 @@ export interface SkillReference {
28
28
  path: string;
29
29
  content?: string;
30
30
  }
31
+ /**
32
+ * Confirmation request shown to the user before a network skill is installed (#137).
33
+ */
34
+ export interface SkillInstallConfirmation {
35
+ name: string;
36
+ source: 'registry' | 'github';
37
+ sourceUrl: string;
38
+ description: string;
39
+ }
40
+ /**
41
+ * Reject skill names that could escape SKILLS_DIR via path traversal (#136).
42
+ * Mirrors the plugin loader guard in plugins.ts.
43
+ */
44
+ export declare function assertSafeSkillName(name: string): void;
45
+ /**
46
+ * Register a confirmation handler invoked before installing a network skill (#137).
47
+ * Returning false aborts the install. Pass null to clear.
48
+ */
49
+ export declare function setSkillInstallConfirmHandler(handler: ((info: SkillInstallConfirmation) => boolean | Promise<boolean>) | null): void;
31
50
  /**
32
51
  * Load a skill from a directory
33
52
  */
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACvE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsHD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAoB1D;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,KAAK,EAAE,CAenC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAWnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,EAAE,CAmBjE;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAmB3D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CA2C1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CA+ClF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAepD;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAezC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhE"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACvE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD;AAyBD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,wBAAwB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,GAC/E,IAAI,CAEN;AA8HD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAoB1D;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,KAAK,EAAE,CAqBnC;AAcD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAiBnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,EAAE,CAmBjE;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAqB3D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAqD1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAyDlF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAepD;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAezC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhE"}