@visorcraft/idlehands 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/agent/prompt-builder.js +188 -0
  2. package/dist/agent/prompt-builder.js.map +1 -0
  3. package/dist/agent/query-classifier.js +72 -0
  4. package/dist/agent/query-classifier.js.map +1 -0
  5. package/dist/agent/resilient-provider.js +170 -0
  6. package/dist/agent/resilient-provider.js.map +1 -0
  7. package/dist/agent/response-cache.js +124 -0
  8. package/dist/agent/response-cache.js.map +1 -0
  9. package/dist/agent/semantic-search.js +138 -0
  10. package/dist/agent/semantic-search.js.map +1 -0
  11. package/dist/agent/tool-calls.js +261 -1
  12. package/dist/agent/tool-calls.js.map +1 -1
  13. package/dist/agent/tool-name-alias.js +140 -0
  14. package/dist/agent/tool-name-alias.js.map +1 -0
  15. package/dist/agent.js +146 -43
  16. package/dist/agent.js.map +1 -1
  17. package/dist/anton/controller.js +442 -186
  18. package/dist/anton/controller.js.map +1 -1
  19. package/dist/anton/preflight.js +89 -28
  20. package/dist/anton/preflight.js.map +1 -1
  21. package/dist/anton/prompt.js +20 -0
  22. package/dist/anton/prompt.js.map +1 -1
  23. package/dist/anton/reporter.js +6 -1
  24. package/dist/anton/reporter.js.map +1 -1
  25. package/dist/bot/discord-commands.js +25 -0
  26. package/dist/bot/discord-commands.js.map +1 -1
  27. package/dist/bot/discord.js +15 -0
  28. package/dist/bot/discord.js.map +1 -1
  29. package/dist/bot/telegram-commands.js +21 -0
  30. package/dist/bot/telegram-commands.js.map +1 -1
  31. package/dist/bot/telegram.js +1 -0
  32. package/dist/bot/telegram.js.map +1 -1
  33. package/dist/bot/upgrade-command.js +398 -0
  34. package/dist/bot/upgrade-command.js.map +1 -0
  35. package/dist/bot/ux/discord-renderer.js +5 -21
  36. package/dist/bot/ux/discord-renderer.js.map +1 -1
  37. package/dist/bot/ux/emitter.js +104 -0
  38. package/dist/bot/ux/emitter.js.map +1 -0
  39. package/dist/bot/ux/shared-formatter.js +43 -0
  40. package/dist/bot/ux/shared-formatter.js.map +1 -0
  41. package/dist/bot/ux/telegram-renderer.js +5 -21
  42. package/dist/bot/ux/telegram-renderer.js.map +1 -1
  43. package/dist/cli/commands/upgrade.js +27 -0
  44. package/dist/cli/commands/upgrade.js.map +1 -0
  45. package/dist/client.js +51 -7
  46. package/dist/client.js.map +1 -1
  47. package/dist/harnesses.js +2 -0
  48. package/dist/harnesses.js.map +1 -1
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/model-customization.js +3 -1
  52. package/dist/model-customization.js.map +1 -1
  53. package/dist/security/leak-detector.js +109 -0
  54. package/dist/security/leak-detector.js.map +1 -0
  55. package/dist/security/prompt-guard.js +120 -0
  56. package/dist/security/prompt-guard.js.map +1 -0
  57. package/dist/tui/command-handler.js +2 -0
  58. package/dist/tui/command-handler.js.map +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,398 @@
