@llblab/pi-telegram 0.13.2 → 0.15.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.
package/lib/runtime.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  * Owns small session-local runtime primitives that are shared by orchestration but are not specific to queueing, rendering, polling, or Telegram transport
5
5
  */
6
6
 
7
- const TELEGRAM_TYPING_ACTION_INTERVAL_MS = 2500;
7
+ const TELEGRAM_TYPING_ACTION_INTERVAL_MS = 3000;
8
+ const TELEGRAM_TYPING_IDLE_DRAIN_MAX_MS = 300;
8
9
 
9
10
  export interface TelegramRuntimeQueueCounters {
10
11
  nextQueuedTelegramItemOrder: number;
@@ -16,7 +17,7 @@ export interface TelegramRuntimeLifecycleFlags {
16
17
  activeTelegramToolExecutions: number;
17
18
  telegramTurnDispatchPending: boolean;
18
19
  compactionInProgress: boolean;
19
- preserveQueuedTurnsAsHistory: boolean;
20
+ foldQueuedPromptsIntoHistory: boolean;
20
21
  setupInProgress: boolean;
21
22
  }
22
23
 
@@ -24,6 +25,7 @@ export interface TelegramBridgeRuntimeState
24
25
  extends TelegramRuntimeQueueCounters, TelegramRuntimeLifecycleFlags {
25
26
  abortHandler?: () => void;
26
27
  typingInterval?: ReturnType<typeof setInterval>;
28
+ typingInFlight?: Promise<void>;
27
29
  }
28
30
 
29
31
  export interface TelegramRuntimeQueuePort {
@@ -44,8 +46,8 @@ export interface TelegramRuntimeLifecyclePort {
44
46
  clearDispatchPending: () => void;
45
47
  isCompactionInProgress: () => boolean;
46
48
  setCompactionInProgress: (inProgress: boolean) => void;
47
- shouldPreserveQueuedTurnsAsHistory: () => boolean;
48
- setPreserveQueuedTurnsAsHistory: (preserve: boolean) => void;
49
+ shouldFoldQueuedPromptsIntoHistory: () => boolean;
50
+ setFoldQueuedPromptsIntoHistory: (fold: boolean) => void;
49
51
  }
50
52
 
51
53
  export interface TelegramRuntimeSetupPort {
@@ -65,6 +67,7 @@ export interface TelegramRuntimeAbortPort {
65
67
  export interface TelegramRuntimeTypingPort {
66
68
  start: (deps: TelegramTypingLoopDeps) => boolean;
67
69
  stop: () => boolean;
70
+ waitForIdle: () => Promise<void>;
68
71
  }
69
72
 
70
73
  export interface TelegramBridgeRuntime {
@@ -84,7 +87,7 @@ export function createTelegramBridgeRuntimeState(): TelegramBridgeRuntimeState {
84
87
  activeTelegramToolExecutions: 0,
85
88
  telegramTurnDispatchPending: false,
86
89
  compactionInProgress: false,
87
- preserveQueuedTurnsAsHistory: false,
90
+ foldQueuedPromptsIntoHistory: false,
88
91
  setupInProgress: false,
89
92
  };
90
93
  }
@@ -117,10 +120,10 @@ export function createTelegramBridgeRuntime(
117
120
  isCompactionInProgress: () => isTelegramCompactionInProgress(state),
118
121
  setCompactionInProgress: (inProgress) =>
119
122
  setTelegramCompactionInProgress(state, inProgress),
120
- shouldPreserveQueuedTurnsAsHistory: () =>
121
- shouldPreserveQueuedTurnsAsHistory(state),
122
- setPreserveQueuedTurnsAsHistory: (preserve) =>
123
- setPreserveQueuedTurnsAsHistory(state, preserve),
123
+ shouldFoldQueuedPromptsIntoHistory: () =>
124
+ shouldFoldQueuedPromptsIntoHistory(state),
125
+ setFoldQueuedPromptsIntoHistory: (fold) =>
126
+ setFoldQueuedPromptsIntoHistory(state, fold),
124
127
  },
125
128
  setup: {
126
129
  isInProgress: () => isTelegramSetupInProgress(state),
@@ -138,6 +141,7 @@ export function createTelegramBridgeRuntime(
138
141
  typing: {
139
142
  start: (deps) => startTelegramTypingLoop(state, deps),
140
143
  stop: () => stopTelegramTypingLoop(state),
144
+ waitForIdle: () => waitForTelegramTypingLoopIdle(state),
141
145
  },
142
146
  };
143
147
  }
@@ -195,8 +199,8 @@ export function syncTelegramLifecycleRuntimeFlags(
195
199
  if (flags.compactionInProgress !== undefined) {
196
200
  state.compactionInProgress = flags.compactionInProgress;
197
201
  }
198
- if (flags.preserveQueuedTurnsAsHistory !== undefined) {
199
- state.preserveQueuedTurnsAsHistory = flags.preserveQueuedTurnsAsHistory;
202
+ if (flags.foldQueuedPromptsIntoHistory !== undefined) {
203
+ state.foldQueuedPromptsIntoHistory = flags.foldQueuedPromptsIntoHistory;
200
204
  }
201
205
  if (flags.setupInProgress !== undefined) {
202
206
  state.setupInProgress = flags.setupInProgress;
@@ -254,17 +258,17 @@ export function setTelegramCompactionInProgress(
254
258
  state.compactionInProgress = inProgress;
255
259
  }
256
260
 
257
- export function shouldPreserveQueuedTurnsAsHistory(
261
+ export function shouldFoldQueuedPromptsIntoHistory(
258
262
  state: TelegramBridgeRuntimeState,
259
263
  ): boolean {
260
- return state.preserveQueuedTurnsAsHistory;
264
+ return state.foldQueuedPromptsIntoHistory;
261
265
  }
262
266
 
263
- export function setPreserveQueuedTurnsAsHistory(
267
+ export function setFoldQueuedPromptsIntoHistory(
264
268
  state: TelegramBridgeRuntimeState,
265
- preserve: boolean,
269
+ fold: boolean,
266
270
  ): void {
267
- state.preserveQueuedTurnsAsHistory = preserve;
271
+ state.foldQueuedPromptsIntoHistory = fold;
268
272
  }
269
273
 
270
274
  export function isTelegramSetupInProgress(
@@ -392,7 +396,13 @@ export function startTelegramTypingLoop(
392
396
  if (state.typingInterval || deps.chatId === undefined || deps.chatId === 0)
393
397
  return false;
394
398
  const sendTyping = (): void => {
395
- void deps.sendTypingAction(deps.chatId as number);
399
+ const typing = Promise.resolve(deps.sendTypingAction(deps.chatId as number))
400
+ .then(() => undefined)
401
+ .catch(() => undefined);
402
+ state.typingInFlight = typing;
403
+ void typing.finally(() => {
404
+ if (state.typingInFlight === typing) state.typingInFlight = undefined;
405
+ });
396
406
  };
397
407
  sendTyping();
398
408
  state.typingInterval = setInterval(sendTyping, deps.intervalMs);
@@ -408,6 +418,24 @@ export function stopTelegramTypingLoop(
408
418
  return true;
409
419
  }
410
420
 
421
+ export async function waitForTelegramTypingLoopIdle(
422
+ state: TelegramBridgeRuntimeState,
423
+ timeoutMs = TELEGRAM_TYPING_IDLE_DRAIN_MAX_MS,
424
+ ): Promise<void> {
425
+ const inFlight = state.typingInFlight;
426
+ if (!inFlight) return;
427
+ if (timeoutMs <= 0) {
428
+ await Promise.race([inFlight, Promise.resolve()]);
429
+ return;
430
+ }
431
+ await Promise.race([
432
+ inFlight,
433
+ new Promise<void>((resolve) => {
434
+ setTimeout(resolve, timeoutMs);
435
+ }),
436
+ ]);
437
+ }
438
+
411
439
  export function createTelegramContextAbortHandlerSetter<
412
440
  TContext extends { abort: () => void },
413
441
  >(
package/lib/sections.ts CHANGED
@@ -94,7 +94,7 @@ export interface TelegramSectionDiagnostic {
94
94
  id: TelegramSectionId;
95
95
  token: TelegramSectionToken;
96
96
  label: string;
97
- status: "active" | "stale" | "error";
97
+ status: "active" | "error";
98
98
  lastError?: string;
99
99
  }
100
100
 
@@ -106,6 +106,12 @@ export interface TelegramSectionRegistry {
106
106
  token: TelegramSectionToken,
107
107
  ): RegisteredTelegramSection | undefined;
108
108
  getDiagnostics(): TelegramSectionDiagnostic[];
109
+ recordError(
110
+ token: TelegramSectionToken,
111
+ message: string,
112
+ source?: string,
113
+ ): void;
114
+ clearError(token: TelegramSectionToken, source?: string): void;
109
115
  clear(): void;
110
116
  }
111
117
 
@@ -299,6 +305,10 @@ function getUtf8ByteLength(value: string): number {
299
305
  return new TextEncoder().encode(value).byteLength;
300
306
  }
301
307
 
308
+ function sectionErrorMessage(error: unknown): string {
309
+ return error instanceof Error ? error.message : String(error);
310
+ }
311
+
302
312
  function buildTelegramSectionCallbackData(
303
313
  token: TelegramSectionToken,
304
314
  action: string,
@@ -340,7 +350,10 @@ function prependBackRow(
340
350
  /** @internal */
341
351
  export function createTelegramExtensionSectionRegistry(): TelegramSectionRegistry {
342
352
  const sections = new Map<TelegramSectionToken, RegisteredTelegramSection>();
343
- const errors = new Map<TelegramSectionToken, string>();
353
+ const errors = new Map<
354
+ TelegramSectionToken,
355
+ { message: string; source: string }
356
+ >();
344
357
  let nextToken = 0;
345
358
 
346
359
  function register(section: TelegramSectionRegistration): () => void {
@@ -382,24 +395,46 @@ export function createTelegramExtensionSectionRegistry(): TelegramSectionRegistr
382
395
  token: s.token,
383
396
  label: s.label,
384
397
  status: errors.has(s.token) ? "error" : "active",
385
- lastError: errors.get(s.token),
398
+ lastError: errors.get(s.token)?.message,
386
399
  }));
387
400
  }
388
401
 
402
+ function recordError(
403
+ token: TelegramSectionToken,
404
+ message: string,
405
+ source = "runtime",
406
+ ): void {
407
+ if (sections.has(token)) errors.set(token, { message, source });
408
+ }
409
+
410
+ function clearError(token: TelegramSectionToken, source?: string): void {
411
+ const current = errors.get(token);
412
+ if (!source || !current || current.source === source) errors.delete(token);
413
+ }
414
+
389
415
  function clear(): void {
390
416
  sections.clear();
391
417
  errors.clear();
392
418
  nextToken = 0;
393
419
  }
394
420
 
395
- return { register, getSections, getByToken, getDiagnostics, clear };
421
+ return {
422
+ register,
423
+ getSections,
424
+ getByToken,
425
+ getDiagnostics,
426
+ recordError,
427
+ clearError,
428
+ clear,
429
+ };
396
430
  }
397
431
 
398
432
  /** @internal */
399
433
  export function getTelegramExtensionSettingsRows(
400
434
  registry: TelegramSectionRegistry,
401
435
  ): TelegramSectionSettingsRow[] {
402
- return registry
436
+ const rows: TelegramSectionSettingsRow[] = [];
437
+ for (const section of registry
403
438
  .getSections()
404
439
  .filter((s) => s.registration.settings)
405
440
  .sort((a, b) => {
@@ -407,22 +442,47 @@ export function getTelegramExtensionSettingsRows(
407
442
  const orderB = b.registration.settings!.order ?? 0;
408
443
  if (orderA !== orderB) return orderA - orderB;
409
444
  return a.id.localeCompare(b.id);
410
- })
411
- .map((s) => ({
412
- label:
413
- s.registration.settings!.getLabel?.() ?? s.registration.settings!.label,
414
- callback_data: `section:${s.token}:settings:open`,
415
- }));
445
+ })) {
446
+ try {
447
+ rows.push({
448
+ label:
449
+ section.registration.settings!.getLabel?.() ??
450
+ section.registration.settings!.label,
451
+ callback_data: `section:${section.token}:settings:open`,
452
+ });
453
+ registry.clearError(section.token, "settings_label");
454
+ } catch (error) {
455
+ registry.recordError(
456
+ section.token,
457
+ sectionErrorMessage(error),
458
+ "settings_label",
459
+ );
460
+ }
461
+ }
462
+ return rows;
416
463
  }
417
464
 
418
465
  /** @internal */
419
466
  export function getTelegramSectionMainMenuRows(
420
467
  registry: TelegramSectionRegistry,
421
468
  ): TelegramSectionMainMenuRow[] {
422
- return registry.getSections().map((s) => ({
423
- text: s.registration.getLabel?.() ?? s.label,
424
- callback_data: `section:${s.token}:open`,
425
- }));
469
+ const rows: TelegramSectionMainMenuRow[] = [];
470
+ for (const section of registry.getSections()) {
471
+ try {
472
+ rows.push({
473
+ text: section.registration.getLabel?.() ?? section.label,
474
+ callback_data: `section:${section.token}:open`,
475
+ });
476
+ registry.clearError(section.token, "main_label");
477
+ } catch (error) {
478
+ registry.recordError(
479
+ section.token,
480
+ sectionErrorMessage(error),
481
+ "main_label",
482
+ );
483
+ }
484
+ }
485
+ return rows;
426
486
  }
427
487
 
428
488
  /** @internal */
@@ -508,9 +568,11 @@ export async function handleTelegramSectionOpen(
508
568
  viewWithBack.replyMarkup,
509
569
  );
510
570
  await deps.answerCallbackQuery(callbackQueryId);
571
+ registry.clearError(token, "render");
511
572
  return true;
512
573
  } catch (error) {
513
- const message = error instanceof Error ? error.message : String(error);
574
+ const message = sectionErrorMessage(error);
575
+ registry.recordError(token, message, "render");
514
576
  await deps.answerCallbackQuery(
515
577
  callbackQueryId,
516
578
  `Section error: ${message}`,
@@ -537,10 +599,10 @@ export async function handleTelegramSectionCallback(
537
599
  );
538
600
  return true;
539
601
  }
540
- // Try main handleCallback first, then settings handleCallback as fallback
541
- const handler =
542
- section.registration.handleCallback ??
543
- section.registration.settings?.handleCallback;
602
+ // Try main handleCallback first, then settings handleCallback as fallback.
603
+ const mainHandler = section.registration.handleCallback;
604
+ const settingsHandler = section.registration.settings?.handleCallback;
605
+ const handler = mainHandler ?? settingsHandler;
544
606
  if (!handler) {
545
607
  await deps.answerCallbackQuery(callbackQueryId);
546
608
  return true;
@@ -555,16 +617,12 @@ export async function handleTelegramSectionCallback(
555
617
  payload,
556
618
  callbackQueryId,
557
619
  deps,
558
- `section:${token}:open`,
620
+ mainHandler ? `section:${token}:open` : "settings:list",
559
621
  );
560
622
  let result = await handler(ctx);
561
623
  // Fallback: if main handler passed and settings handler exists, try settings
562
- // with the correct navigation context (back → settings list)
563
- if (
564
- result === "pass" &&
565
- handler !== section.registration.settings?.handleCallback &&
566
- section.registration.settings?.handleCallback
567
- ) {
624
+ // with the correct navigation context (back → settings list).
625
+ if (result === "pass" && mainHandler && settingsHandler) {
568
626
  const settingsCtx = buildTelegramSectionCallbackContext(
569
627
  section.id,
570
628
  token,
@@ -576,14 +634,16 @@ export async function handleTelegramSectionCallback(
576
634
  deps,
577
635
  "settings:list",
578
636
  );
579
- result = await section.registration.settings.handleCallback(settingsCtx);
637
+ result = await settingsHandler(settingsCtx);
580
638
  }
581
639
  if (result === "pass") {
582
640
  await deps.answerCallbackQuery(callbackQueryId);
583
641
  }
642
+ registry.clearError(token, "callback");
584
643
  return true;
585
644
  } catch (error) {
586
- const message = error instanceof Error ? error.message : String(error);
645
+ const message = sectionErrorMessage(error);
646
+ registry.recordError(token, message, "callback");
587
647
  await deps.answerCallbackQuery(
588
648
  callbackQueryId,
589
649
  `Section error: ${message}`,
@@ -632,9 +692,11 @@ export async function handleTelegramSectionSettingsOpen(
632
692
  viewWithBack.replyMarkup,
633
693
  );
634
694
  await deps.answerCallbackQuery(callbackQueryId);
695
+ registry.clearError(token, "settings_open");
635
696
  return true;
636
697
  } catch (error) {
637
- const message = error instanceof Error ? error.message : String(error);
698
+ const message = sectionErrorMessage(error);
699
+ registry.recordError(token, message, "settings_open");
638
700
  await deps.answerCallbackQuery(
639
701
  callbackQueryId,
640
702
  `Section error: ${message}`,
@@ -677,9 +739,11 @@ export async function handleTelegramSectionSettingsCallback(
677
739
  if (result === "pass") {
678
740
  await deps.answerCallbackQuery(callbackQueryId);
679
741
  }
742
+ registry.clearError(token, "settings_callback");
680
743
  return true;
681
744
  } catch (error) {
682
- const message = error instanceof Error ? error.message : String(error);
745
+ const message = sectionErrorMessage(error);
746
+ registry.recordError(token, message, "settings_callback");
683
747
  await deps.answerCallbackQuery(
684
748
  callbackQueryId,
685
749
  `Section error: ${message}`,
package/lib/status.ts CHANGED
@@ -36,9 +36,24 @@ interface TelegramContextUsage {
36
36
  }
37
37
 
38
38
  export interface TelegramStatusActiveModel {
39
+ provider?: string;
40
+ id?: string;
39
41
  contextWindow?: number;
40
42
  }
41
43
 
44
+ export interface TelegramStatusLineProviderContext {
45
+ activeModel: TelegramStatusActiveModel | undefined;
46
+ }
47
+
48
+ export interface TelegramStatusLineProviderResult {
49
+ label: string;
50
+ value: string;
51
+ }
52
+
53
+ export type TelegramStatusLineProvider = (
54
+ ctx: TelegramStatusLineProviderContext,
55
+ ) => TelegramStatusLineProviderResult | undefined;
56
+
42
57
  export interface TelegramStatusContext {
43
58
  sessionManager: { getEntries(): TelegramStatusSessionEntry[] };
44
59
  getContextUsage(): TelegramContextUsage | undefined;
@@ -52,6 +67,8 @@ export interface TelegramStatusContext {
52
67
 
53
68
  export type TelegramRuntimeEventDetailValue = string | number | boolean | null;
54
69
 
70
+ const TELEGRAM_STATUS_LINE_PROVIDER_REGISTRY_KEY =
71
+ "__piTelegramStatusLineProviders__";
55
72
  const MAX_RECENT_TELEGRAM_RUNTIME_EVENTS = 10;
56
73
  const MAX_TELEGRAM_RUNTIME_EVENT_MESSAGE_LENGTH = 1000;
57
74
  const MAX_TELEGRAM_RUNTIME_EVENT_DETAIL_LENGTH = 1000;
@@ -166,7 +183,10 @@ export interface TelegramStatusRuntime<
166
183
  getStatusLines: () => string[];
167
184
  }
168
185
 
169
- function truncateTelegramRuntimeEventText(text: string, maxLength: number): string {
186
+ function truncateTelegramRuntimeEventText(
187
+ text: string,
188
+ maxLength: number,
189
+ ): string {
170
190
  if (text.length <= maxLength) return text;
171
191
  return `${text.slice(0, maxLength).trimEnd()}… [truncated ${text.length - maxLength} chars]`;
172
192
  }
@@ -262,6 +282,61 @@ export function recordTelegramRuntimeEvent(
262
282
  recordStructuredTelegramRuntimeEvent(events, { category, error }, options);
263
283
  }
264
284
 
285
+ function getOrCreateTelegramStatusLineProviderRegistry(): Map<
286
+ string,
287
+ TelegramStatusLineProvider
288
+ > {
289
+ const existing = (globalThis as Record<string, unknown>)[
290
+ TELEGRAM_STATUS_LINE_PROVIDER_REGISTRY_KEY
291
+ ];
292
+ if (existing instanceof Map)
293
+ return existing as Map<string, TelegramStatusLineProvider>;
294
+ const registry = new Map<string, TelegramStatusLineProvider>();
295
+ (globalThis as Record<string, unknown>)[
296
+ TELEGRAM_STATUS_LINE_PROVIDER_REGISTRY_KEY
297
+ ] = registry;
298
+ return registry;
299
+ }
300
+
301
+ /**
302
+ * Register a compact companion-extension line for the Telegram status menu.
303
+ *
304
+ * Providers are synchronous and should return undefined when their line is not
305
+ * relevant for the active model. Errors are isolated so optional companion
306
+ * status cannot break the core Telegram menu.
307
+ */
308
+ export function registerTelegramStatusLineProvider(
309
+ provider: TelegramStatusLineProvider,
310
+ options: { id: string },
311
+ ): () => void {
312
+ const registry = getOrCreateTelegramStatusLineProviderRegistry();
313
+ registry.set(options.id, provider);
314
+ return () => {
315
+ if (registry.get(options.id) === provider) registry.delete(options.id);
316
+ };
317
+ }
318
+
319
+ export function getTelegramStatusLineProviderResults(
320
+ ctx: TelegramStatusLineProviderContext,
321
+ ): TelegramStatusLineProviderResult[] {
322
+ const results: TelegramStatusLineProviderResult[] = [];
323
+ const registry = getOrCreateTelegramStatusLineProviderRegistry();
324
+ for (const provider of registry.values()) {
325
+ try {
326
+ const result = provider(ctx);
327
+ if (!result?.label || !result.value) continue;
328
+ results.push(result);
329
+ } catch {
330
+ continue;
331
+ }
332
+ }
333
+ return results;
334
+ }
335
+
336
+ export function clearTelegramStatusLineProviders(): void {
337
+ getOrCreateTelegramStatusLineProviderRegistry().clear();
338
+ }
339
+
265
340
  export function createTelegramRuntimeEventRecorder(
266
341
  options: TelegramRuntimeEventRecorderOptions,
267
342
  ): TelegramRuntimeEventRecorder {
@@ -314,7 +389,9 @@ function formatTelegramRuntimeEvent(event: TelegramRuntimeEvent): string {
314
389
  return `${new Date(event.at).toISOString()} ${formatTelegramRuntimeEventSummary(event)}`;
315
390
  }
316
391
 
317
- function buildTelegramRuntimeEventSummary(events: TelegramRuntimeEvent[]): string {
392
+ function buildTelegramRuntimeEventSummary(
393
+ events: TelegramRuntimeEvent[],
394
+ ): string {
318
395
  const counts = new Map<string, number>();
319
396
  for (const event of events) {
320
397
  const category = formatTelegramRuntimeEventCategory(event);
@@ -462,7 +539,7 @@ export function buildTelegramStatusBarText(
462
539
  ? theme.fg("success", state.queuedStatus)
463
540
  : "";
464
541
  if (state.compactionInProgress) {
465
- return `${label} ${theme.fg("accent", "compacting")}${queued}`;
542
+ return `${label} ${theme.fg("warning", "compacting")}${queued}`;
466
543
  }
467
544
  if (state.processing) {
468
545
  const processingStatus = state.queuedStatus
@@ -553,8 +630,13 @@ function collectUsageStats(ctx: TelegramStatusContext): TelegramUsageStats {
553
630
  return stats;
554
631
  }
555
632
 
633
+ function formatStatusRowLabel(label: string): string {
634
+ if (!label) return label;
635
+ return `${label[0]?.toUpperCase() ?? ""}${label.slice(1)}`;
636
+ }
637
+
556
638
  function buildStatusRow(label: string, value: string): string {
557
- return `<b>${escapeHtml(label)}:</b> <code>${escapeHtml(value)}</code>`;
639
+ return `<b>${escapeHtml(formatStatusRowLabel(label))}:</b> <code>${escapeHtml(value)}</code>`;
558
640
  }
559
641
 
560
642
  function buildUsageSummary(stats: TelegramUsageStats): string | undefined {
@@ -613,5 +695,8 @@ export function buildStatusHtml(
613
695
  lines.push(buildStatusRow("Cost", costSummary));
614
696
  }
615
697
  lines.push(buildStatusRow("Context", buildContextSummary(ctx, activeModel)));
698
+ for (const row of getTelegramStatusLineProviderResults({ activeModel })) {
699
+ lines.push(buildStatusRow(row.label, row.value));
700
+ }
616
701
  return lines.join("\n");
617
702
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.13.2",
3
+ "version": "0.15.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -50,6 +50,7 @@
50
50
  "./outbound": "./api/outbound.ts",
51
51
  "./updates": "./api/updates.ts",
52
52
  "./sections": "./api/sections.ts",
53
+ "./status": "./api/status.ts",
53
54
  "./voice": "./api/voice.ts",
54
55
  "./keyboard": "./api/keyboard.ts"
55
56
  },