tg-claude 0.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 (111) hide show
  1. package/README.md +175 -0
  2. package/bin/cli.js +2 -0
  3. package/dist/claude/ClaudeProcess.d.ts +77 -0
  4. package/dist/claude/ClaudeProcess.d.ts.map +1 -0
  5. package/dist/claude/ClaudeProcess.js +270 -0
  6. package/dist/claude/ClaudeProcess.js.map +1 -0
  7. package/dist/claude/EventAdapter.d.ts +44 -0
  8. package/dist/claude/EventAdapter.d.ts.map +1 -0
  9. package/dist/claude/EventAdapter.js +129 -0
  10. package/dist/claude/EventAdapter.js.map +1 -0
  11. package/dist/claude/index.d.ts +10 -0
  12. package/dist/claude/index.d.ts.map +1 -0
  13. package/dist/claude/index.js +9 -0
  14. package/dist/claude/index.js.map +1 -0
  15. package/dist/claude/types.d.ts +244 -0
  16. package/dist/claude/types.d.ts.map +1 -0
  17. package/dist/claude/types.js +8 -0
  18. package/dist/claude/types.js.map +1 -0
  19. package/dist/env.d.ts +21 -0
  20. package/dist/env.d.ts.map +1 -0
  21. package/dist/env.js +49 -0
  22. package/dist/env.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +360 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/parser/AnsiStripper.d.ts +54 -0
  28. package/dist/parser/AnsiStripper.d.ts.map +1 -0
  29. package/dist/parser/AnsiStripper.js +115 -0
  30. package/dist/parser/AnsiStripper.js.map +1 -0
  31. package/dist/parser/OptionExtractor.d.ts +31 -0
  32. package/dist/parser/OptionExtractor.d.ts.map +1 -0
  33. package/dist/parser/OptionExtractor.js +91 -0
  34. package/dist/parser/OptionExtractor.js.map +1 -0
  35. package/dist/parser/OutputParser.d.ts +121 -0
  36. package/dist/parser/OutputParser.d.ts.map +1 -0
  37. package/dist/parser/OutputParser.js +306 -0
  38. package/dist/parser/OutputParser.js.map +1 -0
  39. package/dist/parser/PromptDetector.d.ts +20 -0
  40. package/dist/parser/PromptDetector.d.ts.map +1 -0
  41. package/dist/parser/PromptDetector.js +68 -0
  42. package/dist/parser/PromptDetector.js.map +1 -0
  43. package/dist/parser/index.d.ts +7 -0
  44. package/dist/parser/index.d.ts.map +1 -0
  45. package/dist/parser/index.js +5 -0
  46. package/dist/parser/index.js.map +1 -0
  47. package/dist/parser/types.d.ts +73 -0
  48. package/dist/parser/types.d.ts.map +1 -0
  49. package/dist/parser/types.js +2 -0
  50. package/dist/parser/types.js.map +1 -0
  51. package/dist/pty/OutputBuffer.d.ts +39 -0
  52. package/dist/pty/OutputBuffer.d.ts.map +1 -0
  53. package/dist/pty/OutputBuffer.js +55 -0
  54. package/dist/pty/OutputBuffer.js.map +1 -0
  55. package/dist/pty/PtyProcess.d.ts +47 -0
  56. package/dist/pty/PtyProcess.d.ts.map +1 -0
  57. package/dist/pty/PtyProcess.js +94 -0
  58. package/dist/pty/PtyProcess.js.map +1 -0
  59. package/dist/pty/PtyService.d.ts +55 -0
  60. package/dist/pty/PtyService.d.ts.map +1 -0
  61. package/dist/pty/PtyService.js +115 -0
  62. package/dist/pty/PtyService.js.map +1 -0
  63. package/dist/pty/index.d.ts +5 -0
  64. package/dist/pty/index.d.ts.map +1 -0
  65. package/dist/pty/index.js +4 -0
  66. package/dist/pty/index.js.map +1 -0
  67. package/dist/pty/types.d.ts +36 -0
  68. package/dist/pty/types.d.ts.map +1 -0
  69. package/dist/pty/types.js +2 -0
  70. package/dist/pty/types.js.map +1 -0
  71. package/dist/router/BoundedQueue.d.ts +57 -0
  72. package/dist/router/BoundedQueue.d.ts.map +1 -0
  73. package/dist/router/BoundedQueue.js +86 -0
  74. package/dist/router/BoundedQueue.js.map +1 -0
  75. package/dist/router/EventRouter.d.ts +103 -0
  76. package/dist/router/EventRouter.d.ts.map +1 -0
  77. package/dist/router/EventRouter.js +169 -0
  78. package/dist/router/EventRouter.js.map +1 -0
  79. package/dist/router/index.d.ts +13 -0
  80. package/dist/router/index.d.ts.map +1 -0
  81. package/dist/router/index.js +12 -0
  82. package/dist/router/index.js.map +1 -0
  83. package/dist/router/types.d.ts +104 -0
  84. package/dist/router/types.d.ts.map +1 -0
  85. package/dist/router/types.js +6 -0
  86. package/dist/router/types.js.map +1 -0
  87. package/dist/telegram/TelegramBot.d.ts +151 -0
  88. package/dist/telegram/TelegramBot.d.ts.map +1 -0
  89. package/dist/telegram/TelegramBot.js +514 -0
  90. package/dist/telegram/TelegramBot.js.map +1 -0
  91. package/dist/telegram/index.d.ts +7 -0
  92. package/dist/telegram/index.d.ts.map +1 -0
  93. package/dist/telegram/index.js +6 -0
  94. package/dist/telegram/index.js.map +1 -0
  95. package/dist/telegram/types.d.ts +30 -0
  96. package/dist/telegram/types.d.ts.map +1 -0
  97. package/dist/telegram/types.js +5 -0
  98. package/dist/telegram/types.js.map +1 -0
  99. package/dist/terminal/TerminalInterface.d.ts +61 -0
  100. package/dist/terminal/TerminalInterface.d.ts.map +1 -0
  101. package/dist/terminal/TerminalInterface.js +218 -0
  102. package/dist/terminal/TerminalInterface.js.map +1 -0
  103. package/dist/terminal/index.d.ts +3 -0
  104. package/dist/terminal/index.d.ts.map +1 -0
  105. package/dist/terminal/index.js +2 -0
  106. package/dist/terminal/index.js.map +1 -0
  107. package/dist/terminal/types.d.ts +17 -0
  108. package/dist/terminal/types.d.ts.map +1 -0
  109. package/dist/terminal/types.js +2 -0
  110. package/dist/terminal/types.js.map +1 -0
  111. package/package.json +43 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Generic bounded queue with configurable overflow behavior.
