@calliopelabs/cli 2.2.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 (244) 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/council-types.d.ts +2 -0
  8. package/dist/agents/council-types.d.ts.map +1 -1
  9. package/dist/agents/council-types.js.map +1 -1
  10. package/dist/agents/council.d.ts +5 -0
  11. package/dist/agents/council.d.ts.map +1 -1
  12. package/dist/agents/council.js +150 -14
  13. package/dist/agents/council.js.map +1 -1
  14. package/dist/agents/dynamic-tools.d.ts.map +1 -1
  15. package/dist/agents/dynamic-tools.js +39 -10
  16. package/dist/agents/dynamic-tools.js.map +1 -1
  17. package/dist/agents/orchestrator.d.ts +7 -0
  18. package/dist/agents/orchestrator.d.ts.map +1 -1
  19. package/dist/agents/orchestrator.js +48 -7
  20. package/dist/agents/orchestrator.js.map +1 -1
  21. package/dist/agents/sdk-backend.js +1 -1
  22. package/dist/agents/sdk-backend.js.map +1 -1
  23. package/dist/agents/swarm-types.d.ts +1 -0
  24. package/dist/agents/swarm-types.d.ts.map +1 -1
  25. package/dist/agents/swarm.d.ts +5 -0
  26. package/dist/agents/swarm.d.ts.map +1 -1
  27. package/dist/agents/swarm.js +85 -17
  28. package/dist/agents/swarm.js.map +1 -1
  29. package/dist/agents/types.d.ts +1 -0
  30. package/dist/agents/types.d.ts.map +1 -1
  31. package/dist/agents/types.js.map +1 -1
  32. package/dist/api-server.d.ts +9 -0
  33. package/dist/api-server.d.ts.map +1 -1
  34. package/dist/api-server.js +75 -4
  35. package/dist/api-server.js.map +1 -1
  36. package/dist/auto-checkpoint.d.ts.map +1 -1
  37. package/dist/auto-checkpoint.js +50 -17
  38. package/dist/auto-checkpoint.js.map +1 -1
  39. package/dist/auto-compressor.d.ts +14 -0
  40. package/dist/auto-compressor.d.ts.map +1 -1
  41. package/dist/auto-compressor.js +67 -10
  42. package/dist/auto-compressor.js.map +1 -1
  43. package/dist/background-jobs.d.ts.map +1 -1
  44. package/dist/background-jobs.js +8 -3
  45. package/dist/background-jobs.js.map +1 -1
  46. package/dist/bin.d.ts +8 -0
  47. package/dist/bin.d.ts.map +1 -1
  48. package/dist/bin.js +63 -4
  49. package/dist/bin.js.map +1 -1
  50. package/dist/branching.d.ts.map +1 -1
  51. package/dist/branching.js +14 -1
  52. package/dist/branching.js.map +1 -1
  53. package/dist/checkpoint.d.ts.map +1 -1
  54. package/dist/checkpoint.js +13 -1
  55. package/dist/checkpoint.js.map +1 -1
  56. package/dist/cli/agent.d.ts.map +1 -1
  57. package/dist/cli/agent.js +130 -62
  58. package/dist/cli/agent.js.map +1 -1
  59. package/dist/cli/commands.d.ts.map +1 -1
  60. package/dist/cli/commands.js +218 -11
  61. package/dist/cli/commands.js.map +1 -1
  62. package/dist/cli/index.d.ts.map +1 -1
  63. package/dist/cli/index.js +55 -6
  64. package/dist/cli/index.js.map +1 -1
  65. package/dist/cli/types.d.ts +3 -0
  66. package/dist/cli/types.d.ts.map +1 -1
  67. package/dist/cli/types.js +2 -1
  68. package/dist/cli/types.js.map +1 -1
  69. package/dist/config.d.ts +1 -0
  70. package/dist/config.d.ts.map +1 -1
  71. package/dist/config.js +15 -3
  72. package/dist/config.js.map +1 -1
  73. package/dist/diff.d.ts.map +1 -1
  74. package/dist/diff.js +42 -4
  75. package/dist/diff.js.map +1 -1
  76. package/dist/env-expansion.d.ts +15 -0
  77. package/dist/env-expansion.d.ts.map +1 -0
  78. package/dist/env-expansion.js +43 -0
  79. package/dist/env-expansion.js.map +1 -0
  80. package/dist/errors.d.ts.map +1 -1
  81. package/dist/errors.js +30 -3
  82. package/dist/errors.js.map +1 -1
  83. package/dist/headless.d.ts.map +1 -1
  84. package/dist/headless.js +59 -4
  85. package/dist/headless.js.map +1 -1
  86. package/dist/hooks.d.ts +8 -2
  87. package/dist/hooks.d.ts.map +1 -1
  88. package/dist/hooks.js +97 -11
  89. package/dist/hooks.js.map +1 -1
  90. package/dist/idle-eviction.d.ts.map +1 -1
  91. package/dist/idle-eviction.js +8 -1
  92. package/dist/idle-eviction.js.map +1 -1
  93. package/dist/iteration-ledger.d.ts +111 -2
  94. package/dist/iteration-ledger.d.ts.map +1 -1
  95. package/dist/iteration-ledger.js +327 -19
  96. package/dist/iteration-ledger.js.map +1 -1
  97. package/dist/iteration-limit.d.ts +5 -0
  98. package/dist/iteration-limit.d.ts.map +1 -0
  99. package/dist/iteration-limit.js +17 -0
  100. package/dist/iteration-limit.js.map +1 -0
  101. package/dist/markdown.d.ts.map +1 -1
  102. package/dist/markdown.js +32 -10
  103. package/dist/markdown.js.map +1 -1
  104. package/dist/mcp.d.ts +35 -5
  105. package/dist/mcp.d.ts.map +1 -1
  106. package/dist/mcp.js +191 -12
  107. package/dist/mcp.js.map +1 -1
  108. package/dist/memory.d.ts.map +1 -1
  109. package/dist/memory.js +4 -9
  110. package/dist/memory.js.map +1 -1
  111. package/dist/model-detection.d.ts +14 -1
  112. package/dist/model-detection.d.ts.map +1 -1
  113. package/dist/model-detection.js +307 -114
  114. package/dist/model-detection.js.map +1 -1
  115. package/dist/model-router.js +7 -7
  116. package/dist/model-router.js.map +1 -1
  117. package/dist/parallel-tools.d.ts +9 -1
  118. package/dist/parallel-tools.d.ts.map +1 -1
  119. package/dist/parallel-tools.js +6 -5
  120. package/dist/parallel-tools.js.map +1 -1
  121. package/dist/plugins.d.ts +37 -0
  122. package/dist/plugins.d.ts.map +1 -1
  123. package/dist/plugins.js +87 -0
  124. package/dist/plugins.js.map +1 -1
  125. package/dist/prevent-sleep.d.ts +10 -0
  126. package/dist/prevent-sleep.d.ts.map +1 -0
  127. package/dist/prevent-sleep.js +85 -0
  128. package/dist/prevent-sleep.js.map +1 -0
  129. package/dist/providers/anthropic.d.ts.map +1 -1
  130. package/dist/providers/anthropic.js +36 -2
  131. package/dist/providers/anthropic.js.map +1 -1
  132. package/dist/providers/bedrock.d.ts.map +1 -1
  133. package/dist/providers/bedrock.js +81 -17
  134. package/dist/providers/bedrock.js.map +1 -1
  135. package/dist/providers/compat.d.ts.map +1 -1
  136. package/dist/providers/compat.js +21 -6
  137. package/dist/providers/compat.js.map +1 -1
  138. package/dist/providers/index.d.ts.map +1 -1
  139. package/dist/providers/index.js +2 -0
  140. package/dist/providers/index.js.map +1 -1
  141. package/dist/providers/openai-compat-shims.d.ts +31 -0
  142. package/dist/providers/openai-compat-shims.d.ts.map +1 -0
  143. package/dist/providers/openai-compat-shims.js +179 -0
  144. package/dist/providers/openai-compat-shims.js.map +1 -0
  145. package/dist/providers/openai.d.ts.map +1 -1
  146. package/dist/providers/types.d.ts.map +1 -1
  147. package/dist/providers/types.js +19 -10
  148. package/dist/providers/types.js.map +1 -1
  149. package/dist/risk.d.ts.map +1 -1
  150. package/dist/risk.js +15 -5
  151. package/dist/risk.js.map +1 -1
  152. package/dist/sandbox-native.d.ts +1 -0
  153. package/dist/sandbox-native.d.ts.map +1 -1
  154. package/dist/sandbox-native.js +37 -5
  155. package/dist/sandbox-native.js.map +1 -1
  156. package/dist/scope.d.ts +10 -0
  157. package/dist/scope.d.ts.map +1 -1
  158. package/dist/scope.js +75 -15
  159. package/dist/scope.js.map +1 -1
  160. package/dist/scuttlebot/client.d.ts +83 -0
  161. package/dist/scuttlebot/client.d.ts.map +1 -0
  162. package/dist/scuttlebot/client.js +350 -0
  163. package/dist/scuttlebot/client.js.map +1 -0
  164. package/dist/scuttlebot/config.d.ts +28 -0
  165. package/dist/scuttlebot/config.d.ts.map +1 -0
  166. package/dist/scuttlebot/config.js +91 -0
  167. package/dist/scuttlebot/config.js.map +1 -0
  168. package/dist/scuttlebot/http-client.d.ts +63 -0
  169. package/dist/scuttlebot/http-client.d.ts.map +1 -0
  170. package/dist/scuttlebot/http-client.js +124 -0
  171. package/dist/scuttlebot/http-client.js.map +1 -0
  172. package/dist/scuttlebot/index.d.ts +13 -0
  173. package/dist/scuttlebot/index.d.ts.map +1 -0
  174. package/dist/scuttlebot/index.js +10 -0
  175. package/dist/scuttlebot/index.js.map +1 -0
  176. package/dist/scuttlebot/irc-client.d.ts +124 -0
  177. package/dist/scuttlebot/irc-client.d.ts.map +1 -0
  178. package/dist/scuttlebot/irc-client.js +599 -0
  179. package/dist/scuttlebot/irc-client.js.map +1 -0
  180. package/dist/skills.d.ts +19 -0
  181. package/dist/skills.d.ts.map +1 -1
  182. package/dist/skills.js +98 -10
  183. package/dist/skills.js.map +1 -1
  184. package/dist/smart-router.js +4 -4
  185. package/dist/smart-router.js.map +1 -1
  186. package/dist/storage.d.ts +18 -3
  187. package/dist/storage.d.ts.map +1 -1
  188. package/dist/storage.js +182 -14
  189. package/dist/storage.js.map +1 -1
  190. package/dist/tools.d.ts.map +1 -1
  191. package/dist/tools.js +233 -39
  192. package/dist/tools.js.map +1 -1
  193. package/dist/trust.d.ts +16 -3
  194. package/dist/trust.d.ts.map +1 -1
  195. package/dist/trust.js +23 -4
  196. package/dist/trust.js.map +1 -1
  197. package/dist/types.d.ts.map +1 -1
  198. package/dist/types.js +18 -12
  199. package/dist/types.js.map +1 -1
  200. package/dist/ui/agent.d.ts +1 -1
  201. package/dist/ui/agent.d.ts.map +1 -1
  202. package/dist/ui/agent.js +175 -121
  203. package/dist/ui/agent.js.map +1 -1
  204. package/dist/ui/chat-input.d.ts +3 -1
  205. package/dist/ui/chat-input.d.ts.map +1 -1
  206. package/dist/ui/chat-input.js +82 -17
  207. package/dist/ui/chat-input.js.map +1 -1
  208. package/dist/ui/commands.d.ts +4 -0
  209. package/dist/ui/commands.d.ts.map +1 -1
  210. package/dist/ui/commands.js +562 -39
  211. package/dist/ui/commands.js.map +1 -1
  212. package/dist/ui/completions.d.ts.map +1 -1
  213. package/dist/ui/completions.js +2 -0
  214. package/dist/ui/completions.js.map +1 -1
  215. package/dist/ui/index.d.ts.map +1 -1
  216. package/dist/ui/index.js +288 -60
  217. package/dist/ui/index.js.map +1 -1
  218. package/dist/ui/input-utils.d.ts +20 -0
  219. package/dist/ui/input-utils.d.ts.map +1 -0
  220. package/dist/ui/input-utils.js +35 -0
  221. package/dist/ui/input-utils.js.map +1 -0
  222. package/dist/ui/messages.d.ts +6 -2
  223. package/dist/ui/messages.d.ts.map +1 -1
  224. package/dist/ui/messages.js +42 -11
  225. package/dist/ui/messages.js.map +1 -1
  226. package/dist/ui/modals.d.ts +21 -1
  227. package/dist/ui/modals.d.ts.map +1 -1
  228. package/dist/ui/modals.js +67 -5
  229. package/dist/ui/modals.js.map +1 -1
  230. package/dist/ui/status-bar.d.ts +4 -1
  231. package/dist/ui/status-bar.d.ts.map +1 -1
  232. package/dist/ui/status-bar.js +12 -1
  233. package/dist/ui/status-bar.js.map +1 -1
  234. package/dist/ui/types.d.ts +3 -0
  235. package/dist/ui/types.d.ts.map +1 -1
  236. package/package.json +4 -7
  237. package/dist/completion.d.ts +0 -75
  238. package/dist/completion.d.ts.map +0 -1
  239. package/dist/completion.js +0 -234
  240. package/dist/completion.js.map +0 -1
  241. package/dist/keyboard.d.ts +0 -57
  242. package/dist/keyboard.d.ts.map +0 -1
  243. package/dist/keyboard.js +0 -265
  244. 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"}