1
+ /**
2
+ * Bot /upgrade command — self-upgrade and restart service.
3
+ *
4
+ * Provides same functionality as `idlehands upgrade` CLI but with
5
+ * user feedback and automatic service restart for bots.
6
+ */
7
+ import { execFileSync, execSync, spawn } from 'node:child_process';
8
+ import { accessSync, constants as fsConstants, readFileSync } from 'node:fs';
9
+ import fs from 'node:fs/promises';
10
+ import os from 'node:os';
11
+ import path from 'node:path';
12
+ import { fetchWithTimeout as fetchWithTimeoutStrict, stateDir, PKG_VERSION } from '../utils.js';
13
+ const NPM_SCOPED_PACKAGE = '@visorcraft/idlehands';
14
+ const GITHUB_OWNER = 'visorcraft';
15
+ const GITHUB_REPO = 'idlehands';
16
+ const STATE_DIR = stateDir();
17
+ const ROLLBACK_DIR = path.join(STATE_DIR, 'rollback');
18
+ // ─── Helpers ────────────────────────────────────────────────────────────────
19
+ function isUsableCommand(cmd) {
20
+ try {
21
+ execFileSync(cmd, ['--version'], { stdio: 'ignore', timeout: 5000 });
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ function resolveInstallPaths() {
29
+ try {
30
+ const binPath = execSync('command -v idlehands 2>/dev/null || echo ""', {
31
+ encoding: 'utf8',
32
+ }).trim();
33
+ if (!binPath)
34
+ return null;
35
+ const prefix = path.resolve(path.dirname(binPath), '..');
36
+ const installDir = path.join(prefix, 'lib', 'node_modules', NPM_SCOPED_PACKAGE);
37
+ const npmByPrefix = path.join(prefix, 'bin', 'npm');
38
+ const npmByNodeDir = path.join(path.dirname(process.execPath), 'npm');
39
+ const npmBin = isUsableCommand(npmByPrefix)
40
+ ? npmByPrefix
41
+ : isUsableCommand(npmByNodeDir)
42
+ ? npmByNodeDir
43
+ : 'npm';
44
+ return { binPath, prefix, installDir, npmBin };
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ function needsElevation(prefix) {
51
+ if (process.getuid?.() === 0)
52
+ return false;
53
+ try {
54
+ const target = path.join(prefix, 'lib', 'node_modules');
55
+ accessSync(target, fsConstants.W_OK);
56
+ return false;
57
+ }
58
+ catch {
59
+ return true;
60
+ }
61
+ }
62
+ function hasSudo() {
63
+ try {
64
+ execFileSync('which', ['sudo'], { stdio: 'ignore', timeout: 3000 });
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ async function fetchWithTimeout(url, init, timeoutMs) {
72
+ try {
73
+ return await fetchWithTimeoutStrict(url, init, timeoutMs);
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ function compareSemver(a, b) {
80
+ const pa = a.replace(/^v/, '').split('.').map(Number);
81
+ const pb = b.replace(/^v/, '').split('.').map(Number);
82
+ for (let i = 0; i < 3; i++) {
83
+ const va = pa[i] ?? 0;
84
+ const vb = pb[i] ?? 0;
85
+ if (va < vb)
86
+ return -1;
87
+ if (va > vb)
88
+ return 1;
89
+ }
90
+ return 0;
91
+ }
92
+ function detectInstallSource() {
93
+ const target = resolveInstallPaths();
94
+ if (!target)
95
+ return 'unknown';
96
+ if (target.installDir.includes('node_modules'))
97
+ return 'npm';
98
+ return 'github';
99
+ }
100
+ function resolveGitHubToken() {
101
+ const envToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
102
+ if (envToken)
103
+ return envToken;
104
+ try {
105
+ const ghConfigPath = path.join(os.homedir(), '.config', 'gh', 'hosts.yml');
106
+ const raw = readFileSync(ghConfigPath, 'utf8');
107
+ const lines = raw.split('\n');
108
+ let inGithub = false;
109
+ for (const line of lines) {
110
+ if (line.match(/^github\.com:/)) {
111
+ inGithub = true;
112
+ continue;
113
+ }
114
+ if (inGithub && line.match(/^\S/))
115
+ break;
116
+ if (inGithub) {
117
+ const m = line.match(/oauth_token:\s*(.+)/);
118
+ if (m)
119
+ return m[1].trim();
120
+ }
121
+ }
122
+ }
123
+ catch { }
124
+ return null;
125
+ }
126
+ async function getLatestNpm(timeoutMs = 5000) {
127
+ try {
128
+ const pkg = encodeURIComponent(NPM_SCOPED_PACKAGE);
129
+ const res = await fetchWithTimeout(`https://registry.npmjs.org/${pkg}/latest`, {
130
+ headers: { Accept: 'application/json', 'User-Agent': 'idlehands-bot' },
131
+ }, timeoutMs);
132
+ if (!res || !res.ok)
133
+ return null;
134
+ const data = (await res.json());
135
+ return data?.version ?? null;
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ }
141
+ async function getLatestGitHub(timeoutMs = 5000) {
142
+ try {
143
+ const url = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases/latest`;
144
+ const headers = {
145
+ Accept: 'application/vnd.github+json',
146
+ 'User-Agent': 'idlehands-bot',
147
+ };
148
+ const token = resolveGitHubToken();
149
+ if (token)
150
+ headers['Authorization'] = `token ${token}`;
151
+ const res = await fetchWithTimeout(url, { headers }, timeoutMs);
152
+ if (!res || !res.ok)
153
+ return null;
154
+ const data = (await res.json());
155
+ return data?.tag_name?.replace(/^v/, '') ?? null;
156
+ }
157
+ catch {
158
+ return null;
159
+ }
160
+ }
161
+ async function checkForUpdate(source) {
162
+ const currentVersion = PKG_VERSION;
163
+ let latest = null;
164
+ let finalSource = source;
165
+ if (source === 'npm') {
166
+ latest = await getLatestNpm();
167
+ if (!latest) {
168
+ latest = await getLatestGitHub();
169
+ if (latest)
170
+ finalSource = 'github';
171
+ }
172
+ }
173
+ else {
174
+ latest = await getLatestGitHub();
175
+ if (!latest) {
176
+ latest = await getLatestNpm();
177
+ if (latest)
178
+ finalSource = 'npm';
179
+ }
180
+ }
181
+ if (!latest)
182
+ return null;
183
+ return {
184
+ current: currentVersion,
185
+ latest,
186
+ source: finalSource,
187
+ updateAvailable: compareSemver(currentVersion, latest) < 0,
188
+ };
189
+ }
190
+ function npmInstallGlobal(spec, onProgress) {
191
+ const target = resolveInstallPaths();
192
+ if (target) {
193
+ const args = ['install', '-g', '--prefix', target.prefix, spec];
194
+ const env = { ...process.env, npm_config_prefix: target.prefix };
195
+ if (needsElevation(target.prefix)) {
196
+ if (!hasSudo()) {
197
+ throw new Error(`Permission denied: ${target.prefix} requires elevated permissions.`);
198
+ }
199
+ execFileSync('sudo', [target.npmBin, ...args], {
200
+ stdio: 'pipe',
201
+ timeout: 120_000,
202
+ env,
203
+ });
204
+ return;
205
+ }
206
+ execFileSync(target.npmBin, args, {
207
+ stdio: 'pipe',
208
+ timeout: 120_000,
209
+ env,
210
+ });
211
+ return;
212
+ }
213
+ execFileSync('npm', ['install', '-g', spec], { stdio: 'pipe', timeout: 120_000 });
214
+ }
215
+ async function backupForRollback(currentVersion) {
216
+ try {
217
+ const installDir = resolveInstallPaths()?.installDir;
218
+ if (!installDir)
219
+ return false;
220
+ try {
221
+ await fs.access(installDir);
222
+ }
223
+ catch {
224
+ return false;
225
+ }
226
+ await fs.rm(ROLLBACK_DIR, { recursive: true, force: true });
227
+ await fs.mkdir(ROLLBACK_DIR, { recursive: true });
228
+ execSync(`npm pack --pack-destination "${ROLLBACK_DIR}" 2>/dev/null`, {
229
+ cwd: installDir,
230
+ encoding: 'utf8',
231
+ timeout: 30_000,
232
+ });
233
+ return true;
234
+ }
235
+ catch {
236
+ return false;
237
+ }
238
+ }
239
+ // ─── Service Restart ────────────────────────────────────────────────────────
240
+ function detectServiceManager() {
241
+ // Check for systemd user service
242
+ try {
243
+ const result = execSync('systemctl --user is-active idlehands-bot 2>/dev/null || true', {
244
+ encoding: 'utf8',
245
+ timeout: 5000,
246
+ }).trim();
247
+ if (result === 'active' || result === 'inactive') {
248
+ return 'systemd-user';
249
+ }
250
+ }
251
+ catch { }
252
+ // Check for system service
253
+ try {
254
+ const result = execSync('systemctl is-active idlehands-bot 2>/dev/null || true', {
255
+ encoding: 'utf8',
256
+ timeout: 5000,
257
+ }).trim();
258
+ if (result === 'active' || result === 'inactive') {
259
+ return 'systemd-system';
260
+ }
261
+ }
262
+ catch { }
263
+ return 'none';
264
+ }
265
+ function scheduleServiceRestart(serviceManager) {
266
+ // Schedule restart in background after a short delay to allow response to be sent
267
+ const restartCmd = serviceManager === 'systemd-user'
268
+ ? 'sleep 2 && systemctl --user restart idlehands-bot'
269
+ : 'sleep 2 && sudo systemctl restart idlehands-bot';
270
+ spawn('bash', ['-c', restartCmd], {
271
+ detached: true,
272
+ stdio: 'ignore',
273
+ }).unref();
274
+ }
275
+ // ─── Main Upgrade Function ──────────────────────────────────────────────────
276
+ /**
277
+ * Perform the upgrade with progress callbacks for bot feedback.
278
+ */
279
+ export async function performBotUpgrade(onProgress) {
280
+ const currentVersion = PKG_VERSION;
281
+ const source = detectInstallSource();
282
+ await onProgress(`🔍 Current version: **v${currentVersion}**`);
283
+ await onProgress(`📦 Install source: ${source}`);
284
+ await onProgress('🔄 Checking for updates...');
285
+ const info = await checkForUpdate(source);
286
+ if (!info) {
287
+ return {
288
+ success: false,
289
+ message: '❌ Could not check for updates. Network issue or no releases published.',
290
+ fromVersion: currentVersion,
291
+ };
292
+ }
293
+ if (!info.updateAvailable) {
294
+ return {
295
+ success: true,
296
+ message: `✅ Already on the latest version (**v${currentVersion}**).`,
297
+ fromVersion: currentVersion,
298
+ toVersion: currentVersion,
299
+ needsRestart: false,
300
+ };
301
+ }
302
+ await onProgress(`📥 Update available: **v${info.current}** → **v${info.latest}** (from ${info.source})`);
303
+ await onProgress('💾 Creating backup for rollback...');
304
+ const backed = await backupForRollback(currentVersion);
305
+ if (backed) {
306
+ await onProgress('✅ Backup created');
307
+ }
308
+ else {
309
+ await onProgress('⚠️ Backup skipped (non-fatal)');
310
+ }
311
+ await onProgress('⬇️ Downloading and installing update...');
312
+ try {
313
+ if (info.source === 'npm') {
314
+ npmInstallGlobal(`${NPM_SCOPED_PACKAGE}@latest`);
315
+ }
316
+ else {
317
+ // GitHub release download
318
+ const token = resolveGitHubToken();
319
+ const releaseUrl = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases/tags/v${info.latest}`;
320
+ const headers = {
321
+ Accept: 'application/vnd.github+json',
322
+ 'User-Agent': 'idlehands-bot',
323
+ };
324
+ if (token)
325
+ headers['Authorization'] = `token ${token}`;
326
+ const releaseRes = await fetch(releaseUrl, { headers });
327
+ if (!releaseRes.ok) {
328
+ throw new Error(`Failed to fetch release v${info.latest}`);
329
+ }
330
+ const releaseData = (await releaseRes.json());
331
+ const tgzName = `idlehands-${info.latest}.tgz`;
332
+ const asset = (releaseData.assets ?? []).find((a) => a.name === tgzName);
333
+ if (!asset)
334
+ throw new Error(`Release has no asset named ${tgzName}`);
335
+ await onProgress(`📦 Downloading ${tgzName}...`);
336
+ const dlHeaders = {
337
+ Accept: 'application/octet-stream',
338
+ 'User-Agent': 'idlehands-bot',
339
+ };
340
+ if (token)
341
+ dlHeaders['Authorization'] = `token ${token}`;
342
+ const dlRes = await fetch(asset.url, { headers: dlHeaders });
343
+ if (!dlRes.ok)
344
+ throw new Error('Failed to download asset');
345
+ const tmpPath = path.join(os.tmpdir(), tgzName);
346
+ const buf = Buffer.from(await dlRes.arrayBuffer());
347
+ await fs.writeFile(tmpPath, buf);
348
+ npmInstallGlobal(tmpPath);
349
+ await fs.unlink(tmpPath).catch(() => { });
350
+ }
351
+ await onProgress(`✅ Upgraded to **v${info.latest}**`);
352
+ // Detect and schedule service restart
353
+ const serviceManager = detectServiceManager();
354
+ if (serviceManager !== 'none') {
355
+ await onProgress(`🔄 Scheduling service restart (${serviceManager})...`);
356
+ scheduleServiceRestart(serviceManager);
357
+ return {
358
+ success: true,
359
+ message: `✅ Upgraded from **v${info.current}** to **v${info.latest}**\n🔄 Service restarting in 2 seconds...`,
360
+ fromVersion: info.current,
361
+ toVersion: info.latest,
362
+ needsRestart: true,
363
+ };
364
+ }
365
+ return {
366
+ success: true,
367
+ message: `✅ Upgraded from **v${info.current}** to **v${info.latest}**\n⚠️ No service manager detected. Please restart manually.`,
368
+ fromVersion: info.current,
369
+ toVersion: info.latest,
370
+ needsRestart: true,
371
+ };
372
+ }
373
+ catch (e) {
374
+ return {
375
+ success: false,
376
+ message: `❌ Upgrade failed: ${e?.message ?? String(e)}`,
377
+ fromVersion: currentVersion,
378
+ error: e?.message ?? String(e),
379
+ };
380
+ }
381
+ }
382
+ /**
383
+ * Check for available updates without performing upgrade.
384
+ */
385
+ export async function checkBotUpdate() {
386
+ const source = detectInstallSource();
387
+ const info = await checkForUpdate(source);
388
+ if (!info) {
389
+ return { available: false, current: PKG_VERSION };
390
+ }
391
+ return {
392
+ available: info.updateAvailable,
393
+ current: info.current,
394
+ latest: info.latest,
395
+ source: info.source,
396
+ };
397
+ }
398
+ //# sourceMappingURL=upgrade-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-command.js","sourceRoot":"","sources":["../../src/bot/upgrade-command.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  * Discord Markdown format, respecting Discord's message limits and formatting.
6
6
  */
7
7
  import { blocksToPlainText } from './renderer.js';
8
+ import { truncateBlocks } from './shared-formatter.js';
8
9
  /**
9
10
  * Discord message length limit (recommended: 1900, hard limit: 2000).
10
11
  */
@@ -83,27 +84,10 @@ function blockToDiscordMarkdown(block, opts) {
83
84
  * Truncates content if necessary and adds ellipsis.
84
85
  */
85
86
  export function renderDiscordMarkdown(blocks, opts) {
86
- const maxLen = Math.max(256, Math.floor(opts?.maxLen ?? DISCORD_MAX_LEN));
87
- const parts = [];
88
- let used = 0;
89
- let truncated = false;
90
- for (const block of blocks) {
91
- const piece = blockToDiscordMarkdown(block, opts);
92
- const sep = parts.length ? '\n\n' : '';
93
- const add = sep + piece;
94
- if (used + add.length > maxLen) {
95
- truncated = true;
96
- break;
97
- }
98
- parts.push(add);
99
- used += add.length;
100
- }
101
- let out = parts.join('');
102
- if (truncated && out.length + 2 <= maxLen)
103
- out += '\n…';
104
- if (!out.trim())
105
- out = '⏳ Thinking...';
106
- return out;
87
+ return truncateBlocks(blocks, blockToDiscordMarkdown, {
88
+ maxLen: opts?.maxLen ?? DISCORD_MAX_LEN,
89
+ fallback: '⏳ Thinking...',
90
+ });
107
91
  }
108
92
  /**
109
93
  * Fallback: render blocks to plain text for very long messages.
@@ -1 +1 @@
1
- {"version":3,"file":"discord-renderer.js","sourceRoot":"","sources":["../../../src/bot/ux/discord-renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discord-renderer.js","sourceRoot":"","sources":["../../../src/bot/ux/discord-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Shared UX event emitter for IdleHands bots.
3
+ *
4
+ * This module provides a unified event emitter that both Telegram and Discord
5
+ * bots use to emit identical semantic events for the same workflow stages.
6
+ * This ensures consistent event semantics across all platforms.
7
+ */
8
+ import { createACKEvent, createPROGRESSEvent, createWARNINGEvent, createERROREvent, createRESULTEvent, createACTIONSEvent } from './events.js';
9
+ /**
10
+ * Create a new event emitter state.
11
+ */
12
+ export function createUXEventEmitterState(sessionId, userId, opts) {
13
+ return {
14
+ sessionId,
15
+ userId,
16
+ sequence: 0,
17
+ buffer: [],
18
+ maxBuffer: opts?.maxBuffer,
19
+ listeners: [],
20
+ };
21
+ }
22
+ /**
23
+ * Emit an event to all listeners.
24
+ */
25
+ export function emit(state, event) {
26
+ // Update sequence number
27
+ state.sequence = event.sequence ?? state.sequence + 1;
28
+ event.sequence = state.sequence;
29
+ event.sessionId = state.sessionId;
30
+ event.userId = state.userId;
31
+ // Add to buffer
32
+ state.buffer.push(event);
33
+ if (state.maxBuffer && state.buffer.length > state.maxBuffer) {
34
+ state.buffer.shift();
35
+ }
36
+ // Notify listeners
37
+ for (const listener of state.listeners) {
38
+ void listener(event);
39
+ }
40
+ }
41
+ /**
42
+ * Add an event listener.
43
+ */
44
+ export function on(state, listener) {
45
+ state.listeners.push(listener);
46
+ return () => {
47
+ state.listeners = state.listeners.filter((l) => l !== listener);
48
+ };
49
+ }
50
+ /**
51
+ * Emit an ACK event.
52
+ */
53
+ export function emitACK(state, message, opts) {
54
+ const event = createACKEvent(state.sessionId, state.userId, state.sequence + 1, message, opts);
55
+ emit(state, event);
56
+ }
57
+ /**
58
+ * Emit a PROGRESS event.
59
+ */
60
+ export function emitPROGRESS(state, message, progress, opts) {
61
+ const event = createPROGRESSEvent(state.sessionId, state.userId, state.sequence + 1, message, { ...opts, progress });
62
+ emit(state, event);
63
+ }
64
+ /**
65
+ * Emit a WARNING event.
66
+ */
67
+ export function emitWARNING(state, message, opts) {
68
+ const event = createWARNINGEvent(state.sessionId, state.userId, state.sequence + 1, message, opts);
69
+ emit(state, event);
70
+ }
71
+ /**
72
+ * Emit an ERROR event.
73
+ */
74
+ export function emitERROR(state, message, opts) {
75
+ const event = createERROREvent(state.sessionId, state.userId, state.sequence + 1, message, opts);
76
+ emit(state, event);
77
+ }
78
+ /**
79
+ * Emit a RESULT event.
80
+ */
81
+ export function emitRESULT(state, summary, opts) {
82
+ const event = createRESULTEvent(state.sessionId, state.userId, state.sequence + 1, summary, opts);
83
+ emit(state, event);
84
+ }
85
+ /**
86
+ * Emit an ACTIONS event.
87
+ */
88
+ export function emitACTIONS(state, actions, opts) {
89
+ const event = createACTIONSEvent(state.sessionId, state.userId, state.sequence + 1, actions, opts);
90
+ emit(state, event);
91
+ }
92
+ /**
93
+ * Get the last N events from the buffer.
94
+ */
95
+ export function getRecentEvents(state, count = 10) {
96
+ return state.buffer.slice(-count);
97
+ }
98
+ /**
99
+ * Clear the event buffer.
100
+ */
101
+ export function clearBuffer(state) {
102
+ state.buffer = [];
103
+ }
104
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../../src/bot/ux/emitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Shared formatter utilities for platform-specific renderers.
3
+ *
4
+ * Provides common truncation logic to prevent duplication across platforms
5
+ * (Discord, Telegram, etc.) while allowing platform-specific formatting.
6
+ */
7
+ /**
8
+ * Truncates formatted content from UX blocks to fit within maxLen.
9
+ *
10
+ * This function implements the common truncation algorithm used across
11
+ * all platform renderers, allowing them to share logic while using
12
+ * platform-specific formatting functions.
13
+ *
14
+ * @param blocks - Array of UX blocks to format and truncate
15
+ * @param blockToFormatted - Function that converts a single UX block to formatted string
16
+ * @param opts - Truncation options including max length and optional fallback
17
+ * @returns Formatted and truncated string, or fallback if empty
18
+ */
19
+ export function truncateBlocks(blocks, blockToFormatted, opts) {
20
+ const maxLen = Math.max(256, Math.floor(opts?.maxLen ?? 1900));
21
+ const fallback = opts?.fallback ?? '⏳ Thinking...';
22
+ const parts = [];
23
+ let used = 0;
24
+ let truncated = false;
25
+ for (const block of blocks) {
26
+ const piece = blockToFormatted(block, opts);
27
+ const sep = parts.length ? '\n\n' : '';
28
+ const add = sep + piece;
29
+ if (used + add.length > maxLen) {
30
+ truncated = true;
31
+ break;
32
+ }
33
+ parts.push(add);
34
+ used += add.length;
35
+ }
36
+ let out = parts.join('');
37
+ if (truncated && out.length + 2 <= maxLen)
38
+ out += '\n…';
39
+ if (!out.trim())
40
+ out = fallback;
41
+ return out;
42
+ }
43
+ //# sourceMappingURL=shared-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-formatter.js","sourceRoot":"","sources":["../../../src/bot/ux/shared-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAiB,EACjB,gBAAwD,EACxD,IAAwB;IAExB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,eAAe,CAAC;IAEnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC;QAExB,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM;QACR,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,IAAI,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM;QAAE,GAAG,IAAI,KAAK,CAAC;IACxD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,GAAG,GAAG,QAAQ,CAAC;IAEhC,OAAO,GAAG,CAAC;AACb,CAAC"}