3
+ * Drops oldest items when capacity exceeded (matches OutputBuffer pattern).
4
+ */
5
+ export class BoundedQueue {
6
+ items = [];
7
+ maxSize;
8
+ droppedCount = 0;
9
+ /**
10
+ * Create a new BoundedQueue
11
+ * @param maxSize - Maximum number of items the queue can hold (must be >= 1)
12
+ * @throws Error if maxSize is less than 1
13
+ */
14
+ constructor(maxSize) {
15
+ if (maxSize < 1) {
16
+ throw new Error('maxSize must be at least 1');
17
+ }
18
+ this.maxSize = maxSize;
19
+ }
20
+ /**
21
+ * Add item to queue. If full, drops oldest item.
22
+ * @param item - Item to add to the queue
23
+ * @returns true if item was added without dropping, false if overflow occurred
24
+ */
25
+ push(item) {
26
+ const overflow = this.items.length >= this.maxSize;
27
+ if (overflow) {
28
+ this.items.shift();
29
+ this.droppedCount++;
30
+ }
31
+ this.items.push(item);
32
+ return !overflow;
33
+ }
34
+ /**
35
+ * Remove and return oldest item, or undefined if empty.
36
+ * @returns The oldest item in the queue, or undefined if queue is empty
37
+ */
38
+ shift() {
39
+ return this.items.shift();
40
+ }
41
+ /**
42
+ * Peek at oldest item without removing.
43
+ * @returns The oldest item in the queue, or undefined if queue is empty
44
+ */
45
+ peek() {
46
+ return this.items[0];
47
+ }
48
+ /**
49
+ * Current number of items in queue.
50
+ */
51
+ get size() {
52
+ return this.items.length;
53
+ }
54
+ /**
55
+ * Whether queue is at capacity.
56
+ */
57
+ get isFull() {
58
+ return this.items.length >= this.maxSize;
59
+ }
60
+ /**
61
+ * Whether queue is empty.
62
+ */
63
+ get isEmpty() {
64
+ return this.items.length === 0;
65
+ }
66
+ /**
67
+ * Total items dropped due to overflow since creation.
68
+ */
69
+ get totalDropped() {
70
+ return this.droppedCount;
71
+ }
72
+ /**
73
+ * Clear all items from queue.
74
+ */
75
+ clear() {
76
+ this.items = [];
77
+ }
78
+ /**
79
+ * Get all items as array (for debugging).
80
+ * @returns A copy of the internal items array
81
+ */
82
+ toArray() {
83
+ return [...this.items];
84
+ }
85
+ }
86
+ //# sourceMappingURL=BoundedQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoundedQueue.js","sourceRoot":"","sources":["../../src/router/BoundedQueue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,KAAK,GAAQ,EAAE,CAAC;IACP,OAAO,CAAS;IACzB,YAAY,GAAG,CAAC,CAAC;IAEzB;;;;OAIG;IACH,YAAY,OAAe;QACzB,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,IAAO;QACV,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;QACnD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,QAAQ,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,103 @@
1
+ import type { EventRouterEvents, OutboundEvent, InboundEvent } from './types.js';
2
+ export interface EventRouterOptions {
3
+ /** Max outbound events per session (default: 100) */
4
+ outboundQueueSize?: number;
5
+ /** Max inbound events per session (default: 50) */
6
+ inboundQueueSize?: number;
7
+ }
8
+ /**
9
+ * Central router for bidirectional event flow between PTY/Parser and Telegram layers.
10
+ * Maintains per-session bounded queues for decoupled communication.
11
+ *
12
+ * @emits outbound - When outbound event is published
13
+ * @emits inbound - When inbound event is published
14
+ * @emits sessionCreated - When a new session is registered
15
+ * @emits sessionDestroyed - When a session is unregistered
16
+ * @emits queueOverflow - When a queue drops an event due to size limit
17
+ */
18
+ export declare class EventRouter {
19
+ private readonly emitter;
20
+ private readonly options;
21
+ private readonly outboundQueues;
22
+ private readonly inboundQueues;
23
+ constructor(options?: EventRouterOptions);
24
+ /**
25
+ * Subscribe to router events.
26
+ */
27
+ on<K extends keyof EventRouterEvents>(event: K, listener: EventRouterEvents[K]): this;
28
+ /**
29
+ * Subscribe to router events (once).
30
+ */
31
+ once<K extends keyof EventRouterEvents>(event: K, listener: EventRouterEvents[K]): this;
32
+ /**
33
+ * Unsubscribe from router events.
34
+ */
35
+ off<K extends keyof EventRouterEvents>(event: K, listener: EventRouterEvents[K]): this;
36
+ /**
37
+ * Remove all listeners for an event.
38
+ */
39
+ removeAllListeners<K extends keyof EventRouterEvents>(event?: K): this;
40
+ /**
41
+ * Register a new session with dedicated queues.
42
+ * @throws Error if session already registered
43
+ */
44
+ registerSession(sessionId: string): void;
45
+ /**
46
+ * Unregister a session and remove its queues.
47
+ * Safe to call if session doesn't exist.
48
+ */
49
+ unregisterSession(sessionId: string): void;
50
+ /**
51
+ * Check if a session is registered.
52
+ */
53
+ hasSession(sessionId: string): boolean;
54
+ /**
55
+ * Get all registered session IDs.
56
+ */
57
+ getSessions(): string[];
58
+ /**
59
+ * Publish an outbound event (PTY/Parser -> Telegram direction).
60
+ * @returns false if session not found, true otherwise
61
+ */
62
+ publishOutbound(event: OutboundEvent): boolean;
63
+ /**
64
+ * Publish an inbound event (Telegram -> PTY direction).
65
+ * @returns false if session not found, true otherwise
66
+ */
67
+ publishInbound(event: InboundEvent): boolean;
68
+ /**
69
+ * Consume (dequeue) the oldest outbound event for a session.
70
+ * @returns The event or undefined if queue empty or session not found
71
+ */
72
+ consumeOutbound(sessionId: string): OutboundEvent | undefined;
73
+ /**
74
+ * Consume (dequeue) the oldest inbound event for a session.
75
+ * @returns The event or undefined if queue empty or session not found
76
+ */
77
+ consumeInbound(sessionId: string): InboundEvent | undefined;
78
+ /**
79
+ * Peek at the oldest outbound event without consuming.
80
+ */
81
+ peekOutbound(sessionId: string): OutboundEvent | undefined;
82
+ /**
83
+ * Peek at the oldest inbound event without consuming.
84
+ */
85
+ peekInbound(sessionId: string): InboundEvent | undefined;
86
+ /**
87
+ * Get outbound queue size for a session.
88
+ */
89
+ getOutboundQueueSize(sessionId: string): number;
90
+ /**
91
+ * Get inbound queue size for a session.
92
+ */
93
+ getInboundQueueSize(sessionId: string): number;
94
+ /**
95
+ * Get total dropped events for outbound queue.
96
+ */
97
+ getOutboundDropped(sessionId: string): number;
98
+ /**
99
+ * Get total dropped events for inbound queue.
100
+ */
101
+ getInboundDropped(sessionId: string): number;
102
+ }
103
+ //# sourceMappingURL=EventRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventRouter.d.ts","sourceRoot":"","sources":["../../src/router/EventRouter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGjF,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAWD;;;;;;;;;GASG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkD;IACjF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiD;gBAEnE,OAAO,GAAE,kBAAuB;IAQ5C;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;IAKrF;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;IAKvF;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;IAKtF;;OAEG;IACH,kBAAkB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAKtE;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IASxC;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO1C;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAY9C;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAY5C;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI7D;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI3D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI1D;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIxD;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI/C;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI9C;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI7C;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAG7C"}
@@ -0,0 +1,169 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { BoundedQueue } from './BoundedQueue.js';
3
+ /**
4
+ * Central router for bidirectional event flow between PTY/Parser and Telegram layers.
5
+ * Maintains per-session bounded queues for decoupled communication.
6
+ *
7
+ * @emits outbound - When outbound event is published
8
+ * @emits inbound - When inbound event is published
9
+ * @emits sessionCreated - When a new session is registered
10
+ * @emits sessionDestroyed - When a session is unregistered
11
+ * @emits queueOverflow - When a queue drops an event due to size limit
12
+ */
13
+ export class EventRouter {
14
+ emitter;
15
+ options;
16
+ outboundQueues = new Map();
17
+ inboundQueues = new Map();
18
+ constructor(options = {}) {
19
+ this.emitter = new EventEmitter();
20
+ this.options = {
21
+ outboundQueueSize: options.outboundQueueSize ?? 100,
22
+ inboundQueueSize: options.inboundQueueSize ?? 50,
23
+ };
24
+ }
25
+ /**
26
+ * Subscribe to router events.
27
+ */
28
+ on(event, listener) {
29
+ this.emitter.on(event, listener);
30
+ return this;
31
+ }
32
+ /**
33
+ * Subscribe to router events (once).
34
+ */
35
+ once(event, listener) {
36
+ this.emitter.once(event, listener);
37
+ return this;
38
+ }
39
+ /**
40
+ * Unsubscribe from router events.
41
+ */
42
+ off(event, listener) {
43
+ this.emitter.off(event, listener);
44
+ return this;
45
+ }
46
+ /**
47
+ * Remove all listeners for an event.
48
+ */
49
+ removeAllListeners(event) {
50
+ this.emitter.removeAllListeners(event);
51
+ return this;
52
+ }
53
+ /**
54
+ * Register a new session with dedicated queues.
55
+ * @throws Error if session already registered
56
+ */
57
+ registerSession(sessionId) {
58
+ if (this.outboundQueues.has(sessionId)) {
59
+ throw new Error(`Session ${sessionId} already registered`);
60
+ }
61
+ this.outboundQueues.set(sessionId, new BoundedQueue(this.options.outboundQueueSize));
62
+ this.inboundQueues.set(sessionId, new BoundedQueue(this.options.inboundQueueSize));
63
+ this.emitter.emit('sessionCreated', sessionId);
64
+ }
65
+ /**
66
+ * Unregister a session and remove its queues.
67
+ * Safe to call if session doesn't exist.
68
+ */
69
+ unregisterSession(sessionId) {
70
+ if (!this.outboundQueues.has(sessionId))
71
+ return;
72
+ this.outboundQueues.delete(sessionId);
73
+ this.inboundQueues.delete(sessionId);
74
+ this.emitter.emit('sessionDestroyed', sessionId);
75
+ }
76
+ /**
77
+ * Check if a session is registered.
78
+ */
79
+ hasSession(sessionId) {
80
+ return this.outboundQueues.has(sessionId);
81
+ }
82
+ /**
83
+ * Get all registered session IDs.
84
+ */
85
+ getSessions() {
86
+ return Array.from(this.outboundQueues.keys());
87
+ }
88
+ /**
89
+ * Publish an outbound event (PTY/Parser -> Telegram direction).
90
+ * @returns false if session not found, true otherwise
91
+ */
92
+ publishOutbound(event) {
93
+ const queue = this.outboundQueues.get(event.sessionId);
94
+ if (!queue)
95
+ return false;
96
+ const added = queue.push(event);
97
+ if (!added) {
98
+ this.emitter.emit('queueOverflow', event.sessionId, 'outbound');
99
+ }
100
+ this.emitter.emit('outbound', event);
101
+ return true;
102
+ }
103
+ /**
104
+ * Publish an inbound event (Telegram -> PTY direction).
105
+ * @returns false if session not found, true otherwise
106
+ */
107
+ publishInbound(event) {
108
+ const queue = this.inboundQueues.get(event.sessionId);
109
+ if (!queue)
110
+ return false;
111
+ const added = queue.push(event);
112
+ if (!added) {
113
+ this.emitter.emit('queueOverflow', event.sessionId, 'inbound');
114
+ }
115
+ this.emitter.emit('inbound', event);
116
+ return true;
117
+ }
118
+ /**
119
+ * Consume (dequeue) the oldest outbound event for a session.
120
+ * @returns The event or undefined if queue empty or session not found
121
+ */
122
+ consumeOutbound(sessionId) {
123
+ return this.outboundQueues.get(sessionId)?.shift();
124
+ }
125
+ /**
126
+ * Consume (dequeue) the oldest inbound event for a session.
127
+ * @returns The event or undefined if queue empty or session not found
128
+ */
129
+ consumeInbound(sessionId) {
130
+ return this.inboundQueues.get(sessionId)?.shift();
131
+ }
132
+ /**
133
+ * Peek at the oldest outbound event without consuming.
134
+ */
135
+ peekOutbound(sessionId) {
136
+ return this.outboundQueues.get(sessionId)?.peek();
137
+ }
138
+ /**
139
+ * Peek at the oldest inbound event without consuming.
140
+ */
141
+ peekInbound(sessionId) {
142
+ return this.inboundQueues.get(sessionId)?.peek();
143
+ }
144
+ /**
145
+ * Get outbound queue size for a session.
146
+ */
147
+ getOutboundQueueSize(sessionId) {
148
+ return this.outboundQueues.get(sessionId)?.size ?? 0;
149
+ }
150
+ /**
151
+ * Get inbound queue size for a session.
152
+ */
153
+ getInboundQueueSize(sessionId) {
154
+ return this.inboundQueues.get(sessionId)?.size ?? 0;
155
+ }
156
+ /**
157
+ * Get total dropped events for outbound queue.
158
+ */
159
+ getOutboundDropped(sessionId) {
160
+ return this.outboundQueues.get(sessionId)?.totalDropped ?? 0;
161
+ }
162
+ /**
163
+ * Get total dropped events for inbound queue.
164
+ */
165
+ getInboundDropped(sessionId) {
166
+ return this.inboundQueues.get(sessionId)?.totalDropped ?? 0;
167
+ }
168
+ }
169
+ //# sourceMappingURL=EventRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventRouter.js","sourceRoot":"","sources":["../../src/router/EventRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Event Router module - bidirectional event routing between PTY/Parser and Telegram layers.
3
+ *
4
+ * Exports:
5
+ * - Event types for outbound (PTY->Telegram) and inbound (Telegram->PTY) directions
6
+ * - BoundedQueue utility for memory-safe event buffering
7
+ * - EventRouter class for session-based event routing
8
+ */
9
+ export * from './types.js';
10
+ export { BoundedQueue } from './BoundedQueue.js';
11
+ export { EventRouter } from './EventRouter.js';
12
+ export type { EventRouterOptions } from './EventRouter.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Event Router module - bidirectional event routing between PTY/Parser and Telegram layers.
3
+ *
4
+ * Exports:
5
+ * - Event types for outbound (PTY->Telegram) and inbound (Telegram->PTY) directions
6
+ * - BoundedQueue utility for memory-safe event buffering
7
+ * - EventRouter class for session-based event routing
8
+ */
9
+ export * from './types.js';
10
+ export { BoundedQueue } from './BoundedQueue.js';
11
+ export { EventRouter } from './EventRouter.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Event types for bidirectional routing between PTY/Parser and Telegram layers.
3
+ * Outbound events flow from PTY to Telegram; Inbound events flow from Telegram to PTY.
4
+ */
5
+ import type { PromptEvent } from '../parser/types.js';
6
+ /**
7
+ * Payload for streaming output chunks
8
+ */
9
+ export interface OutputPayload {
10
+ /** Cleaned text with ANSI codes stripped */
11
+ text: string;
12
+ /** Original raw output including ANSI codes */
13
+ raw: string;
14
+ }
15
+ /**
16
+ * Payload for process exit events
17
+ */
18
+ export interface ExitPayload {
19
+ /** Exit code from the process */
20
+ exitCode: number;
21
+ /** Signal number if terminated by signal */
22
+ signal?: number;
23
+ }
24
+ /**
25
+ * Payload for task completion events
26
+ */
27
+ export interface CompletionPayload {
28
+ /** Summary of final output */
29
+ summary: string;
30
+ /** Duration from work start to completion (ms) */
31
+ duration?: number;
32
+ }
33
+ /**
34
+ * Event flowing from PTY/Parser layer to Telegram layer.
35
+ * Discriminated union based on 'type' field.
36
+ */
37
+ export interface OutboundEvent {
38
+ /** Session identifier for routing */
39
+ sessionId: string;
40
+ /** Event category */
41
+ type: 'prompt' | 'output' | 'exit' | 'completion';
42
+ /** Event payload, discriminated by type */
43
+ payload: PromptEvent | OutputPayload | ExitPayload | CompletionPayload;
44
+ /** Timestamp when event occurred (ms since epoch) */
45
+ timestamp: number;
46
+ }
47
+ /**
48
+ * Payload for user response to a prompt
49
+ */
50
+ export interface ResponsePayload {
51
+ /** User's response text */
52
+ text: string;
53
+ /** Index of selected option (if user chose from options) */
54
+ optionIndex?: number;
55
+ }
56
+ /**
57
+ * Payload for cancellation request
58
+ */
59
+ export interface CancelPayload {
60
+ /** Optional reason for cancellation */
61
+ reason?: string;
62
+ }
63
+ /**
64
+ * Payload for terminal resize request
65
+ */
66
+ export interface ResizePayload {
67
+ /** Number of columns */
68
+ cols: number;
69
+ /** Number of rows */
70
+ rows: number;
71
+ }
72
+ /**
73
+ * Event flowing from Telegram layer to PTY layer.
74
+ * Discriminated union based on 'type' field.
75
+ */
76
+ export interface InboundEvent {
77
+ /** Session identifier for routing */
78
+ sessionId: string;
79
+ /** Event category */
80
+ type: 'response' | 'cancel' | 'resize';
81
+ /** Event payload, discriminated by type */
82
+ payload: ResponsePayload | CancelPayload | ResizePayload;
83
+ /** Timestamp when event was created (ms since epoch) */
84
+ timestamp: number;
85
+ /** Source interface that generated this event (for echo prevention) */
86
+ source?: 'terminal' | 'telegram';
87
+ }
88
+ /**
89
+ * Event map for typed EventEmitter.
90
+ * Defines all events the EventRouter can emit.
91
+ */
92
+ export interface EventRouterEvents {
93
+ /** Emitted when an outbound event is published */
94
+ outbound: (event: OutboundEvent) => void;
95
+ /** Emitted when an inbound event is published */
96
+ inbound: (event: InboundEvent) => void;
97
+ /** Emitted when a new session is registered */
98
+ sessionCreated: (sessionId: string) => void;
99
+ /** Emitted when a session is unregistered */
100
+ sessionDestroyed: (sessionId: string) => void;
101
+ /** Emitted when a queue overflows (drops oldest) */
102
+ queueOverflow: (sessionId: string, direction: 'inbound' | 'outbound') => void;
103
+ }
104
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;IAClD,2CAA2C;IAC3C,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,WAAW,GAAG,iBAAiB,CAAC;IACvE,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACvC,2CAA2C;IAC3C,OAAO,EAAE,eAAe,GAAG,aAAa,GAAG,aAAa,CAAC;IACzD,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;CAClC;AAMD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,iDAAiD;IACjD,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,+CAA+C;IAC/C,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,6CAA6C;IAC7C,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oDAAoD;IACpD,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,CAAC;CAC/E"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Event types for bidirectional routing between PTY/Parser and Telegram layers.
3
+ * Outbound events flow from PTY to Telegram; Inbound events flow from Telegram to PTY.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * TelegramBot class wrapping grammY Bot with composition pattern.
3
+ * Implements AUTH-01 whitelist authentication for single-user access.
4
+ */
5
+ import type { NotificationPayload } from './types.js';
6
+ import type { TelegramConfig } from './types.js';
7
+ /**
8
+ * Handler for inline button callback responses.
9
+ * @param sessionId - The session that receives the response
10
+ * @param optionIndex - The selected option index (1-based)
11
+ */
12
+ export type CallbackHandler = (sessionId: string, optionIndex: number) => void;
13
+ /**
14
+ * Handler for freeform text message responses.
15
+ * @param sessionId - The session that receives the response
16
+ * @param text - The user's text input
17
+ */
18
+ export type TextMessageHandler = (sessionId: string, text: string) => void;
19
+ /**
20
+ * Options for TelegramBot initialization.
21
+ * Extends TelegramConfig to allow future options.
22
+ */
23
+ export interface TelegramBotOptions extends TelegramConfig {
24
+ }
25
+ /**
26
+ * TelegramBot wraps grammY Bot with composition pattern.
27
+ * Provides single-user authentication and graceful lifecycle management.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const bot = new TelegramBot({
32
+ * token: process.env.TELEGRAM_BOT_TOKEN,
33
+ * allowedUserId: Number(process.env.TELEGRAM_USER_ID),
34
+ * });
35
+ * await bot.start();
36
+ * ```
37
+ */
38
+ export declare class TelegramBot {
39
+ private readonly bot;
40
+ private readonly allowedUserId;
41
+ private started;
42
+ private readonly sessionChatMap;
43
+ onCallback: CallbackHandler | null;
44
+ onTextMessage: TextMessageHandler | null;
45
+ private awaitingSession;
46
+ private readonly multiSelectState;
47
+ constructor(options: TelegramBotOptions);
48
+ /**
49
+ * Set up bot middleware and command handlers.
50
+ */
51
+ private setupMiddleware;
52
+ /**
53
+ * Set up error handler for Telegram API and network errors.
54
+ */
55
+ private setupErrorHandler;
56
+ /**
57
+ * Handle single-select button click (existing behavior, refactored)
58
+ */
59
+ private handleSingleSelect;
60
+ /**
61
+ * Handle multi-select toggle button click
62
+ */
63
+ private handleToggle;
64
+ /**
65
+ * Handle multi-select submit button click
66
+ */
67
+ private handleSubmit;
68
+ /**
69
+ * Build multi-select keyboard with checkmarks for selected options
70
+ */
71
+ private buildMultiSelectKeyboard;
72
+ /**
73
+ * Start the bot with long polling.
74
+ * Safe to call multiple times (idempotent).
75
+ */
76
+ start(): Promise<void>;
77
+ /**
78
+ * Stop the bot gracefully.
79
+ * Safe to call multiple times (idempotent).
80
+ */
81
+ stop(): void;
82
+ /**
83
+ * Check if the bot is currently running.
84
+ */
85
+ get isStarted(): boolean;
86
+ /**
87
+ * Get the chat ID for the single whitelisted user.
88
+ * For private chats, chat_id equals user_id.
89
+ */
90
+ get chatId(): number;
91
+ /**
92
+ * Expose bot.api for proactive messaging.
93
+ * Used by higher layers to send notifications.
94
+ */
95
+ get api(): import("grammy").Api<import("grammy").RawApi>;
96
+ /**
97
+ * Register a session for notifications.
98
+ * Maps session to the whitelisted user's chat.
99
+ */
100
+ registerSession(sessionId: string): void;
101
+ /**
102
+ * Unregister a session.
103
+ */
104
+ unregisterSession(sessionId: string): void;
105
+ /**
106
+ * Check if a session is registered.
107
+ */
108
+ hasSession(sessionId: string): boolean;
109
+ /**
110
+ * Send a prompt notification to Telegram with inline keyboard.
111
+ * @param payload - The notification payload with question and options
112
+ * @returns Message ID if sent, undefined if session not registered
113
+ */
114
+ sendNotification(payload: NotificationPayload): Promise<number | undefined>;
115
+ /**
116
+ * Truncate button text for Telegram inline keyboards.
117
+ * Extracts label (before " - ") and truncates to max length.
118
+ * Telegram buttons have ~40-50 char visible width.
119
+ */
120
+ private truncateButtonText;
121
+ /**
122
+ * Escape HTML special characters for Telegram HTML parse mode.
123
+ */
124
+ private escapeHtml;
125
+ /**
126
+ * Send a completion notification to Telegram.
127
+ * Handles long messages by splitting into multiple messages.
128
+ * @param payload - The completion payload with summary
129
+ * @returns Message ID of last message if sent, undefined if session not registered
130
+ */
131
+ sendCompletionNotification(payload: {
132
+ sessionId: string;
133
+ summary: string;
134
+ duration?: number;
135
+ }): Promise<number | undefined>;
136
+ /**
137
+ * Split a long message into chunks at natural break points.
138
+ */
139
+ private splitMessage;
140
+ /**
141
+ * Mark a session as awaiting user input.
142
+ * Called when a prompt notification is sent.
143
+ */
144
+ setAwaitingInput(sessionId: string): void;
145
+ /**
146
+ * Clear the awaiting input state.
147
+ * Called when response is received or session ends.
148
+ */
149
+ clearAwaitingInput(): void;
150
+ }
151
+ //# sourceMappingURL=TelegramBot.d.ts.map