@grinev/opencode-telegram-bot 0.21.1 → 0.22.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 (193) hide show
  1. package/.env.example +10 -15
  2. package/README.md +33 -13
  3. package/dist/app/{start-bot-app.js → bootstrap/start-bot-app.js} +16 -15
  4. package/dist/{bot/utils/assistant-run-footer.js → app/formatters/assistant-run-footer-formatter.js} +1 -1
  5. package/dist/{summary → app/formatters}/subagent-formatter.js +8 -3
  6. package/dist/{summary/formatter.js → app/formatters/summary-formatter.js} +20 -132
  7. package/dist/{summary → app/formatters}/tool-message-batcher.js +1 -1
  8. package/dist/{bot/assistant-run-state.js → app/managers/assistant-run-state-manager.js} +1 -1
  9. package/dist/{attach/manager.js → app/managers/attach-manager.js} +1 -1
  10. package/dist/{background-session/tracker.js → app/managers/background-session-manager.js} +2 -2
  11. package/dist/{scheduled-task/foreground-state.js → app/managers/foreground-session-state-manager.js} +1 -1
  12. package/dist/{interaction/manager.js → app/managers/interaction-manager.js} +31 -1
  13. package/dist/{permission/manager.js → app/managers/permission-manager.js} +1 -1
  14. package/dist/{question/manager.js → app/managers/question-manager.js} +1 -1
  15. package/dist/{rename/manager.js → app/managers/rename-manager.js} +1 -1
  16. package/dist/{scheduled-task/creation-manager.js → app/managers/scheduled-task-creation-manager.js} +2 -2
  17. package/dist/{summary/aggregator.js → app/managers/summary-aggregation-manager.js} +177 -13
  18. package/dist/{agent/manager.js → app/services/agent-selection-service.js} +4 -5
  19. package/dist/{attach/service.js → app/services/attach-service.js} +23 -44
  20. package/dist/{bot/utils/busy-reconciliation.js → app/services/busy-reconciliation-service.js} +12 -7
  21. package/dist/app/services/command-catalog-service.js +21 -0
  22. package/dist/{bot/utils/external-user-input.js → app/services/external-user-input-service.js} +4 -19
  23. package/dist/app/services/file-browser-service.js +265 -0
  24. package/dist/{bot/utils/file-download.js → app/services/file-download-service.js} +14 -28
  25. package/dist/app/services/mcp-catalog-service.js +79 -0
  26. package/dist/app/services/message-history-service.js +81 -0
  27. package/dist/{model/capabilities.js → app/services/model-capabilities-service.js} +2 -2
  28. package/dist/{model/context-limit.js → app/services/model-context-limit-service.js} +4 -4
  29. package/dist/{model/manager.js → app/services/model-selection-service.js} +4 -4
  30. package/dist/{project/manager.js → app/services/project-service.js} +3 -3
  31. package/dist/app/services/project-switch-service.js +39 -0
  32. package/dist/{bot/utils/busy-guard.js → app/services/run-control-service.js} +3 -14
  33. package/dist/{scheduled-task/executor.js → app/services/scheduled-task-executor-service.js} +27 -12
  34. package/dist/{scheduled-task/runtime.js → app/services/scheduled-task-runtime-service.js} +17 -56
  35. package/dist/{scheduled-task/schedule-parser.js → app/services/scheduled-task-schedule-parser-service.js} +3 -3
  36. package/dist/{scheduled-task/session-ignore.js → app/services/scheduled-task-session-ignore-service.js} +1 -1
  37. package/dist/{session/cache-manager.js → app/services/session-cache-service.js} +3 -3
  38. package/dist/{session/manager.js → app/services/session-service.js} +1 -1
  39. package/dist/app/services/skills-catalog-service.js +21 -0
  40. package/dist/{stt/client.js → app/services/stt-service.js} +2 -2
  41. package/dist/{tts/client.js → app/services/tts-service.js} +68 -5
  42. package/dist/{variant/manager.js → app/services/variant-selection-service.js} +3 -3
  43. package/dist/{scheduled-task/store.js → app/stores/scheduled-task-store.js} +3 -3
  44. package/dist/{settings/manager.js → app/stores/settings-store.js} +49 -7
  45. package/dist/app/types/worktree.js +1 -0
  46. package/dist/bot/{handlers/agent.js → callbacks/agent-selection-callback-handler.js} +8 -57
  47. package/dist/bot/callbacks/callback-router.js +113 -0
  48. package/dist/bot/{commands/commands.js → callbacks/command-catalog-callback-handler.js} +17 -197
  49. package/dist/bot/{handlers/context.js → callbacks/context-control-callback-handler.js} +3 -32
  50. package/dist/bot/callbacks/file-browser-callback-handler.js +219 -0
  51. package/dist/bot/callbacks/inline-menu-cancel-callback-handler.js +32 -0
  52. package/dist/bot/{commands/mcps.js → callbacks/mcp-catalog-callback-handler.js} +7 -172
  53. package/dist/bot/{commands/messages.js → callbacks/message-history-callback-handler.js} +17 -248
  54. package/dist/bot/{handlers/model.js → callbacks/model-selection-callback-handler.js} +10 -71
  55. package/dist/bot/callbacks/permission-callback-handler.js +114 -0
  56. package/dist/bot/callbacks/project-callback-handler.js +79 -0
  57. package/dist/bot/callbacks/question-callback-handler.js +159 -0
  58. package/dist/bot/{commands/rename.js → callbacks/rename-callback-handler.js} +6 -34
  59. package/dist/bot/{commands/tasklist.js → callbacks/scheduled-task-callback-handler.js} +83 -68
  60. package/dist/bot/{commands/sessions.js → callbacks/session-callback-handler.js} +19 -158
  61. package/dist/bot/callbacks/settings-callback-handler.js +105 -0
  62. package/dist/bot/{commands/skills.js → callbacks/skills-catalog-callback-handler.js} +8 -188
  63. package/dist/bot/{handlers/variant.js → callbacks/variant-selection-callback-handler.js} +7 -69
  64. package/dist/bot/callbacks/worktree-callback-handler.js +97 -0
  65. package/dist/bot/commands/{abort.js → abort-command.js} +6 -6
  66. package/dist/bot/commands/command-catalog-command.js +42 -0
  67. package/dist/bot/commands/definitions.js +1 -1
  68. package/dist/bot/commands/{detach.js → detach-command.js} +8 -8
  69. package/dist/bot/commands/ls-command.js +48 -0
  70. package/dist/bot/commands/mcp-catalog-command.js +39 -0
  71. package/dist/bot/commands/messages-command.js +59 -0
  72. package/dist/bot/commands/{new.js → new-command.js} +12 -11
  73. package/dist/bot/commands/open-command.js +45 -0
  74. package/dist/bot/commands/{opencode-start.js → opencode-start-command.js} +1 -1
  75. package/dist/bot/commands/{opencode-stop.js → opencode-stop-command.js} +1 -1
  76. package/dist/bot/commands/projects-command.js +32 -0
  77. package/dist/bot/commands/rename-command.js +33 -0
  78. package/dist/bot/commands/sessions-command.js +42 -0
  79. package/dist/bot/commands/settings-command.js +10 -0
  80. package/dist/bot/commands/skills-catalog-command.js +42 -0
  81. package/dist/bot/commands/{start.js → start-command.js} +12 -12
  82. package/dist/bot/commands/{status.js → status-command.js} +15 -10
  83. package/dist/bot/commands/{task.js → task-command.js} +9 -81
  84. package/dist/bot/commands/tasklist-command.js +40 -0
  85. package/dist/bot/commands/worktree-command.js +47 -0
  86. package/dist/bot/handlers/{document.js → document-handler.js} +3 -3
  87. package/dist/bot/handlers/{media-group.js → media-group-handler.js} +3 -3
  88. package/dist/bot/handlers/photo-handler.js +44 -0
  89. package/dist/bot/handlers/prompt.js +17 -17
  90. package/dist/bot/handlers/text-message-handler.js +61 -0
  91. package/dist/bot/handlers/tts-response-handler.js +29 -0
  92. package/dist/bot/handlers/{voice.js → voice-handler.js} +6 -3
  93. package/dist/bot/index.js +27 -1179
  94. package/dist/{keyboard/manager.js → bot/keyboards/keyboard-manager.js} +6 -6
  95. package/dist/bot/keyboards/keyboard-types.js +1 -0
  96. package/dist/bot/{utils/keyboard.js → keyboards/main-reply-keyboard.js} +2 -2
  97. package/dist/bot/menus/agent-selection-menu.js +54 -0
  98. package/dist/bot/menus/command-catalog-menu.js +101 -0
  99. package/dist/bot/menus/context-control-menu.js +33 -0
  100. package/dist/bot/menus/file-browser-menu.js +265 -0
  101. package/dist/bot/{handlers → menus}/inline-menu.js +7 -34
  102. package/dist/bot/menus/mcp-catalog-menu.js +97 -0
  103. package/dist/bot/menus/message-history-menu.js +107 -0
  104. package/dist/bot/menus/model-selection-menu.js +66 -0
  105. package/dist/bot/menus/permission-menu.js +116 -0
  106. package/dist/bot/{commands/projects.js → menus/project-selection-menu.js} +5 -105
  107. package/dist/bot/{handlers/question.js → menus/question-menu.js} +10 -166
  108. package/dist/bot/menus/rename-menu.js +6 -0
  109. package/dist/bot/menus/scheduled-task-menu.js +42 -0
  110. package/dist/bot/menus/session-selection-menu.js +115 -0
  111. package/dist/bot/menus/settings-menu.js +52 -0
  112. package/dist/bot/menus/skills-catalog-menu.js +99 -0
  113. package/dist/bot/menus/variant-selection-menu.js +67 -0
  114. package/dist/bot/menus/worktree-selection-menu.js +76 -0
  115. package/dist/bot/{utils → messages}/assistant-rendering.js +2 -2
  116. package/dist/bot/messages/busy-blocked-renderer.js +11 -0
  117. package/dist/bot/messages/external-user-input-notification.js +22 -0
  118. package/dist/bot/messages/scheduled-task-delivery.js +63 -0
  119. package/dist/bot/{utils → messages}/send-downloaded-file.js +1 -1
  120. package/dist/bot/messages/summary-message-formatter.js +130 -0
  121. package/dist/bot/{utils → messages}/thinking-message.js +1 -4
  122. package/dist/bot/messages/thinking-rendering.js +66 -0
  123. package/dist/{interaction/guard.js → bot/middleware/interaction-guard-decision.js} +11 -4
  124. package/dist/bot/middleware/interaction-guard.js +2 -2
  125. package/dist/bot/middleware/unknown-command.js +1 -1
  126. package/dist/{pinned/format.js → bot/pinned/pinned-message-format.js} +1 -2
  127. package/dist/{pinned/manager.js → bot/pinned/pinned-message-manager.js} +10 -10
  128. package/dist/bot/pinned/pinned-message-types.js +1 -0
  129. package/dist/{summary → bot/render}/markdown-to-telegram-v2.js +2 -2
  130. package/dist/bot/render/types.js +1 -0
  131. package/dist/bot/routers/command-router.js +73 -0
  132. package/dist/bot/routers/message-router.js +150 -0
  133. package/dist/bot/services/attach-presentation.js +40 -0
  134. package/dist/bot/services/event-subscription-service.js +1116 -0
  135. package/dist/bot/services/project-switch-presentation.js +26 -0
  136. package/dist/bot/streaming/compact-progress-streamer.js +162 -0
  137. package/dist/bot/{utils → streaming}/finalize-assistant-response.js +9 -3
  138. package/dist/bot/streaming/response-streamer.js +16 -1
  139. package/dist/cli.js +4 -4
  140. package/dist/config.js +9 -18
  141. package/dist/i18n/ar.js +31 -6
  142. package/dist/i18n/de.js +32 -7
  143. package/dist/i18n/en.js +32 -7
  144. package/dist/i18n/es.js +32 -7
  145. package/dist/i18n/fr.js +32 -7
  146. package/dist/i18n/ru.js +32 -7
  147. package/dist/i18n/zh.js +32 -7
  148. package/dist/index.js +1 -1
  149. package/dist/opencode/ready-refresh.js +2 -2
  150. package/dist/{service → runtime/service}/manager.js +2 -2
  151. package/dist/runtime/service/types.js +1 -0
  152. package/package.json +1 -1
  153. package/dist/bot/commands/ls.js +0 -445
  154. package/dist/bot/commands/open.js +0 -319
  155. package/dist/bot/commands/tts.js +0 -13
  156. package/dist/bot/commands/worktree.js +0 -201
  157. package/dist/bot/handlers/permission.js +0 -235
  158. package/dist/bot/utils/browser-roots.js +0 -140
  159. package/dist/bot/utils/file-tree.js +0 -92
  160. package/dist/bot/utils/send-tts-response.js +0 -37
  161. package/dist/bot/utils/switch-project.js +0 -45
  162. package/dist/bot/utils/telegram-file-url.js +0 -11
  163. package/dist/interaction/busy.js +0 -8
  164. package/dist/interaction/cleanup.js +0 -32
  165. /package/dist/{scheduled-task/display.js → app/formatters/scheduled-task-display-formatter.js} +0 -0
  166. /package/dist/{bot/utils/abort-error-suppression.js → app/managers/abort-suppression-manager.js} +0 -0
  167. /package/dist/{external-input/suppression.js → app/managers/external-input-suppression-manager.js} +0 -0
  168. /package/dist/{scheduled-task/next-run.js → app/services/scheduled-task-next-run-service.js} +0 -0
  169. /package/dist/{git/worktree.js → app/services/worktree-service.js} +0 -0
  170. /package/dist/{agent/types.js → app/types/agent.js} +0 -0
  171. /package/dist/{interaction/types.js → app/types/interaction.js} +0 -0
  172. /package/dist/{model/types.js → app/types/model.js} +0 -0
  173. /package/dist/{keyboard/types.js → app/types/permission.js} +0 -0
  174. /package/dist/{permission/types.js → app/types/project.js} +0 -0
  175. /package/dist/{pinned/types.js → app/types/question.js} +0 -0
  176. /package/dist/{scheduled-task/types.js → app/types/scheduled-task.js} +0 -0
  177. /package/dist/{question/types.js → app/types/session.js} +0 -0
  178. /package/dist/{service/types.js → app/types/settings.js} +0 -0
  179. /package/dist/{telegram/render/types.js → app/types/summary.js} +0 -0
  180. /package/dist/{variant/types.js → app/types/variant.js} +0 -0
  181. /package/dist/bot/commands/{help.js → help-command.js} +0 -0
  182. /package/dist/bot/{utils → messages}/send-with-markdown-fallback.js +0 -0
  183. /package/dist/bot/{utils → messages}/telegram-text.js +0 -0
  184. /package/dist/{telegram → bot}/render/block-fallback.js +0 -0
  185. /package/dist/{telegram → bot}/render/block-parser.js +0 -0
  186. /package/dist/{telegram → bot}/render/block-renderer.js +0 -0
  187. /package/dist/{telegram → bot}/render/chunker.js +0 -0
  188. /package/dist/{telegram → bot}/render/inline-renderer.js +0 -0
  189. /package/dist/{telegram → bot}/render/markdown-normalizer.js +0 -0
  190. /package/dist/{telegram → bot}/render/pipeline.js +0 -0
  191. /package/dist/{telegram → bot}/render/validator.js +0 -0
  192. /package/dist/bot/{utils/commands.js → routers/command-utils.js} +0 -0
  193. /package/dist/{service/runtime.js → runtime/service/env.js} +0 -0
