@openacp/cli 0.6.0 → 0.6.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 (93) hide show
  1. package/README.md +11 -2
  2. package/dist/{admin-IKPS5PFC.js → admin-IVQTC72V.js} +2 -2
  3. package/dist/{agent-catalog-T5ECPEDA.js → agent-catalog-IVU2KANH.js} +2 -2
  4. package/dist/{agents-55NX3DHM.js → agents-SXIY4IEF.js} +2 -2
  5. package/dist/{chunk-6Q7PZWCL.js → chunk-2OFIWTYD.js} +3 -3
  6. package/dist/{chunk-H7ZMPBZC.js → chunk-3KGRVAEV.js} +1 -1
  7. package/dist/chunk-3KGRVAEV.js.map +1 -0
  8. package/dist/{chunk-IURZ4QHG.js → chunk-7QJS2XBD.js} +2 -1
  9. package/dist/chunk-7QJS2XBD.js.map +1 -0
  10. package/dist/{chunk-MHFCZGRW.js → chunk-7WQH4SOY.js} +15 -5
  11. package/dist/{chunk-MHFCZGRW.js.map → chunk-7WQH4SOY.js.map} +1 -1
  12. package/dist/{chunk-J6X5SW6O.js → chunk-CKOK7JW6.js} +3 -2
  13. package/dist/{chunk-J6X5SW6O.js.map → chunk-CKOK7JW6.js.map} +1 -1
  14. package/dist/{chunk-DWQKUECJ.js → chunk-EWYNCHUH.js} +68 -17
  15. package/dist/chunk-EWYNCHUH.js.map +1 -0
  16. package/dist/{chunk-Z46LGZ7R.js → chunk-F3AICYO4.js} +56 -1
  17. package/dist/chunk-F3AICYO4.js.map +1 -0
  18. package/dist/{chunk-3WPG7GXA.js → chunk-FF4C3ZE4.js} +2 -2
  19. package/dist/chunk-FF4C3ZE4.js.map +1 -0
  20. package/dist/{chunk-5NBWM7P6.js → chunk-FMWSVLRM.js} +35 -2
  21. package/dist/chunk-FMWSVLRM.js.map +1 -0
  22. package/dist/{chunk-THBR6OXH.js → chunk-HSGUPJU5.js} +1 -1
  23. package/dist/chunk-HSGUPJU5.js.map +1 -0
  24. package/dist/{chunk-V2V767XI.js → chunk-IFTYEG5J.js} +2439 -957
  25. package/dist/chunk-IFTYEG5J.js.map +1 -0
  26. package/dist/{chunk-7G5QKLLF.js → chunk-IUIMBEBX.js} +1 -1
  27. package/dist/chunk-IUIMBEBX.js.map +1 -0
  28. package/dist/{chunk-YYQXWA62.js → chunk-KO5RL7MZ.js} +2 -2
  29. package/dist/{chunk-AKIU4JBF.js → chunk-ONENT7JQ.js} +2 -2
  30. package/dist/chunk-ONENT7JQ.js.map +1 -0
  31. package/dist/{chunk-437NLISU.js → chunk-TMCQZAXN.js} +2 -2
  32. package/dist/chunk-TMCQZAXN.js.map +1 -0
  33. package/dist/{chunk-T22OLSET.js → chunk-TTDSLV35.js} +1 -1
  34. package/dist/chunk-TTDSLV35.js.map +1 -0
  35. package/dist/{chunk-SPX7CKWV.js → chunk-WQZ4RXH7.js} +2 -2
  36. package/dist/cli.js +41 -36
  37. package/dist/cli.js.map +1 -1
  38. package/dist/{config-KF2MQWAP.js → config-4YSJ4NCI.js} +2 -2
  39. package/dist/{config-editor-OTODXUF7.js → config-editor-TOZUBMO7.js} +4 -4
  40. package/dist/{config-registry-SNKA2EH2.js → config-registry-7I6GGDOY.js} +2 -2
  41. package/dist/{daemon-U6UC7OM4.js → daemon-I6XMRQ6P.js} +3 -3
  42. package/dist/{discord-SLLKRUP7.js → discord-7B5NWW5Z.js} +154 -146
  43. package/dist/discord-7B5NWW5Z.js.map +1 -0
  44. package/dist/{doctor-DB5PRQ6D.js → doctor-FR5GASOQ.js} +4 -4
  45. package/dist/doctor-UOH7YCT2.js +9 -0
  46. package/dist/index.d.ts +475 -72
  47. package/dist/index.js +29 -11
  48. package/dist/{integrate-VOUYBPPZ.js → integrate-QTK4PPYQ.js} +15 -6
  49. package/dist/integrate-QTK4PPYQ.js.map +1 -0
  50. package/dist/{main-M6RH3SS5.js → main-46BVXFWI.js} +20 -19
  51. package/dist/main-46BVXFWI.js.map +1 -0
  52. package/dist/{menu-J5YVH665.js → menu-XR2GET2B.js} +2 -2
  53. package/dist/{new-session-DRRP2J7E.js → new-session-BVNE6S3A.js} +3 -3
  54. package/dist/{session-FVFLBREJ.js → session-ZMAM67AA.js} +2 -2
  55. package/dist/{settings-LPOLJ6SA.js → settings-LQ57CFY4.js} +2 -2
  56. package/dist/{setup-LI5CKYDK.js → setup-DZXZTQRD.js} +3 -3
  57. package/dist/{tunnel-service-U6V4HQOO.js → tunnel-service-O5EKGFLO.js} +19 -1
  58. package/dist/tunnel-service-O5EKGFLO.js.map +1 -0
  59. package/package.json +2 -1
  60. package/dist/chunk-3WPG7GXA.js.map +0 -1
  61. package/dist/chunk-437NLISU.js.map +0 -1
  62. package/dist/chunk-5NBWM7P6.js.map +0 -1
  63. package/dist/chunk-7G5QKLLF.js.map +0 -1
  64. package/dist/chunk-AKIU4JBF.js.map +0 -1
  65. package/dist/chunk-DWQKUECJ.js.map +0 -1
  66. package/dist/chunk-H7ZMPBZC.js.map +0 -1
  67. package/dist/chunk-IURZ4QHG.js.map +0 -1
  68. package/dist/chunk-T22OLSET.js.map +0 -1
  69. package/dist/chunk-THBR6OXH.js.map +0 -1
  70. package/dist/chunk-V2V767XI.js.map +0 -1
  71. package/dist/chunk-Z46LGZ7R.js.map +0 -1
  72. package/dist/discord-SLLKRUP7.js.map +0 -1
  73. package/dist/doctor-SYWNJFYK.js +0 -9
  74. package/dist/integrate-VOUYBPPZ.js.map +0 -1
  75. package/dist/main-M6RH3SS5.js.map +0 -1
  76. package/dist/tunnel-service-U6V4HQOO.js.map +0 -1
  77. /package/dist/{admin-IKPS5PFC.js.map → admin-IVQTC72V.js.map} +0 -0
  78. /package/dist/{agent-catalog-T5ECPEDA.js.map → agent-catalog-IVU2KANH.js.map} +0 -0
  79. /package/dist/{agents-55NX3DHM.js.map → agents-SXIY4IEF.js.map} +0 -0
  80. /package/dist/{chunk-6Q7PZWCL.js.map → chunk-2OFIWTYD.js.map} +0 -0
  81. /package/dist/{chunk-YYQXWA62.js.map → chunk-KO5RL7MZ.js.map} +0 -0
  82. /package/dist/{chunk-SPX7CKWV.js.map → chunk-WQZ4RXH7.js.map} +0 -0
  83. /package/dist/{config-KF2MQWAP.js.map → config-4YSJ4NCI.js.map} +0 -0
  84. /package/dist/{config-editor-OTODXUF7.js.map → config-editor-TOZUBMO7.js.map} +0 -0
  85. /package/dist/{config-registry-SNKA2EH2.js.map → config-registry-7I6GGDOY.js.map} +0 -0
  86. /package/dist/{daemon-U6UC7OM4.js.map → daemon-I6XMRQ6P.js.map} +0 -0
  87. /package/dist/{doctor-DB5PRQ6D.js.map → doctor-FR5GASOQ.js.map} +0 -0
  88. /package/dist/{doctor-SYWNJFYK.js.map → doctor-UOH7YCT2.js.map} +0 -0
  89. /package/dist/{menu-J5YVH665.js.map → menu-XR2GET2B.js.map} +0 -0
  90. /package/dist/{new-session-DRRP2J7E.js.map → new-session-BVNE6S3A.js.map} +0 -0
  91. /package/dist/{session-FVFLBREJ.js.map → session-ZMAM67AA.js.map} +0 -0
  92. /package/dist/{settings-LPOLJ6SA.js.map → settings-LQ57CFY4.js.map} +0 -0
  93. /package/dist/{setup-LI5CKYDK.js.map → setup-DZXZTQRD.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { z } from 'zod';
3
3
  import { EventEmitter } from 'node:events';
4
4
  import { Readable, Writable } from 'node:stream';
5
5
  import { PromptResponse } from '@agentclientprotocol/sdk';
6
+ import * as http from 'node:http';
6
7
 
7
8
  interface Attachment {
8
9
  type: 'image' | 'audio' | 'file';
@@ -10,6 +11,7 @@ interface Attachment {
10
11
  fileName: string;
11
12
  mimeType: string;
12
13
  size: number;
14
+ originalFilePath?: string;
13
15
  }
14
16
  interface IncomingMessage {
15
17
  channelId: string;
@@ -19,7 +21,7 @@ interface IncomingMessage {
19
21
  attachments?: Attachment[];
20
22
  }
21
23
  interface OutgoingMessage {
22
- type: "text" | "thought" | "tool_call" | "tool_update" | "plan" | "usage" | "session_end" | "error" | "attachment";
24
+ type: "text" | "thought" | "tool_call" | "tool_update" | "plan" | "usage" | "session_end" | "error" | "attachment" | "system_message";
23
25
  text: string;
24
26
  metadata?: Record<string, unknown>;
25
27
  attachment?: Attachment;
@@ -37,7 +39,7 @@ interface PermissionOption {
37
39
  interface NotificationMessage {
38
40
  sessionId: string;
39
41
  sessionName?: string;
40
- type: "completed" | "error" | "permission" | "input_required";
42
+ type: "completed" | "error" | "permission" | "input_required" | "budget_warning";
41
43
  summary: string;
42
44
  deepLink?: string;
43
45
  }
@@ -100,6 +102,9 @@ type AgentEvent = {
100
102
  } | {
101
103
  type: "error";
102
104
  message: string;
105
+ } | {
106
+ type: "system_message";
107
+ message: string;
103
108
  };
104
109
  interface PlanEntry {
105
110
  content: string;
@@ -209,6 +214,26 @@ interface TelegramPlatformData {
209
214
  topicId: number;
210
215
  skillMsgId?: number;
211
216
  }
217
+ interface UsageRecord {
218
+ id: string;
219
+ sessionId: string;
220
+ agentName: string;
221
+ tokensUsed: number;
222
+ contextSize: number;
223
+ cost?: {
224
+ amount: number;
225
+ currency: string;
226
+ };
227
+ timestamp: string;
228
+ }
229
+ interface UsageSummary {
230
+ period: "today" | "week" | "month" | "all";
231
+ totalTokens: number;
232
+ totalCost: number;
233
+ currency: string;
234
+ sessionCount: number;
235
+ recordCount: number;
236
+ }
212
237
  interface DiscordPlatformData {
213
238
  threadId: string;
214
239
  skillMsgId?: string;
@@ -276,6 +301,26 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
276
301
  } | undefined;
277
302
  }>>;
278
303
  type TunnelConfig = z.infer<typeof TunnelSchema>;
304
+ declare const UsageSchema: z.ZodDefault<z.ZodObject<{
305
+ enabled: z.ZodDefault<z.ZodBoolean>;
306
+ monthlyBudget: z.ZodOptional<z.ZodNumber>;
307
+ warningThreshold: z.ZodDefault<z.ZodNumber>;
308
+ currency: z.ZodDefault<z.ZodString>;
309
+ retentionDays: z.ZodDefault<z.ZodNumber>;
310
+ }, "strip", z.ZodTypeAny, {
311
+ enabled: boolean;
312
+ warningThreshold: number;
313
+ currency: string;
314
+ retentionDays: number;
315
+ monthlyBudget?: number | undefined;
316
+ }, {
317
+ enabled?: boolean | undefined;
318
+ monthlyBudget?: number | undefined;
319
+ warningThreshold?: number | undefined;
320
+ currency?: string | undefined;
321
+ retentionDays?: number | undefined;
322
+ }>>;
323
+ type UsageConfig = z.infer<typeof UsageSchema>;
279
324
  declare const ConfigSchema: z.ZodObject<{
280
325
  channels: z.ZodRecord<z.ZodString, z.ZodObject<{
281
326
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -300,8 +345,8 @@ declare const ConfigSchema: z.ZodObject<{
300
345
  }, {
301
346
  command: string;
302
347
  args?: string[] | undefined;
303
- workingDirectory?: string | undefined;
304
348
  env?: Record<string, string> | undefined;
349
+ workingDirectory?: string | undefined;
305
350
  }>>>>;
306
351
  defaultAgent: z.ZodString;
307
352
  workspace: z.ZodDefault<z.ZodObject<{
@@ -402,6 +447,25 @@ declare const ConfigSchema: z.ZodObject<{
402
447
  token?: string | undefined;
403
448
  } | undefined;
404
449
  }>>;
450
+ usage: z.ZodDefault<z.ZodObject<{
451
+ enabled: z.ZodDefault<z.ZodBoolean>;
452
+ monthlyBudget: z.ZodOptional<z.ZodNumber>;
453
+ warningThreshold: z.ZodDefault<z.ZodNumber>;
454
+ currency: z.ZodDefault<z.ZodString>;
455
+ retentionDays: z.ZodDefault<z.ZodNumber>;
456
+ }, "strip", z.ZodTypeAny, {
457
+ enabled: boolean;
458
+ warningThreshold: number;
459
+ currency: string;
460
+ retentionDays: number;
461
+ monthlyBudget?: number | undefined;
462
+ }, {
463
+ enabled?: boolean | undefined;
464
+ monthlyBudget?: number | undefined;
465
+ warningThreshold?: number | undefined;
466
+ currency?: string | undefined;
467
+ retentionDays?: number | undefined;
468
+ }>>;
405
469
  integrations: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
406
470
  installed: z.ZodBoolean;
407
471
  installedAt: z.ZodOptional<z.ZodString>;
@@ -412,6 +476,88 @@ declare const ConfigSchema: z.ZodObject<{
412
476
  installed: boolean;
413
477
  installedAt?: string | undefined;
414
478
  }>>>;
479
+ speech: z.ZodDefault<z.ZodOptional<z.ZodObject<{
480
+ stt: z.ZodDefault<z.ZodObject<{
481
+ provider: z.ZodDefault<z.ZodNullable<z.ZodString>>;
482
+ providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
483
+ apiKey: z.ZodOptional<z.ZodString>;
484
+ model: z.ZodOptional<z.ZodString>;
485
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
486
+ apiKey: z.ZodOptional<z.ZodString>;
487
+ model: z.ZodOptional<z.ZodString>;
488
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
489
+ apiKey: z.ZodOptional<z.ZodString>;
490
+ model: z.ZodOptional<z.ZodString>;
491
+ }, z.ZodTypeAny, "passthrough">>>>;
492
+ }, "strip", z.ZodTypeAny, {
493
+ provider: string | null;
494
+ providers: Record<string, z.objectOutputType<{
495
+ apiKey: z.ZodOptional<z.ZodString>;
496
+ model: z.ZodOptional<z.ZodString>;
497
+ }, z.ZodTypeAny, "passthrough">>;
498
+ }, {
499
+ provider?: string | null | undefined;
500
+ providers?: Record<string, z.objectInputType<{
501
+ apiKey: z.ZodOptional<z.ZodString>;
502
+ model: z.ZodOptional<z.ZodString>;
503
+ }, z.ZodTypeAny, "passthrough">> | undefined;
504
+ }>>;
505
+ tts: z.ZodDefault<z.ZodObject<{
506
+ provider: z.ZodDefault<z.ZodNullable<z.ZodString>>;
507
+ providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
508
+ apiKey: z.ZodOptional<z.ZodString>;
509
+ model: z.ZodOptional<z.ZodString>;
510
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
511
+ apiKey: z.ZodOptional<z.ZodString>;
512
+ model: z.ZodOptional<z.ZodString>;
513
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
514
+ apiKey: z.ZodOptional<z.ZodString>;
515
+ model: z.ZodOptional<z.ZodString>;
516
+ }, z.ZodTypeAny, "passthrough">>>>;
517
+ }, "strip", z.ZodTypeAny, {
518
+ provider: string | null;
519
+ providers: Record<string, z.objectOutputType<{
520
+ apiKey: z.ZodOptional<z.ZodString>;
521
+ model: z.ZodOptional<z.ZodString>;
522
+ }, z.ZodTypeAny, "passthrough">>;
523
+ }, {
524
+ provider?: string | null | undefined;
525
+ providers?: Record<string, z.objectInputType<{
526
+ apiKey: z.ZodOptional<z.ZodString>;
527
+ model: z.ZodOptional<z.ZodString>;
528
+ }, z.ZodTypeAny, "passthrough">> | undefined;
529
+ }>>;
530
+ }, "strip", z.ZodTypeAny, {
531
+ stt: {
532
+ provider: string | null;
533
+ providers: Record<string, z.objectOutputType<{
534
+ apiKey: z.ZodOptional<z.ZodString>;
535
+ model: z.ZodOptional<z.ZodString>;
536
+ }, z.ZodTypeAny, "passthrough">>;
537
+ };
538
+ tts: {
539
+ provider: string | null;
540
+ providers: Record<string, z.objectOutputType<{
541
+ apiKey: z.ZodOptional<z.ZodString>;
542
+ model: z.ZodOptional<z.ZodString>;
543
+ }, z.ZodTypeAny, "passthrough">>;
544
+ };
545
+ }, {
546
+ stt?: {
547
+ provider?: string | null | undefined;
548
+ providers?: Record<string, z.objectInputType<{
549
+ apiKey: z.ZodOptional<z.ZodString>;
550
+ model: z.ZodOptional<z.ZodString>;
551
+ }, z.ZodTypeAny, "passthrough">> | undefined;
552
+ } | undefined;
553
+ tts?: {
554
+ provider?: string | null | undefined;
555
+ providers?: Record<string, z.objectInputType<{
556
+ apiKey: z.ZodOptional<z.ZodString>;
557
+ model: z.ZodOptional<z.ZodString>;
558
+ }, z.ZodTypeAny, "passthrough">> | undefined;
559
+ } | undefined;
560
+ }>>>;
415
561
  }, "strip", z.ZodTypeAny, {
416
562
  api: {
417
563
  port: number;
@@ -460,10 +606,33 @@ declare const ConfigSchema: z.ZodObject<{
460
606
  sessionStore: {
461
607
  ttlDays: number;
462
608
  };
609
+ usage: {
610
+ enabled: boolean;
611
+ warningThreshold: number;
612
+ currency: string;
613
+ retentionDays: number;
614
+ monthlyBudget?: number | undefined;
615
+ };
463
616
  integrations: Record<string, {
464
617
  installed: boolean;
465
618
  installedAt?: string | undefined;
466
619
  }>;
620
+ speech: {
621
+ stt: {
622
+ provider: string | null;
623
+ providers: Record<string, z.objectOutputType<{
624
+ apiKey: z.ZodOptional<z.ZodString>;
625
+ model: z.ZodOptional<z.ZodString>;
626
+ }, z.ZodTypeAny, "passthrough">>;
627
+ };
628
+ tts: {
629
+ provider: string | null;
630
+ providers: Record<string, z.objectOutputType<{
631
+ apiKey: z.ZodOptional<z.ZodString>;
632
+ model: z.ZodOptional<z.ZodString>;
633
+ }, z.ZodTypeAny, "passthrough">>;
634
+ };
635
+ };
467
636
  }, {
468
637
  channels: Record<string, z.objectInputType<{
469
638
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -477,8 +646,8 @@ declare const ConfigSchema: z.ZodObject<{
477
646
  agents?: Record<string, {
478
647
  command: string;
479
648
  args?: string[] | undefined;
480
- workingDirectory?: string | undefined;
481
649
  env?: Record<string, string> | undefined;
650
+ workingDirectory?: string | undefined;
482
651
  }> | undefined;
483
652
  tunnel?: {
484
653
  options?: Record<string, unknown> | undefined;
@@ -512,10 +681,33 @@ declare const ConfigSchema: z.ZodObject<{
512
681
  sessionStore?: {
513
682
  ttlDays?: number | undefined;
514
683
  } | undefined;
684
+ usage?: {
685
+ enabled?: boolean | undefined;
686
+ monthlyBudget?: number | undefined;
687
+ warningThreshold?: number | undefined;
688
+ currency?: string | undefined;
689
+ retentionDays?: number | undefined;
690
+ } | undefined;
515
691
  integrations?: Record<string, {
516
692
  installed: boolean;
517
693
  installedAt?: string | undefined;
518
694
  }> | undefined;
695
+ speech?: {
696
+ stt?: {
697
+ provider?: string | null | undefined;
698
+ providers?: Record<string, z.objectInputType<{
699
+ apiKey: z.ZodOptional<z.ZodString>;
700
+ model: z.ZodOptional<z.ZodString>;
701
+ }, z.ZodTypeAny, "passthrough">> | undefined;
702
+ } | undefined;
703
+ tts?: {
704
+ provider?: string | null | undefined;
705
+ providers?: Record<string, z.objectInputType<{
706
+ apiKey: z.ZodOptional<z.ZodString>;
707
+ model: z.ZodOptional<z.ZodString>;
708
+ }, z.ZodTypeAny, "passthrough">> | undefined;
709
+ } | undefined;
710
+ } | undefined;
519
711
  }>;
520
712
  type Config = z.infer<typeof ConfigSchema>;
521
713
  declare function expandHome(p: string): string;
@@ -575,7 +767,7 @@ interface IChannelAdapter {
575
767
  * Adapters can extend this or implement IChannelAdapter directly.
576
768
  */
577
769
  declare abstract class ChannelAdapter<TCore = unknown> implements IChannelAdapter {
578
- protected core: TCore;
770
+ readonly core: TCore;
579
771
  protected config: ChannelConfig;
580
772
  constructor(core: TCore, config: ChannelConfig);
581
773
  abstract start(): Promise<void>;
@@ -588,6 +780,9 @@ declare abstract class ChannelAdapter<TCore = unknown> implements IChannelAdapte
588
780
  deleteSessionThread(_sessionId: string): Promise<void>;
589
781
  sendSkillCommands(_sessionId: string, _commands: AgentCommand[]): Promise<void>;
590
782
  cleanupSkillCommands(_sessionId: string): Promise<void>;
783
+ archiveSessionTopic(_sessionId: string): Promise<{
784
+ newThreadId: string;
785
+ } | null>;
591
786
  }
592
787
 
593
788
  declare class NotificationManager {
@@ -608,7 +803,45 @@ declare class StderrCapture {
608
803
  getLastLines(): string;
609
804
  }
610
805
 
611
- declare class AgentInstance {
806
+ /**
807
+ * A minimal, generic typed event emitter.
808
+ *
809
+ * Usage:
810
+ * interface MyEvents {
811
+ * data: (payload: string) => void
812
+ * error: (err: Error) => void
813
+ * }
814
+ * const emitter = new TypedEmitter<MyEvents>()
815
+ * emitter.on('data', (payload) => { ... })
816
+ * emitter.emit('data', 'hello')
817
+ */
818
+ declare class TypedEmitter<T extends Record<string & keyof T, (...args: any[]) => void>> {
819
+ private listeners;
820
+ private paused;
821
+ private buffer;
822
+ on<K extends keyof T>(event: K, listener: T[K]): this;
823
+ off<K extends keyof T>(event: K, listener: T[K]): this;
824
+ emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void;
825
+ /**
826
+ * Pause event delivery. Events emitted while paused are buffered.
827
+ * Optionally pass a filter to allow specific events through even while paused.
828
+ */
829
+ pause(passthrough?: (event: keyof T, args: unknown[]) => boolean): void;
830
+ private passthroughFn?;
831
+ /** Resume event delivery and replay buffered events in order. */
832
+ resume(): void;
833
+ /** Discard all buffered events without delivering them. */
834
+ clearBuffer(): void;
835
+ get isPaused(): boolean;
836
+ get bufferSize(): number;
837
+ removeAllListeners(event?: keyof T): void;
838
+ private deliver;
839
+ }
840
+
841
+ interface AgentInstanceEvents {
842
+ agent_event: (event: AgentEvent) => void;
843
+ }
844
+ declare class AgentInstance extends TypedEmitter<AgentInstanceEvents> {
612
845
  private connection;
613
846
  private child;
614
847
  private stderrCapture;
@@ -619,7 +852,6 @@ declare class AgentInstance {
619
852
  image?: boolean;
620
853
  audio?: boolean;
621
854
  };
622
- onSessionUpdate: (event: AgentEvent) => void;
623
855
  onPermissionRequest: (request: PermissionRequest) => Promise<string>;
624
856
  private constructor();
625
857
  private static spawnSubprocess;
@@ -686,41 +918,6 @@ declare class AgentManager {
686
918
  resume(agentName: string, workingDirectory: string, agentSessionId: string): Promise<AgentInstance>;
687
919
  }
688
920
 
689
- /**
690
- * A minimal, generic typed event emitter.
691
- *
692
- * Usage:
693
- * interface MyEvents {
694
- * data: (payload: string) => void
695
- * error: (err: Error) => void
696
- * }
697
- * const emitter = new TypedEmitter<MyEvents>()
698
- * emitter.on('data', (payload) => { ... })
699
- * emitter.emit('data', 'hello')
700
- */
701
- declare class TypedEmitter<T extends Record<string & keyof T, (...args: any[]) => void>> {
702
- private listeners;
703
- private paused;
704
- private buffer;
705
- on<K extends keyof T>(event: K, listener: T[K]): this;
706
- off<K extends keyof T>(event: K, listener: T[K]): this;
707
- emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void;
708
- /**
709
- * Pause event delivery. Events emitted while paused are buffered.
710
- * Optionally pass a filter to allow specific events through even while paused.
711
- */
712
- pause(passthrough?: (event: keyof T, args: unknown[]) => boolean): void;
713
- private passthroughFn?;
714
- /** Resume event delivery and replay buffered events in order. */
715
- resume(): void;
716
- /** Discard all buffered events without delivering them. */
717
- clearBuffer(): void;
718
- get isPaused(): boolean;
719
- get bufferSize(): number;
720
- removeAllListeners(event?: keyof T): void;
721
- private deliver;
722
- }
723
-
724
921
  /**
725
922
  * Encapsulates pending permission state with a typed Promise API.
726
923
  */
@@ -743,6 +940,70 @@ declare class PermissionGate {
743
940
  private cleanup;
744
941
  }
745
942
 
943
+ interface STTOptions {
944
+ language?: string;
945
+ model?: string;
946
+ }
947
+ interface STTResult {
948
+ text: string;
949
+ language?: string;
950
+ duration?: number;
951
+ }
952
+ interface TTSOptions {
953
+ language?: string;
954
+ voice?: string;
955
+ model?: string;
956
+ }
957
+ interface TTSResult {
958
+ audioBuffer: Buffer;
959
+ mimeType: string;
960
+ }
961
+ interface STTProvider {
962
+ readonly name: string;
963
+ transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult>;
964
+ }
965
+ interface TTSProvider {
966
+ readonly name: string;
967
+ synthesize(text: string, options?: TTSOptions): Promise<TTSResult>;
968
+ }
969
+ interface SpeechProviderConfig {
970
+ apiKey?: string;
971
+ model?: string;
972
+ [key: string]: unknown;
973
+ }
974
+ interface SpeechServiceConfig {
975
+ stt: {
976
+ provider: string | null;
977
+ providers: Record<string, SpeechProviderConfig>;
978
+ };
979
+ tts: {
980
+ provider: string | null;
981
+ providers: Record<string, SpeechProviderConfig>;
982
+ };
983
+ }
984
+
985
+ declare class SpeechService {
986
+ private config;
987
+ private sttProviders;
988
+ private ttsProviders;
989
+ constructor(config: SpeechServiceConfig);
990
+ registerSTTProvider(name: string, provider: STTProvider): void;
991
+ registerTTSProvider(name: string, provider: TTSProvider): void;
992
+ isSTTAvailable(): boolean;
993
+ isTTSAvailable(): boolean;
994
+ transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult>;
995
+ synthesize(text: string, options?: TTSOptions): Promise<TTSResult>;
996
+ updateConfig(config: SpeechServiceConfig): void;
997
+ }
998
+
999
+ declare class GroqSTT implements STTProvider {
1000
+ private apiKey;
1001
+ private defaultModel;
1002
+ readonly name = "groq";
1003
+ constructor(apiKey: string, defaultModel?: string);
1004
+ transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult>;
1005
+ }
1006
+
746
1007
  interface SessionEvents {
747
1008
  agent_event: (event: AgentEvent) => void;
748
1009
  permission_request: (request: PermissionRequest) => void;
@@ -762,16 +1023,20 @@ declare class Session extends TypedEmitter<SessionEvents> {
762
1023
  private _status;
763
1024
  name?: string;
764
1025
  createdAt: Date;
1026
+ voiceMode: "off" | "next" | "on";
765
1027
  dangerousMode: boolean;
1028
+ archiving: boolean;
766
1029
  log: Logger;
767
1030
  readonly permissionGate: PermissionGate;
768
1031
  private readonly queue;
1032
+ private speechService?;
769
1033
  constructor(opts: {
770
1034
  id?: string;
771
1035
  channelId: string;
772
1036
  agentName: string;
773
1037
  workingDirectory: string;
774
1038
  agentInstance: AgentInstance;
1039
+ speechService?: SpeechService;
775
1040
  });
776
1041
  get status(): SessionStatus;
777
1042
  /** Transition to active — from initializing, error, or cancelled */
@@ -786,8 +1051,11 @@ declare class Session extends TypedEmitter<SessionEvents> {
786
1051
  /** Number of prompts waiting in queue */
787
1052
  get queueDepth(): number;
788
1053
  get promptRunning(): boolean;
1054
+ setVoiceMode(mode: "off" | "next" | "on"): void;
789
1055
  enqueuePrompt(text: string, attachments?: Attachment[]): Promise<void>;
790
1056
  private processPrompt;
1057
+ private maybeTranscribeAudio;
1058
+ private processTTSResponse;
791
1059
  private autoName;
792
1060
  /** Fire-and-forget warm-up: primes model cache while user types their first message */
793
1061
  warmup(): Promise<void>;
@@ -908,9 +1176,38 @@ interface SessionStore {
908
1176
  remove(sessionId: string): Promise<void>;
909
1177
  }
910
1178
 
1179
+ interface EventBusEvents {
1180
+ "session:created": (data: {
1181
+ sessionId: string;
1182
+ agent: string;
1183
+ status: SessionStatus;
1184
+ }) => void;
1185
+ "session:updated": (data: {
1186
+ sessionId: string;
1187
+ status?: SessionStatus;
1188
+ name?: string;
1189
+ dangerousMode?: boolean;
1190
+ }) => void;
1191
+ "session:deleted": (data: {
1192
+ sessionId: string;
1193
+ }) => void;
1194
+ "agent:event": (data: {
1195
+ sessionId: string;
1196
+ event: AgentEvent;
1197
+ }) => void;
1198
+ "permission:request": (data: {
1199
+ sessionId: string;
1200
+ permission: PermissionRequest;
1201
+ }) => void;
1202
+ }
1203
+ declare class EventBus extends TypedEmitter<EventBusEvents> {
1204
+ }
1205
+
911
1206
  declare class SessionManager {
912
1207
  private sessions;
913
1208
  private store;
1209
+ private eventBus?;
1210
+ setEventBus(eventBus: EventBus): void;
914
1211
  constructor(store?: SessionStore | null);
915
1212
  createSession(channelId: string, agentName: string, workingDirectory: string, agentManager: AgentManager): Promise<Session>;
916
1213
  getSession(sessionId: string): Session | undefined;
@@ -930,10 +1227,23 @@ declare class SessionManager {
930
1227
  destroyAll(): Promise<void>;
931
1228
  }
932
1229
 
1230
+ declare class SecurityGuard {
1231
+ private configManager;
1232
+ private sessionManager;
1233
+ constructor(configManager: ConfigManager, sessionManager: SessionManager);
1234
+ checkAccess(message: IncomingMessage): {
1235
+ allowed: true;
1236
+ } | {
1237
+ allowed: false;
1238
+ reason: string;
1239
+ };
1240
+ }
1241
+
933
1242
  interface BridgeDeps {
934
1243
  messageTransformer: MessageTransformer;
935
1244
  notificationManager: NotificationManager;
936
1245
  sessionManager: SessionManager;
1246
+ eventBus?: EventBus;
937
1247
  fileService?: FileService;
938
1248
  }
939
1249
  declare class SessionBridge {
@@ -942,6 +1252,7 @@ declare class SessionBridge {
942
1252
  private deps;
943
1253
  private connected;
944
1254
  private agentEventHandler?;
1255
+ private sessionEventHandler?;
945
1256
  private statusChangeHandler?;
946
1257
  private namedHandler?;
947
1258
  constructor(session: Session, adapter: ChannelAdapter, deps: BridgeDeps);
@@ -953,6 +1264,71 @@ declare class SessionBridge {
953
1264
  private wireLifecycle;
954
1265
  }
955
1266
 
1267
+ declare class UsageStore {
1268
+ private filePath;
1269
+ private retentionDays;
1270
+ private records;
1271
+ private debounceTimer;
1272
+ private cleanupInterval;
1273
+ private flushHandler;
1274
+ constructor(filePath: string, retentionDays: number);
1275
+ append(record: UsageRecord): void;
1276
+ query(period: "today" | "week" | "month" | "all"): UsageSummary;
1277
+ getMonthlyTotal(): {
1278
+ totalCost: number;
1279
+ currency: string;
1280
+ };
1281
+ cleanup(): void;
1282
+ flushSync(): void;
1283
+ destroy(): void;
1284
+ private load;
1285
+ private getCutoff;
1286
+ private scheduleDiskWrite;
1287
+ }
1288
+
1289
+ declare class UsageBudget {
1290
+ private store;
1291
+ private config;
1292
+ private now;
1293
+ private lastNotifiedStatus;
1294
+ private lastNotifiedMonth;
1295
+ constructor(store: UsageStore, config: UsageConfig, now?: () => Date);
1296
+ check(): {
1297
+ status: "ok" | "warning" | "exceeded";
1298
+ message?: string;
1299
+ };
1300
+ getStatus(): {
1301
+ status: "ok" | "warning" | "exceeded";
1302
+ used: number;
1303
+ budget: number;
1304
+ percent: number;
1305
+ };
1306
+ }
1307
+
1308
+ interface SessionCreateParams {
1309
+ channelId: string;
1310
+ agentName: string;
1311
+ workingDirectory: string;
1312
+ resumeAgentSessionId?: string;
1313
+ existingSessionId?: string;
1314
+ initialName?: string;
1315
+ }
1316
+ interface SideEffectDeps {
1317
+ usageStore?: UsageStore | null;
1318
+ usageBudget?: UsageBudget | null;
1319
+ notificationManager: NotificationManager;
1320
+ tunnelService?: TunnelService;
1321
+ }
1322
+ declare class SessionFactory {
1323
+ private agentManager;
1324
+ private sessionManager;
1325
+ private speechService;
1326
+ private eventBus;
1327
+ constructor(agentManager: AgentManager, sessionManager: SessionManager, speechService: SpeechService, eventBus: EventBus);
1328
+ create(params: SessionCreateParams): Promise<Session>;
1329
+ wireSideEffects(session: Session, deps: SideEffectDeps): void;
1330
+ }
1331
+
956
1332
  declare class OpenACPCore {
957
1333
  configManager: ConfigManager;
958
1334
  agentCatalog: AgentCatalog;
@@ -961,18 +1337,31 @@ declare class OpenACPCore {
961
1337
  notificationManager: NotificationManager;
962
1338
  messageTransformer: MessageTransformer;
963
1339
  fileService: FileService;
1340
+ readonly speechService: SpeechService;
1341
+ securityGuard: SecurityGuard;
964
1342
  adapters: Map<string, ChannelAdapter>;
965
1343
  /** Set by main.ts — triggers graceful shutdown with restart exit code */
966
1344
  requestRestart: (() => Promise<void>) | null;
967
1345
  private _tunnelService?;
968
1346
  private sessionStore;
969
1347
  private resumeLocks;
1348
+ eventBus: EventBus;
1349
+ sessionFactory: SessionFactory;
1350
+ readonly usageStore: UsageStore | null;
1351
+ readonly usageBudget: UsageBudget | null;
970
1352
  constructor(configManager: ConfigManager);
971
1353
  get tunnelService(): TunnelService | undefined;
972
1354
  set tunnelService(service: TunnelService | undefined);
973
1355
  registerAdapter(name: string, adapter: ChannelAdapter): void;
974
1356
  start(): Promise<void>;
975
1357
  stop(): Promise<void>;
1358
+ archiveSession(sessionId: string): Promise<{
1359
+ ok: true;
1360
+ newThreadId: string;
1361
+ } | {
1362
+ ok: false;
1363
+ error: string;
1364
+ }>;
976
1365
  handleMessage(message: IncomingMessage): Promise<void>;
977
1366
  createSession(params: {
978
1367
  channelId: string;
@@ -984,7 +1373,7 @@ declare class OpenACPCore {
984
1373
  initialName?: string;
985
1374
  }): Promise<Session>;
986
1375
  handleNewSession(channelId: string, agentName?: string, workspacePath?: string): Promise<Session>;
987
- adoptSession(agentName: string, agentSessionId: string, cwd: string): Promise<{
1376
+ adoptSession(agentName: string, agentSessionId: string, cwd: string, channelId?: string): Promise<{
988
1377
  ok: true;
989
1378
  sessionId: string;
990
1379
  threadId: string;
@@ -995,6 +1384,11 @@ declare class OpenACPCore {
995
1384
  message: string;
996
1385
  }>;
997
1386
  handleNewChat(channelId: string, currentThreadId: string): Promise<Session | null>;
1387
+ /**
1388
+ * Get active session by thread, or attempt lazy resume from store.
1389
+ * Used by adapter command handlers that need a session but don't go through handleMessage().
1390
+ */
1391
+ getOrResumeSession(channelId: string, threadId: string): Promise<Session | null>;
998
1392
  private lazyResume;
999
1393
  /** Create a SessionBridge for the given session and adapter */
1000
1394
  createBridge(session: Session, adapter: ChannelAdapter): SessionBridge;
@@ -1002,7 +1396,7 @@ declare class OpenACPCore {
1002
1396
 
1003
1397
  interface AdapterFactory {
1004
1398
  name: string;
1005
- createAdapter(core: any, config: any): ChannelAdapter;
1399
+ createAdapter(core: OpenACPCore, config: ChannelConfig): ChannelAdapter;
1006
1400
  }
1007
1401
  declare function installPlugin(packageName: string): void;
1008
1402
  declare function uninstallPlugin(packageName: string): void;
@@ -1097,43 +1491,49 @@ declare class ApiServer {
1097
1491
  private startedAt;
1098
1492
  private secret;
1099
1493
  private secretFilePath;
1100
- constructor(core: OpenACPCore, config: ApiConfig, portFilePath?: string, topicManager?: TopicManager | undefined, secretFilePath?: string);
1494
+ private sseManager;
1495
+ private staticServer;
1496
+ private router;
1497
+ constructor(core: OpenACPCore, config: ApiConfig, portFilePath?: string, topicManager?: TopicManager | undefined, secretFilePath?: string, uiDir?: string);
1101
1498
  start(): Promise<void>;
1102
1499
  stop(): Promise<void>;
1103
1500
  getPort(): number;
1501
+ getSecret(): string;
1104
1502
  private writePortFile;
1105
1503
  private removePortFile;
1106
1504
  private loadOrCreateSecret;
1107
1505
  private authenticate;
1108
1506
  private handleRequest;
1109
- private handleCreateSession;
1110
- private handleSendPrompt;
1111
- private handleGetSession;
1112
- private handleToggleDangerous;
1113
- private handleHealth;
1114
- private handleVersion;
1115
- private handleGetEditableConfig;
1116
- private handleGetConfig;
1117
- private handleUpdateConfig;
1118
- private handleListAdapters;
1119
- private handleTunnelStatus;
1120
- private handleTunnelList;
1121
- private handleTunnelAdd;
1122
- private handleTunnelStop;
1123
- private handleTunnelStopAll;
1124
- private handleNotify;
1125
- private handleRestart;
1126
- private handleCancelSession;
1127
- private handleListSessions;
1128
- private handleAdoptSession;
1129
- private handleListAgents;
1130
1507
  private sendJson;
1131
- private handleListTopics;
1132
- private handleDeleteTopic;
1133
- private handleCleanupTopics;
1134
1508
  private readBody;
1135
1509
  }
1136
1510
 
1511
+ interface SessionStats {
1512
+ active: number;
1513
+ total: number;
1514
+ }
1515
+ declare class SSEManager {
1516
+ private eventBus;
1517
+ private getSessionStats;
1518
+ private startedAt;
1519
+ private sseConnections;
1520
+ private sseCleanupHandlers;
1521
+ private healthInterval?;
1522
+ private boundHandlers;
1523
+ constructor(eventBus: EventBus | undefined, getSessionStats: () => SessionStats, startedAt: number);
1524
+ setup(): void;
1525
+ handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void;
1526
+ broadcast(event: string, data: unknown): void;
1527
+ stop(): void;
1528
+ }
1529
+
1530
+ declare class StaticServer {
1531
+ private uiDir;
1532
+ constructor(uiDir?: string);
1533
+ isAvailable(): boolean;
1534
+ serve(req: http.IncomingMessage, res: http.ServerResponse): boolean;
1535
+ }
1536
+
1137
1537
  interface ConfigFieldDef {
1138
1538
  path: string;
1139
1539
  displayName: string;
@@ -1150,8 +1550,7 @@ declare function isHotReloadable(path: string): boolean;
1150
1550
  declare function resolveOptions(def: ConfigFieldDef, config: Config): string[] | undefined;
1151
1551
  declare function getConfigValue(config: Config, path: string): unknown;
1152
1552
 
1153
- interface TelegramChannelConfig {
1154
- enabled: boolean;
1553
+ interface TelegramChannelConfig extends ChannelConfig {
1155
1554
  botToken: string;
1156
1555
  chatId: number;
1157
1556
  notificationTopicId: number | null;
@@ -1177,6 +1576,7 @@ declare class TelegramAdapter extends ChannelAdapter<OpenACPCore> {
1177
1576
  start(): Promise<void>;
1178
1577
  stop(): Promise<void>;
1179
1578
  private setupRoutes;
1579
+ private messageHandlers;
1180
1580
  sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>;
1181
1581
  sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>;
1182
1582
  sendNotification(notification: NotificationMessage): Promise<void>;
@@ -1188,6 +1588,9 @@ declare class TelegramAdapter extends ChannelAdapter<OpenACPCore> {
1188
1588
  private downloadTelegramFile;
1189
1589
  private handleIncomingMedia;
1190
1590
  cleanupSkillCommands(sessionId: string): Promise<void>;
1591
+ archiveSessionTopic(sessionId: string): Promise<{
1592
+ newThreadId: string;
1593
+ } | null>;
1191
1594
  }
1192
1595
 
1193
- export { type AdapterFactory, AgentCatalog, type AgentCommand, type AgentDefinition, type AgentDistribution, type AgentEvent, AgentInstance, type AgentListItem, AgentManager, AgentStore, type ApiConfig, ApiServer, type Attachment, type AvailabilityResult, type BridgeDeps, CONFIG_REGISTRY, ChannelAdapter, type ChannelConfig, type CleanupResult, type Config, type ConfigFieldDef, ConfigManager, type DeleteTopicResult, type DiscordPlatformData, FileService, type IChannelAdapter, type IncomingMessage, type InstallProgress, type InstallResult, type InstalledAgent, type Logger, type LoggingConfig, MessageTransformer, NotificationManager, type NotificationMessage, OpenACPCore, type OutgoingMessage, PLUGINS_DIR, PermissionGate, type PermissionOption, type PermissionRequest, type PlanEntry, PromptQueue, type RegistryAgent, type RegistryBinaryTarget, type RegistryDistribution, Session, SessionBridge, type SessionEvents, SessionManager, type SessionRecord, type SessionStatus, StderrCapture, TelegramAdapter, type TelegramPlatformData, type TopicInfo, TopicManager, TypedEmitter, cleanupOldSessionLogs, createChildLogger, createSessionLogger, expandHome, getConfigValue, getFieldDef, getPidPath, getSafeFields, getStatus, initLogger, installAutoStart, installPlugin, isAutoStartInstalled, isAutoStartSupported, isHotReloadable, listPlugins, loadAdapterFactory, log, nodeToWebReadable, nodeToWebWritable, resolveOptions, runConfigEditor, setLogLevel, shutdownLogger, startDaemon, stopDaemon, uninstallAutoStart, uninstallPlugin };
1596
+ export { type AdapterFactory, AgentCatalog, type AgentCommand, type AgentDefinition, type AgentDistribution, type AgentEvent, AgentInstance, type AgentListItem, AgentManager, AgentStore, type ApiConfig, ApiServer, type Attachment, type AvailabilityResult, type BridgeDeps, CONFIG_REGISTRY, ChannelAdapter, type ChannelConfig, type CleanupResult, type Config, type ConfigFieldDef, ConfigManager, type DeleteTopicResult, type DiscordPlatformData, EventBus, type EventBusEvents, FileService, GroqSTT, type IChannelAdapter, type IncomingMessage, type InstallProgress, type InstallResult, type InstalledAgent, type Logger, type LoggingConfig, MessageTransformer, NotificationManager, type NotificationMessage, OpenACPCore, type OutgoingMessage, PLUGINS_DIR, PermissionGate, type PermissionOption, type PermissionRequest, type PlanEntry, PromptQueue, type RegistryAgent, type RegistryBinaryTarget, type RegistryDistribution, SSEManager, type STTOptions, type STTProvider, type STTResult, SecurityGuard, Session, SessionBridge, type SessionCreateParams, type SessionEvents, SessionFactory, SessionManager, type SessionRecord, type SessionStatus, type SideEffectDeps, type SpeechProviderConfig, SpeechService, type SpeechServiceConfig, StaticServer, StderrCapture, type TTSOptions, type TTSProvider, type TTSResult, TelegramAdapter, type TelegramPlatformData, type TopicInfo, TopicManager, TypedEmitter, UsageBudget, type UsageConfig, type UsageRecord, UsageStore, type UsageSummary, cleanupOldSessionLogs, createChildLogger, createSessionLogger, expandHome, getConfigValue, getFieldDef, getPidPath, getSafeFields, getStatus, initLogger, installAutoStart, installPlugin, isAutoStartInstalled, isAutoStartSupported, isHotReloadable, listPlugins, loadAdapterFactory, log, nodeToWebReadable, nodeToWebWritable, resolveOptions, runConfigEditor, setLogLevel, shutdownLogger, startDaemon, stopDaemon, uninstallAutoStart, uninstallPlugin };