aegis-bridge 2.2.2

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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +244 -0
  3. package/dashboard/dist/assets/index-CijFoeRu.css +32 -0
  4. package/dashboard/dist/assets/index-QtT4j0ht.js +262 -0
  5. package/dashboard/dist/index.html +14 -0
  6. package/dist/auth.d.ts +76 -0
  7. package/dist/auth.js +219 -0
  8. package/dist/channels/index.d.ts +8 -0
  9. package/dist/channels/index.js +9 -0
  10. package/dist/channels/manager.d.ts +39 -0
  11. package/dist/channels/manager.js +101 -0
  12. package/dist/channels/telegram-style.d.ts +118 -0
  13. package/dist/channels/telegram-style.js +203 -0
  14. package/dist/channels/telegram.d.ts +76 -0
  15. package/dist/channels/telegram.js +1396 -0
  16. package/dist/channels/types.d.ts +77 -0
  17. package/dist/channels/types.js +9 -0
  18. package/dist/channels/webhook.d.ts +58 -0
  19. package/dist/channels/webhook.js +162 -0
  20. package/dist/cli.d.ts +8 -0
  21. package/dist/cli.js +223 -0
  22. package/dist/config.d.ts +60 -0
  23. package/dist/config.js +188 -0
  24. package/dist/dashboard/assets/index-CijFoeRu.css +32 -0
  25. package/dist/dashboard/assets/index-QtT4j0ht.js +262 -0
  26. package/dist/dashboard/index.html +14 -0
  27. package/dist/events.d.ts +86 -0
  28. package/dist/events.js +258 -0
  29. package/dist/hook-settings.d.ts +67 -0
  30. package/dist/hook-settings.js +138 -0
  31. package/dist/hook.d.ts +18 -0
  32. package/dist/hook.js +199 -0
  33. package/dist/hooks.d.ts +32 -0
  34. package/dist/hooks.js +279 -0
  35. package/dist/jsonl-watcher.d.ts +57 -0
  36. package/dist/jsonl-watcher.js +159 -0
  37. package/dist/mcp-server.d.ts +60 -0
  38. package/dist/mcp-server.js +788 -0
  39. package/dist/metrics.d.ts +104 -0
  40. package/dist/metrics.js +226 -0
  41. package/dist/monitor.d.ts +84 -0
  42. package/dist/monitor.js +553 -0
  43. package/dist/permission-guard.d.ts +51 -0
  44. package/dist/permission-guard.js +197 -0
  45. package/dist/pipeline.d.ts +84 -0
  46. package/dist/pipeline.js +218 -0
  47. package/dist/screenshot.d.ts +26 -0
  48. package/dist/screenshot.js +57 -0
  49. package/dist/server.d.ts +10 -0
  50. package/dist/server.js +1577 -0
  51. package/dist/session.d.ts +297 -0
  52. package/dist/session.js +1275 -0
  53. package/dist/sse-limiter.d.ts +47 -0
  54. package/dist/sse-limiter.js +62 -0
  55. package/dist/sse-writer.d.ts +31 -0
  56. package/dist/sse-writer.js +95 -0
  57. package/dist/ssrf.d.ts +57 -0
  58. package/dist/ssrf.js +169 -0
  59. package/dist/swarm-monitor.d.ts +114 -0
  60. package/dist/swarm-monitor.js +267 -0
  61. package/dist/terminal-parser.d.ts +16 -0
  62. package/dist/terminal-parser.js +343 -0
  63. package/dist/tmux.d.ts +161 -0
  64. package/dist/tmux.js +725 -0
  65. package/dist/transcript.d.ts +47 -0
  66. package/dist/transcript.js +244 -0
  67. package/dist/validation.d.ts +222 -0
  68. package/dist/validation.js +268 -0
  69. package/dist/ws-terminal.d.ts +32 -0
  70. package/dist/ws-terminal.js +297 -0
  71. package/package.json +71 -0