package/dist/i18n/es.js CHANGED
@@ -5,7 +5,7 @@ export const es = {
5
5
  "cmd.description.detach": "Desconectar de la sesión actual",
6
6
  "cmd.description.sessions": "Listar sesiones",
7
7
  "cmd.description.messages": "Ver mensajes de la sesión",
8
- "cmd.description.tts": "Alternar respuestas de audio",
8
+ "cmd.description.settings": "Cambiar ajustes del bot",
9
9
  "cmd.description.projects": "Listar proyectos",
10
10
  "cmd.description.worktree": "Cambiar worktrees de git",
11
11
  "cmd.description.task": "Crear tarea programada",
@@ -35,6 +35,7 @@ export const es = {
35
35
  "question.blocked.expected_answer": "⚠️ Responde la pregunta actual usando botones, Respuesta personalizada o Cancelar.",
36
36
  "question.blocked.command_not_allowed": "⚠️ Este comando no está disponible hasta que se complete el flujo de la pregunta actual.",
37
37
  "inline.button.cancel": "❌ Cancelar",
38
+ "inline.button.close": "❌ Cerrar",
38
39
  "inline.inactive_callback": "Este menú está inactivo",
39
40
  "inline.cancelled_callback": "Cancelado",
40
41
  "common.unknown": "desconocido",
@@ -43,6 +44,16 @@ export const es = {
43
44
  "help.keyboard_hint": "💡 Usa los botones inferiores para agente, modelo, variante y acciones de contexto.",
44
45
  "help.text": "📖 **Ayuda**\n\n/status - Ver estado del servidor\n/sessions - Lista de sesiones\n/new - Crear una sesión nueva\n/help - Ayuda",
45
46
  "bot.thinking": "💭 Pensando...",
47
+ "progress.compact.activity": "{header}\n{activity}",
48
+ "progress.compact.working_header": "⏳ Trabajando",
49
+ "progress.compact.finished_header": "✅ Trabajo terminado",
50
+ "progress.compact.thinking": "💭 Pensando...",
51
+ "progress.compact.responding": "✍️ Escribiendo respuesta...",
52
+ "progress.compact.waiting_question": "❓ Esperando tu respuesta...",
53
+ "progress.compact.waiting_permission": "🔐 Esperando permiso...",
54
+ "progress.compact.retrying": "🔁 Reintentando...",
55
+ "progress.compact.task": "🤖 Tarea en ejecución",
56
+ "progress.compact.done": "{header}\nllamadas de herramientas: {tools} · archivos modificados: {files}",
46
57
  "bot.project_not_selected": "🏗 No hay un proyecto seleccionado.\n\nPrimero selecciona un proyecto con /projects.",
47
58
  "bot.creating_session": "🔄 Creando una sesión nueva...",
48
59
  "bot.create_session_error": "🔴 No se pudo crear la sesión. Prueba /new o revisa el estado del servidor con /status.",
@@ -84,9 +95,10 @@ export const es = {
84
95
  "status.line.uptime_sec": "Tiempo activo: {seconds} s",
85
96
  "status.line.mode": "Agente: {mode}",
86
97
  "status.line.model": "Modelo: {model}",
87
- "status.line.tts": "Respuestas TTS: {tts}",
88
- "status.tts.on": "Activadas",
98
+ "status.line.tts": "Respuestas de audio: {tts}",
89
99
  "status.tts.off": "Desactivadas",
100
+ "status.tts.all": "Todo",
101
+ "status.tts.auto": "Auto",
90
102
  "status.agent_not_set": "no configurado",
91
103
  "status.project_selected": "Proyecto: {project}",
92
104
  "status.worktree_selected": "Worktree: {worktree}",
@@ -96,10 +108,23 @@ export const es = {
96
108
  "status.session_not_selected": "Sesión actual: no seleccionada",
97
109
  "status.session_hint": "Usa /sessions para elegir una o /new para crear una",
98
110
  "status.server_unavailable": "🔴 OpenCode Server no está disponible\n\nUsa /opencode_start para iniciar el servidor.",
99
- "tts.enabled": "🔊 Respuestas de audio activadas globalmente.",
111
+ "tts.off": "🔇 Respuestas de audio desactivadas.",
112
+ "tts.all": "🔊 Respuestas de audio activadas para todos los mensajes.",
113
+ "tts.auto": "🎤 Respuestas de audio activadas solo para mensajes de voz.",
100
114
  "tts.not_configured": "⚠️ Las respuestas de audio no estan disponibles. Configura primero `TTS_API_URL` y `TTS_API_KEY`.",
101
- "tts.disabled": "🔇 Respuestas de audio desactivadas globalmente.",
102
115
  "tts.failed": "⚠️ No se pudo generar la respuesta de audio.",
116
+ "settings.menu.title": "⚙️ Ajustes del bot\nToca un ajuste para cambiar su valor:",
117
+ "settings.compact_output.label": "Salida compacta",
118
+ "settings.thinking_content.label": "Contenido de thinking",
119
+ "settings.response_streaming.label": "Streaming de respuesta",
120
+ "settings.response_streaming.edit": "edit",
121
+ "settings.response_streaming.draft": "draft (experimental)",
122
+ "settings.diff_files.label": "Archivos diff",
123
+ "settings.assistant_footer.label": "Pie de respuesta",
124
+ "settings.tts.label": "Respuestas de audio",
125
+ "settings.value.on": "Activado",
126
+ "settings.value.off": "Desactivado",
127
+ "settings.saved": "✅ Ajuste guardado.",
103
128
  "projects.empty": "📭 No se encontraron proyectos.\n\nAbre un directorio en OpenCode y crea al menos una sesión; entonces aparecerá aquí.",
104
129
  "projects.select": "Selecciona un proyecto:",
105
130
  "projects.select_with_current": "Selecciona un proyecto:\n\nActual: 🏗 {project}",
@@ -213,8 +238,8 @@ export const es = {
213
238
  "model.menu.error": "🔴 No se pudo obtener la lista de modelos",
214
239
  "model.search.button": "🔍 Buscar",
215
240
  "model.search.prompt": "🔍 Ingrese el nombre del modelo para buscar:",
216
- "model.search.results_title": "Resultados de búsqueda para \"{query}\":",
217
- "model.search.no_results": "No se encontraron modelos para \"{query}\"",
241
+ "model.search.results_title": 'Resultados de búsqueda para "{query}":',
242
+ "model.search.no_results": 'No se encontraron modelos para "{query}"',
218
243
  "model.search.search_again": "↩ Buscar de nuevo",
219
244
  "model.search.error": "Búsqueda fallida",
220
245
  "variant.model_not_selected_callback": "Error: no hay un modelo seleccionado",
package/dist/i18n/fr.js CHANGED
@@ -5,7 +5,7 @@ export const fr = {
5
5
  "cmd.description.detach": "Se détacher de la session actuelle",
6
6
  "cmd.description.sessions": "Lister les sessions",
7
7
  "cmd.description.messages": "Parcourir les messages de session",
8
- "cmd.description.tts": "Basculer les réponses audio",
8
+ "cmd.description.settings": "Modifier les paramètres du bot",
9
9
  "cmd.description.projects": "Lister les projets",
10
10
  "cmd.description.worktree": "Changer de worktree git",
11
11
  "cmd.description.task": "Créer une tâche planifiée",
@@ -35,6 +35,7 @@ export const fr = {
35
35
  "question.blocked.expected_answer": "⚠️ Répondez à la question en cours avec les boutons, Réponse personnalisée ou Annuler.",
36
36
  "question.blocked.command_not_allowed": "⚠️ Cette commande n'est pas disponible tant que le flux de question actuel n'est pas terminé.",
37
37
  "inline.button.cancel": "❌ Annuler",
38
+ "inline.button.close": "❌ Fermer",
38
39
  "inline.inactive_callback": "Ce menu est inactif",
39
40
  "inline.cancelled_callback": "Annulé",
40
41
  "common.unknown": "inconnu",
@@ -43,6 +44,16 @@ export const fr = {
43
44
  "help.keyboard_hint": "💡 Utilisez les boutons du bas pour l'agent, le modèle, la variante et les actions de contexte.",
44
45
  "help.text": "📖 **Aide**\n\n/status - Vérifier l'état du serveur\n/sessions - Liste des sessions\n/new - Créer une nouvelle session\n/help - Aide",
45
46
  "bot.thinking": "💭 Réflexion en cours...",
47
+ "progress.compact.activity": "{header}\n{activity}",
48
+ "progress.compact.working_header": "⏳ Travail en cours",
49
+ "progress.compact.finished_header": "✅ Travail terminé",
50
+ "progress.compact.thinking": "💭 Réflexion en cours...",
51
+ "progress.compact.responding": "✍️ Rédaction de la réponse...",
52
+ "progress.compact.waiting_question": "❓ En attente de votre réponse...",
53
+ "progress.compact.waiting_permission": "🔐 En attente d'autorisation...",
54
+ "progress.compact.retrying": "🔁 Nouvelle tentative...",
55
+ "progress.compact.task": "🤖 Tâche en cours",
56
+ "progress.compact.done": "{header}\nappels d’outils : {tools} · fichiers modifiés : {files}",
46
57
  "bot.project_not_selected": "🏗 Aucun projet n'est sélectionné.\n\nSélectionnez d'abord un projet avec /projects.",
47
58
  "bot.creating_session": "🔄 Création d'une nouvelle session...",
48
59
  "bot.create_session_error": "🔴 Impossible de créer la session. Essayez /new ou vérifiez l'état du serveur avec /status.",
@@ -84,9 +95,10 @@ export const fr = {
84
95
  "status.line.uptime_sec": "Temps de fonctionnement : {seconds} sec",
85
96
  "status.line.mode": "Agent : {mode}",
86
97
  "status.line.model": "Modèle : {model}",
87
- "status.line.tts": "Réponses TTS : {tts}",
88
- "status.tts.on": "Activées",
98
+ "status.line.tts": "Réponses audio : {tts}",
89
99
  "status.tts.off": "Désactivées",
100
+ "status.tts.all": "Tout",
101
+ "status.tts.auto": "Auto",
90
102
  "status.agent_not_set": "non défini",
91
103
  "status.project_selected": "Projet : {project}",
92
104
  "status.worktree_selected": "Worktree : {worktree}",
@@ -96,10 +108,23 @@ export const fr = {
96
108
  "status.session_not_selected": "Session actuelle : non sélectionnée",
97
109
  "status.session_hint": "Utilisez /sessions pour en sélectionner une ou /new pour en créer une",
98
110
  "status.server_unavailable": "🔴 Le serveur OpenCode est indisponible\n\nUtilisez /opencode_start pour démarrer le serveur.",
99
- "tts.enabled": "🔊 Réponses audio activées globalement.",
111
+ "tts.off": "🔇 Réponses audio désactivées.",
112
+ "tts.all": "🔊 Réponses audio activées pour tous les messages.",
113
+ "tts.auto": "🎤 Réponses audio activées pour les messages vocaux uniquement.",
100
114
  "tts.not_configured": "⚠️ Les réponses audio ne sont pas disponibles. Définissez d'abord `TTS_API_URL` et `TTS_API_KEY`.",
101
- "tts.disabled": "🔇 Réponses audio désactivées globalement.",
102
115
  "tts.failed": "⚠️ Impossible de générer la réponse audio.",
116
+ "settings.menu.title": "⚙️ Paramètres du bot\nTouchez un paramètre pour basculer sa valeur :",
117
+ "settings.compact_output.label": "Sortie compacte",
118
+ "settings.thinking_content.label": "Contenu thinking",
119
+ "settings.response_streaming.label": "Streaming de réponse",
120
+ "settings.response_streaming.edit": "edit",
121
+ "settings.response_streaming.draft": "draft (experimental)",
122
+ "settings.diff_files.label": "Fichiers diff",
123
+ "settings.assistant_footer.label": "Pied de réponse",
124
+ "settings.tts.label": "Réponses audio",
125
+ "settings.value.on": "Activé",
126
+ "settings.value.off": "Désactivé",
127
+ "settings.saved": "✅ Paramètre enregistré.",
103
128
  "projects.empty": "📭 Aucun projet trouvé.\n\nOuvrez un répertoire dans OpenCode et créez au moins une session, il apparaîtra ensuite ici.",
104
129
  "projects.select": "Sélectionnez un projet :",
105
130
  "projects.select_with_current": "Sélectionnez un projet :\n\nActuel : 🏗 {project}",
@@ -213,8 +238,8 @@ export const fr = {
213
238
  "model.menu.error": "🔴 Impossible de récupérer la liste des modèles",
214
239
  "model.search.button": "🔍 Rechercher",
215
240
  "model.search.prompt": "🔍 Entrez le nom du modèle à rechercher :",
216
- "model.search.results_title": "Résultats de recherche pour \"{query}\" :",
217
- "model.search.no_results": "Aucun modèle trouvé pour \"{query}\"",
241
+ "model.search.results_title": 'Résultats de recherche pour "{query}" :',
242
+ "model.search.no_results": 'Aucun modèle trouvé pour "{query}"',
218
243
  "model.search.search_again": "↩ Rechercher à nouveau",
219
244
  "model.search.error": "Échec de la recherche",
220
245
  "variant.model_not_selected_callback": "Erreur : aucun modèle sélectionné",
package/dist/i18n/ru.js CHANGED
@@ -5,7 +5,7 @@ export const ru = {
5
5
  "cmd.description.detach": "Отсоединиться от текущей сессии",
6
6
  "cmd.description.sessions": "Список сессий",
7
7
  "cmd.description.messages": "Сообщения текущей сессии",
8
- "cmd.description.tts": "Переключить аудиоответы",
8
+ "cmd.description.settings": "Изменить настройки бота",
9
9
  "cmd.description.projects": "Список проектов",
10
10
  "cmd.description.worktree": "Переключить git worktree",
11
11
  "cmd.description.task": "Создать задачу по расписанию",
@@ -35,6 +35,7 @@ export const ru = {
35
35
  "question.blocked.expected_answer": "⚠️ Ответьте на текущий вопрос кнопками, через Свой ответ, или нажмите Отмена.",
36
36
  "question.blocked.command_not_allowed": "⚠️ Эта команда недоступна, пока не завершен текущий опрос.",
37
37
  "inline.button.cancel": "❌ Отмена",
38
+ "inline.button.close": "❌ Закрыть",
38
39
  "inline.inactive_callback": "Это меню уже неактивно",
39
40
  "inline.cancelled_callback": "Отменено",
40
41
  "common.unknown": "неизвестна",
@@ -43,6 +44,16 @@ export const ru = {
43
44
  "help.keyboard_hint": "💡 Агент, модель, вариант и действия с контекстом доступны через нижние кнопки клавиатуры.",
44
45
  "help.text": "📖 **Справка**\n\n/status - Проверить статус сервера\n/sessions - Список сессий\n/new - Создать новую сессию\n/help - Справка",
45
46
  "bot.thinking": "💭 Думаю...",
47
+ "progress.compact.activity": "{header}\n{activity}",
48
+ "progress.compact.working_header": "⏳ Работаю",
49
+ "progress.compact.finished_header": "✅ Работа завершена",
50
+ "progress.compact.thinking": "💭 Думаю...",
51
+ "progress.compact.responding": "✍️ Пишу ответ...",
52
+ "progress.compact.waiting_question": "❓ Жду ваш ответ...",
53
+ "progress.compact.waiting_permission": "🔐 Жду разрешение...",
54
+ "progress.compact.retrying": "🔁 Повторяю запрос...",
55
+ "progress.compact.task": "🤖 Выполняю задачу",
56
+ "progress.compact.done": "{header}\nвызовы инструментов: {tools} · изменённые файлы: {files}",
46
57
  "bot.project_not_selected": "🏗 Проект не выбран.\n\nСначала выберите проект командой /projects.",
47
58
  "bot.creating_session": "🔄 Создаю новую сессию...",
48
59
  "bot.create_session_error": "🔴 Не удалось создать сессию. Попробуйте команду /new или проверьте статус сервера /status.",
@@ -84,9 +95,10 @@ export const ru = {
84
95
  "status.line.uptime_sec": "Uptime: {seconds} сек",
85
96
  "status.line.mode": "Агент: {mode}",
86
97
  "status.line.model": "Модель: {model}",
87
- "status.line.tts": "TTS-ответы: {tts}",
88
- "status.tts.on": "Вкл",
98
+ "status.line.tts": "Аудиоответы: {tts}",
89
99
  "status.tts.off": "Выкл",
100
+ "status.tts.all": "Все",
101
+ "status.tts.auto": "Авто",
90
102
  "status.agent_not_set": "не установлен",
91
103
  "status.project_selected": "Проект: {project}",
92
104
  "status.worktree_selected": "Worktree: {worktree}",
@@ -96,10 +108,23 @@ export const ru = {
96
108
  "status.session_not_selected": "Текущая сессия: не выбрана",
97
109
  "status.session_hint": "Используйте /sessions для выбора или /new для создания",
98
110
  "status.server_unavailable": "🔴 OpenCode Server недоступен\n\nИспользуйте /opencode_start для запуска сервера.",
99
- "tts.enabled": "🔊 Аудиоответы включены глобально.",
111
+ "tts.off": "🔇 Аудиоответы выключены.",
112
+ "tts.all": "🔊 Аудиоответы включены для всех сообщений.",
113
+ "tts.auto": "🎤 Аудиоответы включены только для голосовых сообщений.",
100
114
  "tts.not_configured": "⚠️ Аудиоответы недоступны. Сначала укажите `TTS_API_URL` и `TTS_API_KEY`.",
101
- "tts.disabled": "🔇 Аудиоответы выключены глобально.",
102
115
  "tts.failed": "⚠️ Не удалось создать аудиоответ.",
116
+ "settings.menu.title": "⚙️ Настройки бота\nНажмите на параметр, чтобы переключить его значение:",
117
+ "settings.compact_output.label": "Компактный вывод",
118
+ "settings.thinking_content.label": "Содержимое thinking",
119
+ "settings.response_streaming.label": "Стриминг ответа",
120
+ "settings.response_streaming.edit": "edit",
121
+ "settings.response_streaming.draft": "draft (experimental)",
122
+ "settings.diff_files.label": "Файлы с diff",
123
+ "settings.assistant_footer.label": "Футер ответа",
124
+ "settings.tts.label": "Аудиоответы",
125
+ "settings.value.on": "Вкл",
126
+ "settings.value.off": "Выкл",
127
+ "settings.saved": "✅ Настройка сохранена.",
103
128
  "projects.empty": "📭 Проектов нет.\n\nОткройте директорию в OpenCode и создайте хотя бы одну сессию, после этого она появится здесь.",
104
129
  "projects.select": "Выберите проект:",
105
130
  "projects.select_with_current": "Выберите проект:\n\nТекущий: 🏗 {project}",
@@ -213,8 +238,8 @@ export const ru = {
213
238
  "model.menu.error": "🔴 Не удалось получить список моделей",
214
239
  "model.search.button": "🔍 Поиск",
215
240
  "model.search.prompt": "🔍 Введите название модели для поиска:",
216
- "model.search.results_title": "Результаты поиска для \"{query}\":",
217
- "model.search.no_results": "Модели не найдены для \"{query}\"",
241
+ "model.search.results_title": 'Результаты поиска для "{query}":',
242
+ "model.search.no_results": 'Модели не найдены для "{query}"',
218
243
  "model.search.search_again": "↩ Искать снова",
219
244
  "model.search.error": "Ошибка поиска",
220
245
  "variant.model_not_selected_callback": "Ошибка: модель не выбрана",
package/dist/i18n/zh.js CHANGED
@@ -5,7 +5,7 @@ export const zh = {
5
5
  "cmd.description.detach": "从当前会话分离",
6
6
  "cmd.description.sessions": "列出会话",
7
7
  "cmd.description.messages": "浏览会话消息",
8
- "cmd.description.tts": "切换语音回复",
8
+ "cmd.description.settings": "更改机器人设置",
9
9
  "cmd.description.projects": "列出项目",
10
10
  "cmd.description.worktree": "切换 git worktree",
11
11
  "cmd.description.task": "创建定时任务",
@@ -35,6 +35,7 @@ export const zh = {
35
35
  "question.blocked.expected_answer": "⚠️ 请使用按钮、自定义回答或取消来回答当前问题。",
36
36
  "question.blocked.command_not_allowed": "⚠️ 在当前问答流程完成之前不可用此命令。",
37
37
  "inline.button.cancel": "❌ 取消",
38
+ "inline.button.close": "❌ 关闭",
38
39
  "inline.inactive_callback": "此菜单已失效",
39
40
  "inline.cancelled_callback": "已取消",
40
41
  "common.unknown": "未知",
@@ -43,6 +44,16 @@ export const zh = {
43
44
  "help.keyboard_hint": "💡 Agent、模型、变体和上下文操作请使用底部键盘按钮。",
44
45
  "help.text": "📖 **帮助**\n\n/status - 查看服务器状态\n/sessions - 会话列表\n/new - 创建新会话\n/help - 帮助",
45
46
  "bot.thinking": "💭 思考中...",
47
+ "progress.compact.activity": "{header}\n{activity}",
48
+ "progress.compact.working_header": "⏳ 工作中",
49
+ "progress.compact.finished_header": "✅ 工作完成",
50
+ "progress.compact.thinking": "💭 思考中...",
51
+ "progress.compact.responding": "✍️ 正在撰写回复...",
52
+ "progress.compact.waiting_question": "❓ 等待你的回答...",
53
+ "progress.compact.waiting_permission": "🔐 等待权限...",
54
+ "progress.compact.retrying": "🔁 正在重试...",
55
+ "progress.compact.task": "🤖 任务运行中",
56
+ "progress.compact.done": "{header}\n工具调用:{tools} · 已更改文件:{files}",
46
57
  "bot.project_not_selected": "🏗 未选择项目。\n\n请先使用 /projects 选择一个项目。",
47
58
  "bot.creating_session": "🔄 正在创建新会话...",
48
59
  "bot.create_session_error": "🔴 创建会话失败。请重试 /new,或使用 /status 检查服务器状态。",
@@ -84,9 +95,10 @@ export const zh = {
84
95
  "status.line.uptime_sec": "运行时间:{seconds} 秒",
85
96
  "status.line.mode": "Agent:{mode}",
86
97
  "status.line.model": "模型:{model}",
87
- "status.line.tts": "TTS 回复:{tts}",
88
- "status.tts.on": "开启",
98
+ "status.line.tts": "语音回复:{tts}",
89
99
  "status.tts.off": "关闭",
100
+ "status.tts.all": "全部",
101
+ "status.tts.auto": "自动",
90
102
  "status.agent_not_set": "未设置",
91
103
  "status.project_selected": "项目:{project}",
92
104
  "status.worktree_selected": "Worktree:{worktree}",
@@ -96,10 +108,23 @@ export const zh = {
96
108
  "status.session_not_selected": "当前会话:未选择",
97
109
  "status.session_hint": "使用 /sessions 选择一个会话,或 /new 创建",
98
110
  "status.server_unavailable": "🔴 OpenCode 服务器不可用\n\n使用 /opencode_start 启动服务器。",
99
- "tts.enabled": "🔊 已全局启用语音回复。",
111
+ "tts.off": "🔇 语音回复已关闭。",
112
+ "tts.all": "🔊 已为所有消息启用语音回复。",
113
+ "tts.auto": "🎤 仅为语音消息启用语音回复。",
100
114
  "tts.not_configured": "⚠️ 语音回复暂不可用。请先设置 `TTS_API_URL` 和 `TTS_API_KEY`。",
101
- "tts.disabled": "🔇 已全局关闭语音回复。",
102
115
  "tts.failed": "⚠️ 生成语音回复失败。",
116
+ "settings.menu.title": "⚙️ 机器人设置\n点按设置项以切换其值:",
117
+ "settings.compact_output.label": "紧凑输出模式",
118
+ "settings.thinking_content.label": "思考内容",
119
+ "settings.response_streaming.label": "回复流式模式",
120
+ "settings.response_streaming.edit": "edit",
121
+ "settings.response_streaming.draft": "draft (experimental)",
122
+ "settings.diff_files.label": "Diff 文件",
123
+ "settings.assistant_footer.label": "回复页脚",
124
+ "settings.tts.label": "语音回复",
125
+ "settings.value.on": "开启",
126
+ "settings.value.off": "关闭",
127
+ "settings.saved": "✅ 设置已保存。",
103
128
  "projects.empty": "📭 未找到项目。\n\n在 OpenCode 中打开一个目录并至少创建一个会话,然后它会出现在这里。",
104
129
  "projects.select": "请选择一个项目:",
105
130
  "projects.select_with_current": "请选择一个项目:\n\n当前:🏗 {project}",
@@ -213,8 +238,8 @@ export const zh = {
213
238
  "model.menu.error": "🔴 获取模型列表失败",
214
239
  "model.search.button": "🔍 搜索",
215
240
  "model.search.prompt": "🔍 输入模型名称进行搜索:",
216
- "model.search.results_title": "\"{query}\" 的搜索结果:",
217
- "model.search.no_results": "未找到 \"{query}\" 的模型",
241
+ "model.search.results_title": '"{query}" 的搜索结果:',
242
+ "model.search.no_results": '未找到 "{query}" 的模型',
218
243
  "model.search.search_again": "↩ 重新搜索",
219
244
  "model.search.error": "搜索失败",
220
245
  "variant.model_not_selected_callback": "错误:未选择模型",
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ async function main() {
14
14
  setRuntimeMode(modeResult.mode);
15
15
  const { initializeLogger } = await import("./utils/logger.js");
16
16
  await initializeLogger();
17
- const { startBotApp } = await import("./app/start-bot-app.js");
17
+ const { startBotApp } = await import("./app/bootstrap/start-bot-app.js");
18
18
  await startBotApp();
19
19
  }
20
20
  void main().catch((error) => {
@@ -1,5 +1,5 @@
1
- import { reconcileStoredModelSelection } from "../model/manager.js";
2
- import { warmupSessionDirectoryCache } from "../session/cache-manager.js";
1
+ import { reconcileStoredModelSelection } from "../app/services/model-selection-service.js";
2
+ import { warmupSessionDirectoryCache } from "../app/services/session-cache-service.js";
3
3
  import { logger } from "../utils/logger.js";
4
4
  import { opencodeClient } from "./client.js";
5
5
  import { opencodeReadyLifecycle } from "./ready-lifecycle.js";
@@ -3,8 +3,8 @@ import fsPromises from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { exec, spawn } from "node:child_process";
5
5
  import { promisify } from "node:util";
6
- import { getRuntimePaths } from "../runtime/paths.js";
7
- import { buildServiceChildEnv } from "./runtime.js";
6
+ import { getRuntimePaths } from "../paths.js";
7
+ import { buildServiceChildEnv } from "./env.js";
8
8
  const execAsync = promisify(exec);
9
9
  const SERVICE_STATE_FILE_NAME = "bot-service.json";
10
10
  const PROCESS_EXIT_POLL_MS = 100;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grinev/opencode-telegram-bot",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
4
4
  "description": "Telegram bot client for OpenCode to run and monitor coding tasks from chat.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",