@@ -0,0 +1,203 @@
1
+ /**
2
+ * channels/telegram-style.ts — Telegram Message Style Guide
3
+ *
4
+ * 6 standard message types for clean, consistent Telegram UX.
5
+ * Rule: readable in 2 seconds. Max 2 button rows. Always an escape hatch.
6
+ *
7
+ * Types:
8
+ * ① quickUpdate — one-liner (70% of messages)
9
+ * ② taskComplete — post-merge quality gate card
10
+ * ③ alert — error/crash requiring action
11
+ * ④ yesNo — binary question
12
+ * ⑤ decision — technical choice with context + escape hatch
13
+ * ⑥ progress — pipeline/deploy with ASCII progress bar
14
+ */
15
+ // ── HTML Helpers (re-exported for channel use) ──────────────────────────────
16
+ export function esc(text) {
17
+ return text
18
+ .replace(/&/g, '&')
19
+ .replace(/</g, '&lt;')
20
+ .replace(/>/g, '&gt;');
21
+ }
22
+ export function bold(text) {
23
+ return `<b>${esc(text)}</b>`;
24
+ }
25
+ export function code(text) {
26
+ return `<code>${esc(text)}</code>`;
27
+ }
28
+ export function italic(text) {
29
+ return `<i>${esc(text)}</i>`;
30
+ }
31
+ const STATUS_EMOJI = {
32
+ ok: '🟢',
33
+ done: '✅',
34
+ warn: '⚠️',
35
+ error: '🔴',
36
+ fail: '❌',
37
+ progress: '🔄',
38
+ work: '🔨',
39
+ deploy: '🚀',
40
+ };
41
+ export function statusEmoji(status) {
42
+ return STATUS_EMOJI[status] ?? '🔄';
43
+ }
44
+ // ── ① Quick Update ──────────────────────────────────────────────────────────
45
+ /**
46
+ * One-liner status update. 70% of all messages.
47
+ * No buttons, no separators. Emoji + text + optional data.
48
+ */
49
+ export function quickUpdate(emoji, message) {
50
+ return {
51
+ text: `${emoji} ${esc(message)}`,
52
+ parse_mode: 'HTML',
53
+ };
54
+ }
55
+ /**
56
+ * Quick update with inline code for technical data.
57
+ * e.g. quickUpdateCode('🟢', 'CI verde su', 'main', '— 150/150 test ✅')
58
+ */
59
+ export function quickUpdateCode(emoji, prefix, codeText, suffix) {
60
+ const parts = [emoji, esc(prefix), code(codeText)];
61
+ if (suffix)
62
+ parts.push(esc(suffix));
63
+ return {
64
+ text: parts.join(' '),
65
+ parse_mode: 'HTML',
66
+ };
67
+ }
68
+ /**
69
+ * Post-merge/completion card with quality gate.
70
+ * 3 lines max + 1 row of buttons.
71
+ */
72
+ export function taskComplete(data, buttons) {
73
+ const checksStr = data.checks
74
+ .map(([label, passed]) => `${passed ? '✅' : '❌'} ${esc(label)}`)
75
+ .join(' · ');
76
+ const text = [
77
+ `✅ ${bold(data.taskRef)} — ${esc(data.title)}`,
78
+ `⏱ ${code(data.duration)} · 🌿 ${code(data.branch)}`,
79
+ checksStr,
80
+ ].join('\n');
81
+ const msg = { text, parse_mode: 'HTML' };
82
+ if (buttons) {
83
+ const row = [];
84
+ if (buttons.merge)
85
+ row.push({ text: '✅ Merge', callback_data: buttons.merge });
86
+ if (buttons.review)
87
+ row.push({ text: '👀 Review', callback_data: buttons.review });
88
+ if (buttons.close)
89
+ row.push({ text: '❌ Chiudi', callback_data: buttons.close });
90
+ if (row.length)
91
+ msg.reply_markup = { inline_keyboard: [row] };
92
+ }
93
+ return msg;
94
+ }
95
+ /**
96
+ * Error/crash alert requiring action.
97
+ * Monospace block for technical details + 1 row of buttons.
98
+ */
99
+ export function alert(data, buttons) {
100
+ // Limit details to 3 lines
101
+ const detailLines = data.details.split('\n').slice(0, 3).join('\n');
102
+ const text = [
103
+ `🔴 ${bold(data.title)} — ${code(data.resourceId)}`,
104
+ `<pre>${esc(detailLines)}</pre>`,
105
+ ].join('\n');
106
+ const msg = { text, parse_mode: 'HTML' };
107
+ if (buttons) {
108
+ const row = [];
109
+ if (buttons.restart)
110
+ row.push({ text: '🔄 Riavvia', callback_data: buttons.restart });
111
+ if (buttons.log)
112
+ row.push({ text: '📜 Log', callback_data: buttons.log });
113
+ if (buttons.ignore)
114
+ row.push({ text: '⏸ Ignora', callback_data: buttons.ignore });
115
+ if (row.length)
116
+ msg.reply_markup = { inline_keyboard: [row] };
117
+ }
118
+ return msg;
119
+ }
120
+ // ── ④ Yes/No ────────────────────────────────────────────────────────────────
121
+ /**
122
+ * Binary question. 2 buttons, zero ambiguity.
123
+ * The "no" label should describe what happens if declined.
124
+ */
125
+ export function yesNo(question, yesLabel, noLabel, yesCallback, noCallback) {
126
+ return {
127
+ text: esc(question),
128
+ parse_mode: 'HTML',
129
+ reply_markup: {
130
+ inline_keyboard: [
131
+ [
132
+ { text: `✅ ${yesLabel}`, callback_data: yesCallback },
133
+ { text: `❌ ${noLabel}`, callback_data: noCallback },
134
+ ],
135
+ ],
136
+ },
137
+ };
138
+ }
139
+ /**
140
+ * Technical decision with context + escape hatch.
141
+ * The ONLY type allowed 2 rows of buttons.
142
+ * Max 3 options + always "Decidi tu" / "Parliamone".
143
+ */
144
+ export function decision(question, options, escapeCallbacks) {
145
+ const opts = options.slice(0, 3); // Max 3
146
+ const optionLines = opts.map((o) => `${bold(o.label)} — ${esc(o.description)}`);
147
+ const text = [esc(question), '', ...optionLines].join('\n');
148
+ const optionRow = opts.map((o) => ({
149
+ text: `${o.emoji} ${o.label}`,
150
+ callback_data: o.callback,
151
+ }));
152
+ const escapeRow = [];
153
+ if (escapeCallbacks?.decideTu) {
154
+ escapeRow.push({ text: '🤷 Decidi tu', callback_data: escapeCallbacks.decideTu });
155
+ }
156
+ if (escapeCallbacks?.parliamone) {
157
+ escapeRow.push({ text: '💬 Parliamone', callback_data: escapeCallbacks.parliamone });
158
+ }
159
+ const keyboard = [optionRow];
160
+ if (escapeRow.length)
161
+ keyboard.push(escapeRow);
162
+ return {
163
+ text,
164
+ parse_mode: 'HTML',
165
+ reply_markup: { inline_keyboard: keyboard },
166
+ };
167
+ }
168
+ /**
169
+ * Progress/pipeline card with ASCII bar.
170
+ * Updates via editMessageText — never send a new message for refresh.
171
+ */
172
+ export function progress(title, steps, percent, buttons) {
173
+ const doneSteps = steps.filter((s) => s.done);
174
+ const currentStep = steps.find((s) => !s.done);
175
+ // Done steps on one line with · separator
176
+ const doneStr = doneSteps
177
+ .map((s) => `✅ ${esc(s.label)}${s.duration ? ' ' + code(s.duration) : ''}`)
178
+ .join(' · ');
179
+ // ASCII progress bar
180
+ const barLen = 14;
181
+ const filled = Math.round((percent / 100) * barLen);
182
+ const bar = '█'.repeat(filled) + '░'.repeat(barLen - filled);
183
+ const lines = [
184
+ `🔄 ${bold(title)}`,
185
+ ];
186
+ if (doneStr)
187
+ lines.push(doneStr);
188
+ if (currentStep)
189
+ lines.push(`🔄 ${esc(currentStep.label)}...`);
190
+ lines.push(`${code(bar)} ${percent}%`);
191
+ const msg = { text: lines.join('\n'), parse_mode: 'HTML' };
192
+ if (buttons) {
193
+ const row = [];
194
+ if (buttons.pause)
195
+ row.push({ text: '⏸ Pausa', callback_data: buttons.pause });
196
+ if (buttons.cancel)
197
+ row.push({ text: '❌ Annulla', callback_data: buttons.cancel });
198
+ if (row.length)
199
+ msg.reply_markup = { inline_keyboard: [row] };
200
+ }
201
+ return msg;
202
+ }
203
+ //# sourceMappingURL=telegram-style.js.map
@@ -0,0 +1,76 @@
1
+ /**
2
+ * channels/telegram.ts — Telegram notification channel.
3
+ *
4
+ * Creates one topic per CC session in a Telegram supergroup.
5
+ * Bidirectional: reads replies from topics and fires inbound commands.
6
+ *
7
+ * Formatting: HTML parse_mode with structured, clean messages.
8
+ */
9
+ import type { Channel, SessionEventPayload, InboundHandler } from './types.js';
10
+ import type { SwarmMonitor } from '../swarm-monitor.js';
11
+ import { type StyledMessage } from './telegram-style.js';
12
+ export interface TelegramChannelConfig {
13
+ botToken: string;
14
+ groupChatId: string;
15
+ allowedUserIds: number[];
16
+ }
17
+ export declare class TelegramChannel implements Channel {
18
+ private config;
19
+ readonly name = "telegram";
20
+ private topics;
21
+ private progress;
22
+ private pollOffset;
23
+ private polling;
24
+ private onInbound;
25
+ private messageQueue;
26
+ private lastSent;
27
+ private flushTimers;
28
+ private pendingTool;
29
+ static readonly MAX_IN_FLIGHT = 10;
30
+ private inFlightCount;
31
+ private preTopicBuffer;
32
+ private pendingReads;
33
+ private readTimer;
34
+ private lastUserMessage;
35
+ private swarmMonitor;
36
+ /** Set the swarm monitor for /swarm command support. */
37
+ setSwarmMonitor(monitor: SwarmMonitor): void;
38
+ constructor(config: TelegramChannelConfig);
39
+ private pollLoopPromise;
40
+ init(onInbound: InboundHandler): Promise<void>;
41
+ destroy(): Promise<void>;
42
+ onSessionCreated(payload: SessionEventPayload): Promise<void>;
43
+ onSessionEnded(payload: SessionEventPayload): Promise<void>;
44
+ onMessage(payload: SessionEventPayload): Promise<void>;
45
+ onStatusChange(payload: SessionEventPayload): Promise<void>;
46
+ private addPendingRead;
47
+ private flushReads;
48
+ /**
49
+ * Send a StyledMessage (from telegram-style.ts) with inline keyboard support.
50
+ * This is the primary way to send the 6 standard message types.
51
+ */
52
+ sendStyled(sessionId: string, styled: StyledMessage): Promise<number | null>;
53
+ private sendStyledToTopic;
54
+ /**
55
+ * Edit a message in-place with a StyledMessage (for progress updates with buttons).
56
+ */
57
+ editStyled(sessionId: string, messageId: number, styled: StyledMessage): Promise<boolean>;
58
+ private editMessage;
59
+ private sendImmediate;
60
+ private sendToTopic;
61
+ /** Issue #89 L12: Decrement in-flight counter, clamped to 0. */
62
+ private decrementInFlight;
63
+ private queueMessage;
64
+ private flushQueue;
65
+ private cleanup;
66
+ private handleSwarmCommand;
67
+ private pollLoop;
68
+ /** Issue #348: Redact bot token from error messages before logging. */
69
+ private redactError;
70
+ private handleUpdate;
71
+ private handleCallbackQuery;
72
+ /**
73
+ * Remove inline keyboard from a message after button click (one-shot actions).
74
+ */
75
+ private removeReplyMarkup;
76
+ }