@shepai/cli 1.181.0 → 1.182.0-pr512.369be8e

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 (386) hide show
  1. package/apis/json-schema/MessagingCommand.yaml +28 -0
  2. package/apis/json-schema/MessagingCommandType.yaml +17 -0
  3. package/apis/json-schema/MessagingConfig.yaml +40 -0
  4. package/apis/json-schema/MessagingFrameType.yaml +8 -0
  5. package/apis/json-schema/MessagingNotification.yaml +22 -0
  6. package/apis/json-schema/MessagingPlatform.yaml +7 -0
  7. package/apis/json-schema/MessagingPlatformConfig.yaml +38 -0
  8. package/apis/json-schema/Settings.yaml +3 -0
  9. package/dist/packages/core/src/application/ports/output/services/gateway-client.interface.d.ts +58 -0
  10. package/dist/packages/core/src/application/ports/output/services/gateway-client.interface.d.ts.map +1 -0
  11. package/dist/packages/core/src/application/ports/output/services/gateway-client.interface.js +10 -0
  12. package/dist/packages/core/src/application/ports/output/services/message-sender.interface.d.ts +18 -0
  13. package/dist/packages/core/src/application/ports/output/services/message-sender.interface.d.ts.map +1 -0
  14. package/dist/packages/core/src/application/ports/output/services/message-sender.interface.js +9 -0
  15. package/dist/packages/core/src/application/ports/output/services/messaging-service.interface.d.ts +34 -0
  16. package/dist/packages/core/src/application/ports/output/services/messaging-service.interface.d.ts.map +1 -0
  17. package/dist/packages/core/src/application/ports/output/services/messaging-service.interface.js +12 -0
  18. package/dist/packages/core/src/application/ports/output/services/telegram-client.interface.d.ts +19 -0
  19. package/dist/packages/core/src/application/ports/output/services/telegram-client.interface.d.ts.map +1 -0
  20. package/dist/packages/core/src/application/ports/output/services/telegram-client.interface.js +8 -0
  21. package/dist/packages/core/src/application/use-cases/messaging/begin-pairing.use-case.d.ts +46 -0
  22. package/dist/packages/core/src/application/use-cases/messaging/begin-pairing.use-case.d.ts.map +1 -0
  23. package/dist/packages/core/src/application/use-cases/messaging/begin-pairing.use-case.js +148 -0
  24. package/dist/packages/core/src/application/use-cases/messaging/confirm-pairing.use-case.d.ts +19 -0
  25. package/dist/packages/core/src/application/use-cases/messaging/confirm-pairing.use-case.d.ts.map +1 -0
  26. package/dist/packages/core/src/application/use-cases/messaging/confirm-pairing.use-case.js +63 -0
  27. package/dist/packages/core/src/application/use-cases/messaging/disconnect-messaging.use-case.d.ts +19 -0
  28. package/dist/packages/core/src/application/use-cases/messaging/disconnect-messaging.use-case.d.ts.map +1 -0
  29. package/dist/packages/core/src/application/use-cases/messaging/disconnect-messaging.use-case.js +65 -0
  30. package/dist/packages/core/src/domain/generated/output.d.ts +155 -0
  31. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  32. package/dist/packages/core/src/domain/generated/output.js +26 -0
  33. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  34. package/dist/packages/core/src/infrastructure/di/container.js +117 -0
  35. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +24 -0
  36. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +117 -0
  38. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-messaging-remote-control.d.ts +22 -0
  39. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-messaging-remote-control.d.ts.map +1 -0
  40. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-messaging-remote-control.js +62 -0
  41. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +43 -3
  43. package/dist/packages/core/src/infrastructure/services/messaging/chat-relay.d.ts +45 -0
  44. package/dist/packages/core/src/infrastructure/services/messaging/chat-relay.d.ts.map +1 -0
  45. package/dist/packages/core/src/infrastructure/services/messaging/chat-relay.js +100 -0
  46. package/dist/packages/core/src/infrastructure/services/messaging/command-executor.d.ts +53 -0
  47. package/dist/packages/core/src/infrastructure/services/messaging/command-executor.d.ts.map +1 -0
  48. package/dist/packages/core/src/infrastructure/services/messaging/command-executor.js +200 -0
  49. package/dist/packages/core/src/infrastructure/services/messaging/content-sanitizer.d.ts +23 -0
  50. package/dist/packages/core/src/infrastructure/services/messaging/content-sanitizer.d.ts.map +1 -0
  51. package/dist/packages/core/src/infrastructure/services/messaging/content-sanitizer.js +39 -0
  52. package/dist/packages/core/src/infrastructure/services/messaging/http-gateway.client.d.ts +19 -0
  53. package/dist/packages/core/src/infrastructure/services/messaging/http-gateway.client.d.ts.map +1 -0
  54. package/dist/packages/core/src/infrastructure/services/messaging/http-gateway.client.js +124 -0
  55. package/dist/packages/core/src/infrastructure/services/messaging/http-telegram.client.d.ts +18 -0
  56. package/dist/packages/core/src/infrastructure/services/messaging/http-telegram.client.d.ts.map +1 -0
  57. package/dist/packages/core/src/infrastructure/services/messaging/http-telegram.client.js +60 -0
  58. package/dist/packages/core/src/infrastructure/services/messaging/messaging-tunnel.adapter.d.ts +68 -0
  59. package/dist/packages/core/src/infrastructure/services/messaging/messaging-tunnel.adapter.d.ts.map +1 -0
  60. package/dist/packages/core/src/infrastructure/services/messaging/messaging-tunnel.adapter.js +262 -0
  61. package/dist/packages/core/src/infrastructure/services/messaging/messaging.service.d.ts +78 -0
  62. package/dist/packages/core/src/infrastructure/services/messaging/messaging.service.d.ts.map +1 -0
  63. package/dist/packages/core/src/infrastructure/services/messaging/messaging.service.js +279 -0
  64. package/dist/packages/core/src/infrastructure/services/messaging/notification-emitter.d.ts +33 -0
  65. package/dist/packages/core/src/infrastructure/services/messaging/notification-emitter.d.ts.map +1 -0
  66. package/dist/packages/core/src/infrastructure/services/messaging/notification-emitter.js +79 -0
  67. package/dist/packages/core/src/infrastructure/services/messaging/stub-gateway.client.d.ts +12 -0
  68. package/dist/packages/core/src/infrastructure/services/messaging/stub-gateway.client.d.ts.map +1 -0
  69. package/dist/packages/core/src/infrastructure/services/messaging/stub-gateway.client.js +26 -0
  70. package/dist/packages/core/src/infrastructure/services/messaging/telegram-message-sender.d.ts +26 -0
  71. package/dist/packages/core/src/infrastructure/services/messaging/telegram-message-sender.d.ts.map +1 -0
  72. package/dist/packages/core/src/infrastructure/services/messaging/telegram-message-sender.js +49 -0
  73. package/dist/packages/core/src/infrastructure/services/messaging/telegram-webhook.parser.d.ts +28 -0
  74. package/dist/packages/core/src/infrastructure/services/messaging/telegram-webhook.parser.d.ts.map +1 -0
  75. package/dist/packages/core/src/infrastructure/services/messaging/telegram-webhook.parser.js +45 -0
  76. package/dist/packages/core/src/infrastructure/services/messaging/tunnel-protocol.d.ts +102 -0
  77. package/dist/packages/core/src/infrastructure/services/messaging/tunnel-protocol.d.ts.map +1 -0
  78. package/dist/packages/core/src/infrastructure/services/messaging/tunnel-protocol.js +16 -0
  79. package/dist/packages/core/src/infrastructure/services/messaging/whatsapp-webhook.parser.d.ts +39 -0
  80. package/dist/packages/core/src/infrastructure/services/messaging/whatsapp-webhook.parser.d.ts.map +1 -0
  81. package/dist/packages/core/src/infrastructure/services/messaging/whatsapp-webhook.parser.js +56 -0
  82. package/dist/src/presentation/cli/commands/_serve.command.d.ts.map +1 -1
  83. package/dist/src/presentation/cli/commands/_serve.command.js +6 -0
  84. package/dist/src/presentation/cli/commands/app/del.command.d.ts +14 -0
  85. package/dist/src/presentation/cli/commands/app/del.command.d.ts.map +1 -0
  86. package/dist/src/presentation/cli/commands/app/del.command.js +58 -0
  87. package/dist/src/presentation/cli/commands/app/index.d.ts +20 -0
  88. package/dist/src/presentation/cli/commands/app/index.d.ts.map +1 -0
  89. package/dist/src/presentation/cli/commands/app/index.js +33 -0
  90. package/dist/src/presentation/cli/commands/app/ls.command.d.ts +11 -0
  91. package/dist/src/presentation/cli/commands/app/ls.command.d.ts.map +1 -0
  92. package/dist/src/presentation/cli/commands/app/ls.command.js +74 -0
  93. package/dist/src/presentation/cli/commands/app/new.command.d.ts +17 -0
  94. package/dist/src/presentation/cli/commands/app/new.command.d.ts.map +1 -0
  95. package/dist/src/presentation/cli/commands/app/new.command.js +58 -0
  96. package/dist/src/presentation/cli/commands/app/resolve-application.d.ts +10 -0
  97. package/dist/src/presentation/cli/commands/app/resolve-application.d.ts.map +1 -0
  98. package/dist/src/presentation/cli/commands/app/resolve-application.js +33 -0
  99. package/dist/src/presentation/cli/commands/app/show.command.d.ts +11 -0
  100. package/dist/src/presentation/cli/commands/app/show.command.d.ts.map +1 -0
  101. package/dist/src/presentation/cli/commands/app/show.command.js +95 -0
  102. package/dist/src/presentation/cli/commands/settings/index.d.ts.map +1 -1
  103. package/dist/src/presentation/cli/commands/settings/index.js +3 -1
  104. package/dist/src/presentation/cli/commands/settings/messaging.command.d.ts +17 -0
  105. package/dist/src/presentation/cli/commands/settings/messaging.command.d.ts.map +1 -0
  106. package/dist/src/presentation/cli/commands/settings/messaging.command.js +187 -0
  107. package/dist/src/presentation/cli/index.js +2 -0
  108. package/dist/src/presentation/web/app/actions/messaging.d.ts +29 -0
  109. package/dist/src/presentation/web/app/actions/messaging.d.ts.map +1 -0
  110. package/dist/src/presentation/web/app/actions/messaging.js +55 -0
  111. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.d.ts +6 -0
  112. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.d.ts.map +1 -0
  113. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.js +206 -0
  114. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.stories.d.ts +17 -0
  115. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.stories.d.ts.map +1 -0
  116. package/dist/src/presentation/web/components/features/settings/messaging-settings-section.stories.js +55 -0
  117. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  118. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +9 -2
  119. package/dist/src/presentation/web/dev-server.js +27 -0
  120. package/dist/translations/ar/cli.json +63 -0
  121. package/dist/translations/ar/web.json +2 -1
  122. package/dist/translations/de/cli.json +63 -0
  123. package/dist/translations/de/web.json +2 -1
  124. package/dist/translations/en/cli.json +63 -0
  125. package/dist/translations/en/web.json +13 -12
  126. package/dist/translations/es/cli.json +63 -0
  127. package/dist/translations/es/web.json +2 -1
  128. package/dist/translations/fr/cli.json +63 -0
  129. package/dist/translations/fr/web.json +2 -1
  130. package/dist/translations/he/cli.json +63 -0
  131. package/dist/translations/he/web.json +2 -1
  132. package/dist/translations/pt/cli.json +63 -0
  133. package/dist/translations/pt/web.json +2 -1
  134. package/dist/translations/ru/cli.json +63 -0
  135. package/dist/translations/ru/web.json +2 -1
  136. package/dist/translations/uk/cli.json +63 -0
  137. package/dist/translations/uk/web.json +2 -1
  138. package/dist/tsconfig.build.tsbuildinfo +1 -1
  139. package/package.json +3 -1
  140. package/web/.next/BUILD_ID +1 -1
  141. package/web/.next/build-manifest.json +2 -2
  142. package/web/.next/fallback-build-manifest.json +2 -2
  143. package/web/.next/prerender-manifest.json +3 -3
  144. package/web/.next/required-server-files.js +3 -3
  145. package/web/.next/required-server-files.json +3 -3
  146. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +32 -32
  147. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  148. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  149. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +30 -30
  150. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  151. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  152. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +33 -33
  153. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  154. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  155. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +41 -41
  156. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  157. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  158. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +41 -41
  159. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  160. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  161. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +31 -31
  162. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  163. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  164. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +31 -31
  165. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  166. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  167. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +30 -30
  168. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  169. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  170. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +33 -33
  171. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  172. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  173. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +41 -41
  174. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  175. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  176. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +41 -41
  177. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  178. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  179. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +30 -30
  180. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  181. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  182. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +31 -31
  183. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  184. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  185. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +31 -31
  186. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  187. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  188. package/web/.next/server/app/_global-error.html +2 -2
  189. package/web/.next/server/app/_global-error.rsc +1 -1
  190. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  191. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  192. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  193. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  194. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  195. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +7 -7
  196. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  197. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  198. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  199. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  200. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  201. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  202. package/web/.next/server/app/application/[id]/page/server-reference-manifest.json +15 -15
  203. package/web/.next/server/app/application/[id]/page.js.nft.json +1 -1
  204. package/web/.next/server/app/application/[id]/page_client-reference-manifest.js +1 -1
  205. package/web/.next/server/app/features/page/server-reference-manifest.json +7 -7
  206. package/web/.next/server/app/features/page.js.nft.json +1 -1
  207. package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
  208. package/web/.next/server/app/settings/page/server-reference-manifest.json +65 -20
  209. package/web/.next/server/app/settings/page.js +1 -1
  210. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  211. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  212. package/web/.next/server/app/skills/page/server-reference-manifest.json +15 -15
  213. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  214. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  215. package/web/.next/server/app/tools/page/server-reference-manifest.json +13 -13
  216. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  217. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  218. package/web/.next/server/app/version/page/server-reference-manifest.json +7 -7
  219. package/web/.next/server/app/version/page.js.nft.json +1 -1
  220. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  221. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  222. package/web/.next/server/chunks/[root-of-the-server]__b2a4bfcc._.js +1 -1
  223. package/web/.next/server/chunks/[root-of-the-server]__b2a4bfcc._.js.map +1 -1
  224. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  225. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  227. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  228. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  229. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/{7f428_lucide-react_dist_esm_icons_5da25833._.js → 7f428_lucide-react_dist_esm_icons_469d51b7._.js} +2 -2
  231. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_469d51b7._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/[root-of-the-server]__013a0318._.js +1 -1
  233. package/web/.next/server/chunks/ssr/[root-of-the-server]__013a0318._.js.map +1 -1
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__17dadd08._.js +1 -1
  235. package/web/.next/server/chunks/ssr/[root-of-the-server]__17dadd08._.js.map +1 -1
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__1925bef0._.js +1 -1
  237. package/web/.next/server/chunks/ssr/[root-of-the-server]__1a9687c4._.js +1 -1
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__1a9687c4._.js.map +1 -1
  239. package/web/.next/server/chunks/ssr/[root-of-the-server]__24756fa9._.js +2 -2
  240. package/web/.next/server/chunks/ssr/[root-of-the-server]__24756fa9._.js.map +1 -1
  241. package/web/.next/server/chunks/ssr/[root-of-the-server]__42d066e1._.js +3 -0
  242. package/web/.next/server/chunks/ssr/[root-of-the-server]__42d066e1._.js.map +1 -0
  243. package/web/.next/server/chunks/ssr/[root-of-the-server]__4ee8be85._.js +1 -1
  244. package/web/.next/server/chunks/ssr/[root-of-the-server]__70986695._.js +1 -1
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__70986695._.js.map +1 -1
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__a5ea76a6._.js +1 -1
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__a5ea76a6._.js.map +1 -1
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd3e834e._.js +1 -1
  249. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd3e834e._.js.map +1 -1
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__e265da61._.js +1 -1
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__f3ca7bea._.js +1 -1
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__f3ca7bea._.js.map +1 -1
  253. package/web/.next/server/chunks/ssr/{[root-of-the-server]__bb391c45._.js → [root-of-the-server]__f4f07ee6._.js} +2 -2
  254. package/web/.next/server/chunks/ssr/[root-of-the-server]__f4f07ee6._.js.map +1 -0
  255. package/web/.next/server/chunks/ssr/_0277d3b5._.js +1 -1
  256. package/web/.next/server/chunks/ssr/_0277d3b5._.js.map +1 -1
  257. package/web/.next/server/chunks/ssr/{_da028026._.js → _1c03437e._.js} +2 -2
  258. package/web/.next/server/chunks/ssr/{_da028026._.js.map → _1c03437e._.js.map} +1 -1
  259. package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -1
  260. package/web/.next/server/chunks/ssr/{_655cc4fd._.js → _49838974._.js} +2 -2
  261. package/web/.next/server/chunks/ssr/{_655cc4fd._.js.map → _49838974._.js.map} +1 -1
  262. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  263. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/_708a9069._.js +3 -0
  265. package/web/.next/server/chunks/ssr/_708a9069._.js.map +1 -0
  266. package/web/.next/server/chunks/ssr/{_295fffde._.js → _86bb5eb1._.js} +6 -2
  267. package/web/.next/server/chunks/ssr/_86bb5eb1._.js.map +1 -0
  268. package/web/.next/server/chunks/ssr/_946a7fc6._.js +1 -1
  269. package/web/.next/server/chunks/ssr/_946a7fc6._.js.map +1 -1
  270. package/web/.next/server/chunks/ssr/{_fbf4db9c._.js → _b6df235f._.js} +2 -2
  271. package/web/.next/server/chunks/ssr/{_fbf4db9c._.js.map → _b6df235f._.js.map} +1 -1
  272. package/web/.next/server/chunks/ssr/_bad61758._.js +3 -0
  273. package/web/.next/server/chunks/ssr/_bad61758._.js.map +1 -0
  274. package/web/.next/server/chunks/ssr/{_e5753970._.js → _c5357cf5._.js} +2 -2
  275. package/web/.next/server/chunks/ssr/{_e5753970._.js.map → _c5357cf5._.js.map} +1 -1
  276. package/web/.next/server/chunks/ssr/_d7d82308._.js +3 -0
  277. package/web/.next/server/chunks/ssr/_d7d82308._.js.map +1 -0
  278. package/web/.next/server/chunks/ssr/_dd852eae._.js +3 -0
  279. package/web/.next/server/chunks/ssr/_dd852eae._.js.map +1 -0
  280. package/web/.next/server/chunks/ssr/_eff1b518._.js +1 -1
  281. package/web/.next/server/chunks/ssr/_eff1b518._.js.map +1 -1
  282. package/web/.next/server/chunks/ssr/_f227429a._.js +1 -1
  283. package/web/.next/server/chunks/ssr/_f227429a._.js.map +1 -1
  284. package/web/.next/server/chunks/ssr/_f6b812ec._.js +9 -0
  285. package/web/.next/server/chunks/ssr/_f6b812ec._.js.map +1 -0
  286. package/web/.next/server/chunks/ssr/_f86fc1bf._.js +1 -1
  287. package/web/.next/server/chunks/ssr/_f86fc1bf._.js.map +1 -1
  288. package/web/.next/server/chunks/ssr/_f8c55130._.js +1 -1
  289. package/web/.next/server/chunks/ssr/{_5bb39227._.js → _fa95e517._.js} +2 -2
  290. package/web/.next/server/chunks/ssr/{_5bb39227._.js.map → _fa95e517._.js.map} +1 -1
  291. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  292. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  293. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  294. package/web/.next/server/chunks/ssr/node_modules__pnpm_64cc95e9._.js +3 -0
  295. package/web/.next/server/chunks/ssr/node_modules__pnpm_64cc95e9._.js.map +1 -0
  296. package/web/.next/server/chunks/ssr/src_presentation_web_36f2bc45._.js +1 -1
  297. package/web/.next/server/chunks/ssr/src_presentation_web_36f2bc45._.js.map +1 -1
  298. package/web/.next/server/chunks/ssr/src_presentation_web_486908de._.js +1 -1
  299. package/web/.next/server/chunks/ssr/src_presentation_web_486908de._.js.map +1 -1
  300. package/web/.next/server/chunks/ssr/src_presentation_web_5c3596bc._.js +1 -1
  301. package/web/.next/server/chunks/ssr/src_presentation_web_5c3596bc._.js.map +1 -1
  302. package/web/.next/server/chunks/ssr/src_presentation_web_6159fef8._.js +1 -1
  303. package/web/.next/server/chunks/ssr/src_presentation_web_6159fef8._.js.map +1 -1
  304. package/web/.next/server/chunks/ssr/src_presentation_web_6326f81e._.js +1 -1
  305. package/web/.next/server/chunks/ssr/src_presentation_web_6326f81e._.js.map +1 -1
  306. package/web/.next/server/chunks/ssr/src_presentation_web_6b2fdcd8._.js +1 -1
  307. package/web/.next/server/chunks/ssr/src_presentation_web_6b2fdcd8._.js.map +1 -1
  308. package/web/.next/server/chunks/ssr/src_presentation_web_74703c9f._.js +1 -1
  309. package/web/.next/server/chunks/ssr/src_presentation_web_74703c9f._.js.map +1 -1
  310. package/web/.next/server/chunks/ssr/src_presentation_web_a8056dac._.js +1 -1
  311. package/web/.next/server/chunks/ssr/src_presentation_web_a8056dac._.js.map +1 -1
  312. package/web/.next/server/chunks/ssr/src_presentation_web_ad42cc73._.js +1 -1
  313. package/web/.next/server/chunks/ssr/src_presentation_web_ad42cc73._.js.map +1 -1
  314. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +3 -3
  315. package/web/.next/server/chunks/ssr/src_presentation_web_b00bfb08._.js +1 -1
  316. package/web/.next/server/chunks/ssr/src_presentation_web_b00bfb08._.js.map +1 -1
  317. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  318. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  319. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_base-drawer_base-drawer_tsx_97dfbbc8._.js +1 -1
  320. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_base-drawer_base-drawer_tsx_97dfbbc8._.js.map +1 -1
  321. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  322. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  323. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
  324. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
  325. package/web/.next/server/chunks/ssr/src_presentation_web_f1edcf5e._.js +1 -1
  326. package/web/.next/server/chunks/ssr/src_presentation_web_f1edcf5e._.js.map +1 -1
  327. package/web/.next/server/chunks/ssr/src_presentation_web_f9436804._.js +1 -1
  328. package/web/.next/server/chunks/ssr/src_presentation_web_f9436804._.js.map +1 -1
  329. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  330. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  331. package/web/.next/server/pages/500.html +2 -2
  332. package/web/.next/server/server-reference-manifest.js +1 -1
  333. package/web/.next/server/server-reference-manifest.json +109 -64
  334. package/web/.next/static/chunks/0239d68df2738a2a.js +1 -0
  335. package/web/.next/static/chunks/{b40755bc75789277.js → 101e7888c4b7e328.js} +1 -1
  336. package/web/.next/static/chunks/{53f9385d4a447ad4.js → 18fa374b1b856687.js} +2 -2
  337. package/web/.next/static/chunks/{7c3fe3c694874dea.js → 32940aa08b947f66.js} +1 -1
  338. package/web/.next/static/chunks/{ae94e98b7163890b.js → 42d86b3a628702b0.js} +1 -1
  339. package/web/.next/static/chunks/6da04daaac881f27.js +1 -0
  340. package/web/.next/static/chunks/6f9ba92ee19bcbd7.js +5 -0
  341. package/web/.next/static/chunks/{25bbd99fa3dcc0b2.js → 79a8ec8b8de391f8.js} +1 -1
  342. package/web/.next/static/chunks/{e8444bf5f6c35f8b.js → 7bbe49d9daedd94d.js} +5 -1
  343. package/web/.next/static/chunks/{d8e96baa3feb79cb.js → 7e0cb9a6e06f075f.js} +1 -1
  344. package/web/.next/static/chunks/87b197ebd301232a.js +3 -0
  345. package/web/.next/static/chunks/8fe70d4e73e1fe31.css +1 -0
  346. package/web/.next/static/chunks/{6ad23a3ac827b65b.js → b3051a00d29f0f0f.js} +1 -1
  347. package/web/.next/static/chunks/b6b07ccbccda00e2.js +7 -0
  348. package/web/.next/static/chunks/b9b3a6d83e07b213.js +1 -0
  349. package/web/.next/static/chunks/c92bc820f657f9d9.js +1 -0
  350. package/web/.next/static/chunks/{e11508a76f5fca98.js → d436ca26f19e7c42.js} +1 -1
  351. package/web/.next/static/chunks/{5635fe220632fced.js → d8505faa90c97f2b.js} +1 -1
  352. package/web/.next/static/chunks/{d7310881615cb55b.js → e2b0da48f8e15118.js} +1 -1
  353. package/web/.next/static/chunks/{443c0073e58878d8.js → e3ecbef934b77afa.js} +1 -1
  354. package/web/.next/static/chunks/{b6ddc3e5f64bef7f.js → e6fc771fc21a0b62.js} +1 -1
  355. package/web/.next/static/chunks/ecafea5bc026ed41.js +1 -0
  356. package/web/.next/static/chunks/{fe29d30a75e697ed.js → f28fa2d7fa19eee6.js} +1 -1
  357. package/web/.next/static/chunks/f79d32f56056c680.js +1 -0
  358. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_5da25833._.js.map +0 -1
  359. package/web/.next/server/chunks/ssr/[root-of-the-server]__a6f2b763._.js +0 -3
  360. package/web/.next/server/chunks/ssr/[root-of-the-server]__a6f2b763._.js.map +0 -1
  361. package/web/.next/server/chunks/ssr/[root-of-the-server]__bb391c45._.js.map +0 -1
  362. package/web/.next/server/chunks/ssr/_295fffde._.js.map +0 -1
  363. package/web/.next/server/chunks/ssr/_44531b76._.js +0 -9
  364. package/web/.next/server/chunks/ssr/_44531b76._.js.map +0 -1
  365. package/web/.next/server/chunks/ssr/_5bf2415e._.js +0 -7
  366. package/web/.next/server/chunks/ssr/_5bf2415e._.js.map +0 -1
  367. package/web/.next/server/chunks/ssr/_869a3a15._.js +0 -3
  368. package/web/.next/server/chunks/ssr/_869a3a15._.js.map +0 -1
  369. package/web/.next/server/chunks/ssr/_b227ff50._.js +0 -3
  370. package/web/.next/server/chunks/ssr/_b227ff50._.js.map +0 -1
  371. package/web/.next/server/chunks/ssr/_e071ba48._.js +0 -3
  372. package/web/.next/server/chunks/ssr/_e071ba48._.js.map +0 -1
  373. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js +0 -3
  374. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +0 -1
  375. package/web/.next/static/chunks/06b9d6dbf635c370.css +0 -1
  376. package/web/.next/static/chunks/15951ad67a810e2c.js +0 -5
  377. package/web/.next/static/chunks/1ae0cf5be30ef398.js +0 -1
  378. package/web/.next/static/chunks/7a9d8b705c0f8d2d.js +0 -7
  379. package/web/.next/static/chunks/8492d8e0b5f9a4e8.js +0 -1
  380. package/web/.next/static/chunks/927442d2628f6e22.js +0 -1
  381. package/web/.next/static/chunks/b99506a6f7bc2fa8.js +0 -1
  382. package/web/.next/static/chunks/be165be5db7a6054.js +0 -7
  383. package/web/.next/static/chunks/e65f14d14ad46a32.js +0 -1
  384. /package/web/.next/static/{_PzlF7w3QzhaBsMnhT75_ → i04ZwSXpTvkppxSePII4p}/_buildManifest.js +0 -0
  385. /package/web/.next/static/{_PzlF7w3QzhaBsMnhT75_ → i04ZwSXpTvkppxSePII4p}/_clientMiddlewareManifest.json +0 -0
  386. /package/web/.next/static/{_PzlF7w3QzhaBsMnhT75_ → i04ZwSXpTvkppxSePII4p}/_ssgManifest.js +0 -0
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Messaging Tunnel Adapter
3
+ *
4
+ * Manages the WebSocket tunnel connection to the Commands.com Gateway and
5
+ * translates its binary/text frames into a presentation-agnostic callback
6
+ * for the consuming messaging service.
7
+ *
8
+ * Protocol reference:
9
+ * https://github.com/Commands-com/gateway/blob/main/internal/gateway/integrations_tunnel.go
10
+ *
11
+ * Responsibilities:
12
+ * - Open an authenticated WebSocket (Bearer token on the upgrade headers)
13
+ * - Handle tunnel.connected → auto-activate the configured routes
14
+ * - Decode incoming tunnel.request frames and dispatch to `onRequest`
15
+ * - Send tunnel.response frames back with the handler's reply
16
+ * - Reconnect on disconnect with a small delay
17
+ */
18
+ import WebSocket from 'ws';
19
+ const RECONNECT_DELAY_MS = 5_000;
20
+ const PING_INTERVAL_MS = 25_000;
21
+ const defaultFactory = (url, options) => new WebSocket(url, options);
22
+ function headersArrayToRecord(pairs) {
23
+ if (!pairs)
24
+ return {};
25
+ const out = {};
26
+ for (const [k, v] of pairs) {
27
+ out[k.toLowerCase()] = v;
28
+ }
29
+ return out;
30
+ }
31
+ function headersRecordToArray(record) {
32
+ if (!record)
33
+ return undefined;
34
+ return Object.entries(record);
35
+ }
36
+ function base64Encode(s) {
37
+ return Buffer.from(s, 'utf8').toString('base64');
38
+ }
39
+ function base64Decode(b64) {
40
+ return Buffer.from(b64, 'base64').toString('utf8');
41
+ }
42
+ export class MessagingTunnelAdapter {
43
+ deps;
44
+ ws = null;
45
+ requestHandler = null;
46
+ pingTimer = null;
47
+ reconnectTimer = null;
48
+ connected = false;
49
+ stopping = false;
50
+ activatedRoutes = new Set();
51
+ factory;
52
+ constructor(deps) {
53
+ this.deps = deps;
54
+ this.factory = deps.webSocketFactory ?? defaultFactory;
55
+ }
56
+ /** Register a handler for inbound tunnel.request frames. */
57
+ onRequest(handler) {
58
+ this.requestHandler = handler;
59
+ }
60
+ /** Whether the WebSocket tunnel is currently open. */
61
+ isConnected() {
62
+ return this.connected;
63
+ }
64
+ /** Whether the given route has been activated on the tunnel. */
65
+ isRouteActivated(routeId) {
66
+ return this.activatedRoutes.has(routeId);
67
+ }
68
+ /**
69
+ * Open the tunnel and resolve once the server has emitted tunnel.connected.
70
+ * Reconnects are silent (fire-and-forget).
71
+ */
72
+ async connect() {
73
+ if (this.connected || this.stopping)
74
+ return;
75
+ const base = this.deps.gatewayUrl.replace(/^http/, 'ws').replace(/\/$/, '');
76
+ const url = `${base}/gateway/v1/integrations/tunnel/connect?device_id=${encodeURIComponent(this.deps.deviceId)}`;
77
+ const ws = this.factory(url, {
78
+ headers: { authorization: `Bearer ${this.deps.accessToken}` },
79
+ });
80
+ this.ws = ws;
81
+ await new Promise((resolve, reject) => {
82
+ const onceOpen = () => {
83
+ ws.off('error', onceError);
84
+ resolve();
85
+ };
86
+ const onceError = (err) => {
87
+ ws.off('open', onceOpen);
88
+ reject(err);
89
+ };
90
+ ws.once('open', onceOpen);
91
+ ws.once('error', onceError);
92
+ });
93
+ ws.on('message', (data) => {
94
+ this.handleRawFrame(data).catch(() => {
95
+ // Malformed frames are non-fatal.
96
+ });
97
+ });
98
+ ws.on('close', () => this.handleClose());
99
+ ws.on('error', () => {
100
+ // Errors also trigger close; avoid duplicate handling.
101
+ });
102
+ this.connected = true;
103
+ this.startPing();
104
+ }
105
+ /** Close the tunnel permanently (no auto-reconnect). */
106
+ async disconnect() {
107
+ this.stopping = true;
108
+ this.stopPing();
109
+ this.clearReconnect();
110
+ this.activatedRoutes.clear();
111
+ if (this.ws) {
112
+ try {
113
+ this.ws.close();
114
+ }
115
+ catch {
116
+ // ignore
117
+ }
118
+ this.ws = null;
119
+ }
120
+ this.connected = false;
121
+ }
122
+ async handleRawFrame(data) {
123
+ const raw = typeof data === 'string' ? data : data.toString('utf8');
124
+ let frame;
125
+ try {
126
+ frame = JSON.parse(raw);
127
+ }
128
+ catch {
129
+ return;
130
+ }
131
+ switch (frame.type) {
132
+ case 'tunnel.connected':
133
+ this.handleConnected(frame);
134
+ return;
135
+ case 'tunnel.activate.result':
136
+ this.handleActivateResult(frame);
137
+ return;
138
+ case 'tunnel.request':
139
+ await this.handleRequest(frame);
140
+ return;
141
+ case 'tunnel.route_deactivated':
142
+ this.handleRouteDeactivated(frame);
143
+ return;
144
+ case 'tunnel.error':
145
+ this.handleProtocolError(frame);
146
+ return;
147
+ default:
148
+ // Unknown frame — silently drop per gateway forward-compat policy.
149
+ return;
150
+ }
151
+ }
152
+ handleConnected(_frame) {
153
+ // Auto-activate every configured route. The gateway expects a single
154
+ // batched frame with a `routes` array — sending one-at-a-time with
155
+ // `route_id` is silently ignored.
156
+ if (this.deps.routeIds.length === 0)
157
+ return;
158
+ this.sendFrame({
159
+ type: 'tunnel.activate',
160
+ routes: [...this.deps.routeIds],
161
+ });
162
+ }
163
+ handleActivateResult(frame) {
164
+ // Gateway returns "active" for newly-activated routes. Treat any
165
+ // non-rejected status as success to be forward-compatible.
166
+ for (const entry of frame.results ?? []) {
167
+ if (entry.status && entry.status !== 'rejected') {
168
+ this.activatedRoutes.add(entry.route_id);
169
+ }
170
+ }
171
+ }
172
+ handleRouteDeactivated(frame) {
173
+ this.activatedRoutes.delete(frame.route_id);
174
+ }
175
+ handleProtocolError(_frame) {
176
+ // No-op — recoverable errors are surfaced through reconnection.
177
+ }
178
+ async handleRequest(frame) {
179
+ if (!this.requestHandler) {
180
+ this.sendFrame({
181
+ type: 'tunnel.response',
182
+ request_id: frame.request_id,
183
+ status: 503,
184
+ });
185
+ return;
186
+ }
187
+ const decoded = {
188
+ requestId: frame.request_id,
189
+ routeId: frame.route_id,
190
+ method: frame.method,
191
+ path: frame.path,
192
+ headers: headersArrayToRecord(frame.headers),
193
+ body: frame.body_base64 ? base64Decode(frame.body_base64) : '',
194
+ };
195
+ let response;
196
+ try {
197
+ response = await this.requestHandler(decoded);
198
+ }
199
+ catch {
200
+ response = { status: 500 };
201
+ }
202
+ this.sendFrame({
203
+ type: 'tunnel.response',
204
+ request_id: frame.request_id,
205
+ status: response.status,
206
+ headers: headersRecordToArray(response.headers),
207
+ body_base64: response.body ? base64Encode(response.body) : undefined,
208
+ });
209
+ }
210
+ sendFrame(frame) {
211
+ if (this.ws?.readyState !== WebSocket.OPEN)
212
+ return;
213
+ try {
214
+ this.ws.send(JSON.stringify(frame));
215
+ }
216
+ catch {
217
+ // ignore — close handler will reconnect
218
+ }
219
+ }
220
+ handleClose() {
221
+ this.connected = false;
222
+ this.activatedRoutes.clear();
223
+ this.stopPing();
224
+ if (!this.stopping) {
225
+ this.scheduleReconnect();
226
+ }
227
+ }
228
+ startPing() {
229
+ this.pingTimer = setInterval(() => {
230
+ if (this.ws?.readyState === WebSocket.OPEN) {
231
+ try {
232
+ this.ws.ping();
233
+ }
234
+ catch {
235
+ // ignore
236
+ }
237
+ }
238
+ }, PING_INTERVAL_MS);
239
+ this.pingTimer.unref?.();
240
+ }
241
+ stopPing() {
242
+ if (this.pingTimer) {
243
+ clearInterval(this.pingTimer);
244
+ this.pingTimer = null;
245
+ }
246
+ }
247
+ scheduleReconnect() {
248
+ this.clearReconnect();
249
+ this.reconnectTimer = setTimeout(() => {
250
+ this.connect().catch(() => {
251
+ // Will retry on the next close event.
252
+ });
253
+ }, RECONNECT_DELAY_MS);
254
+ this.reconnectTimer.unref?.();
255
+ }
256
+ clearReconnect() {
257
+ if (this.reconnectTimer) {
258
+ clearTimeout(this.reconnectTimer);
259
+ this.reconnectTimer = null;
260
+ }
261
+ }
262
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Messaging Service
3
+ *
4
+ * Core orchestrator for the external messaging remote control feature.
5
+ * Wires together:
6
+ * - Commands.com Gateway tunnel (inbound webhook delivery)
7
+ * - Telegram Bot API client (outbound replies + notifications)
8
+ * - Command executor (parses slash commands, runs use cases)
9
+ * - Notification emitter (debounced forwarding from the local event bus)
10
+ * - Chat relay (interactive agent ↔ messenger bridge)
11
+ * - Pairing auto-confirm (matches /pair <code> against pending codes)
12
+ *
13
+ * Lifecycle:
14
+ * 1. `isConfigured()` checks settings for required fields.
15
+ * 2. `start()` opens the tunnel and subscribes to the notification bus.
16
+ * 3. Inbound `tunnel.request` frames are parsed as Telegram Update objects
17
+ * and dispatched to either the pair confirm flow or the command executor.
18
+ * 4. `stop()` tears everything down.
19
+ */
20
+ import type { IMessagingService } from '../../../application/ports/output/services/messaging-service.interface.js';
21
+ import type { MessagingNotification, MessagingConfig } from '../../../domain/generated/output.js';
22
+ import type { NotificationBus } from '../notifications/notification-bus.js';
23
+ import type { IFeatureRepository } from '../../../application/ports/output/repositories/feature-repository.interface.js';
24
+ import type { ListFeaturesUseCase } from '../../../application/use-cases/features/list-features.use-case.js';
25
+ import type { ShowFeatureUseCase } from '../../../application/use-cases/features/show-feature.use-case.js';
26
+ import type { CreateFeatureUseCase } from '../../../application/use-cases/features/create/create-feature.use-case.js';
27
+ import type { ApproveAgentRunUseCase } from '../../../application/use-cases/agents/approve-agent-run.use-case.js';
28
+ import type { RejectAgentRunUseCase } from '../../../application/use-cases/agents/reject-agent-run.use-case.js';
29
+ import type { StopAgentRunUseCase } from '../../../application/use-cases/agents/stop-agent-run.use-case.js';
30
+ import type { ResumeFeatureUseCase } from '../../../application/use-cases/features/resume-feature.use-case.js';
31
+ import type { ListRepositoriesUseCase } from '../../../application/use-cases/repositories/list-repositories.use-case.js';
32
+ import type { ConfirmMessagingPairingUseCase } from '../../../application/use-cases/messaging/confirm-pairing.use-case.js';
33
+ import type { ITelegramClient } from '../../../application/ports/output/services/telegram-client.interface.js';
34
+ import type { IInteractiveSessionService } from '../../../application/ports/output/services/interactive-session-service.interface.js';
35
+ interface MessagingServiceDeps {
36
+ config: MessagingConfig;
37
+ accessToken: string;
38
+ telegramClient: ITelegramClient;
39
+ /** Bot token the sender will use to reply to Telegram users. */
40
+ telegramBotToken?: string;
41
+ notificationBus: NotificationBus;
42
+ featureRepo: IFeatureRepository;
43
+ createFeature: CreateFeatureUseCase;
44
+ approveAgentRun: ApproveAgentRunUseCase;
45
+ rejectAgentRun: RejectAgentRunUseCase;
46
+ stopAgentRun: StopAgentRunUseCase;
47
+ resumeFeature: ResumeFeatureUseCase;
48
+ listFeatures: ListFeaturesUseCase;
49
+ showFeature: ShowFeatureUseCase;
50
+ listRepositories: ListRepositoriesUseCase;
51
+ confirmPairing: ConfirmMessagingPairingUseCase;
52
+ interactiveSessionService: IInteractiveSessionService;
53
+ }
54
+ export declare class MessagingService implements IMessagingService {
55
+ private readonly deps;
56
+ private tunnelAdapter;
57
+ private commandExecutor;
58
+ private notificationEmitter;
59
+ private chatRelay;
60
+ private sender;
61
+ private started;
62
+ constructor(deps: MessagingServiceDeps);
63
+ isConfigured(): boolean;
64
+ isConnected(): boolean;
65
+ start(): Promise<void>;
66
+ stop(): Promise<void>;
67
+ sendNotification(notification: MessagingNotification): Promise<void>;
68
+ private collectRouteIds;
69
+ private handleTunnelRequest;
70
+ private handleChatStart;
71
+ private handleChatEnd;
72
+ private handleChatMessage;
73
+ private platformForRoute;
74
+ private handlePairConfirm;
75
+ private sendReply;
76
+ }
77
+ export {};
78
+ //# sourceMappingURL=messaging.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/messaging/messaging.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2EAA2E,CAAC;AACnH,OAAO,KAAK,EAEV,qBAAqB,EACrB,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAa7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mEAAmE,CAAC;AAC7G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kEAAkE,CAAC;AAC3G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2EAA2E,CAAC;AACtH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qEAAqE,CAAC;AAClH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAC5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oEAAoE,CAAC;AAC/G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2EAA2E,CAAC;AACzH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,sEAAsE,CAAC;AAC3H,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yEAAyE,CAAC;AAC/G,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qFAAqF,CAAC;AAGtI,UAAU,oBAAoB;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,eAAe,CAAC;IAChC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,oBAAoB,CAAC;IACpC,eAAe,EAAE,sBAAsB,CAAC;IACxC,cAAc,EAAE,qBAAqB,CAAC;IACtC,YAAY,EAAE,mBAAmB,CAAC;IAClC,aAAa,EAAE,oBAAoB,CAAC;IACpC,YAAY,EAAE,mBAAmB,CAAC;IAClC,WAAW,EAAE,kBAAkB,CAAC;IAChC,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,cAAc,EAAE,8BAA8B,CAAC;IAC/C,yBAAyB,EAAE,0BAA0B,CAAC;CACvD;AAmCD,qBAAa,gBAAiB,YAAW,iBAAiB;IAQ5C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEK,IAAI,EAAE,oBAAoB;IAEvD,YAAY,IAAI,OAAO;IAgBvB,WAAW,IAAI,OAAO;IAIhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAerB,gBAAgB,CAAC,YAAY,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E,OAAO,CAAC,eAAe;YAQT,mBAAmB;YAiEnB,eAAe;YAgDf,aAAa;YAMb,iBAAiB;IAa/B,OAAO,CAAC,gBAAgB;YAOV,iBAAiB;YAyBjB,SAAS;CASxB"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Messaging Service
3
+ *
4
+ * Core orchestrator for the external messaging remote control feature.
5
+ * Wires together:
6
+ * - Commands.com Gateway tunnel (inbound webhook delivery)
7
+ * - Telegram Bot API client (outbound replies + notifications)
8
+ * - Command executor (parses slash commands, runs use cases)
9
+ * - Notification emitter (debounced forwarding from the local event bus)
10
+ * - Chat relay (interactive agent ↔ messenger bridge)
11
+ * - Pairing auto-confirm (matches /pair <code> against pending codes)
12
+ *
13
+ * Lifecycle:
14
+ * 1. `isConfigured()` checks settings for required fields.
15
+ * 2. `start()` opens the tunnel and subscribes to the notification bus.
16
+ * 3. Inbound `tunnel.request` frames are parsed as Telegram Update objects
17
+ * and dispatched to either the pair confirm flow or the command executor.
18
+ * 4. `stop()` tears everything down.
19
+ */
20
+ import { MessagingPlatform, MessagingFrameType, MessagingCommandType, } from '../../../domain/generated/output.js';
21
+ import { MessagingTunnelAdapter } from './messaging-tunnel.adapter.js';
22
+ import { MessagingCommandExecutor } from './command-executor.js';
23
+ import { MessagingNotificationEmitter } from './notification-emitter.js';
24
+ import { MessagingChatRelay } from './chat-relay.js';
25
+ import { TelegramMessageSender } from './telegram-message-sender.js';
26
+ import { parseTelegramUpdate, parsePairCommand } from './telegram-webhook.parser.js';
27
+ import { parseWhatsAppUpdate } from './whatsapp-webhook.parser.js';
28
+ const COMMAND_REGEX = /^\/(new|approve|reject|stop|resume|status|list|chat|end|mute|unmute|help)(?:@\w+)?(?:\s+(\S+))?(?:\s+(.+))?$/i;
29
+ const COMMANDS_TAKING_FEATURE_ID = [
30
+ MessagingCommandType.Approve,
31
+ MessagingCommandType.Reject,
32
+ MessagingCommandType.Stop,
33
+ MessagingCommandType.Resume,
34
+ MessagingCommandType.Status,
35
+ MessagingCommandType.Chat,
36
+ ];
37
+ function parseSlashCommand(text) {
38
+ const match = text.trim().match(COMMAND_REGEX);
39
+ if (!match)
40
+ return null;
41
+ const command = match[1].toLowerCase();
42
+ const second = match[2];
43
+ const rest = match[3];
44
+ if (COMMANDS_TAKING_FEATURE_ID.includes(command) && second) {
45
+ return { command, featureId: second, args: rest };
46
+ }
47
+ const args = [second, rest].filter(Boolean).join(' ');
48
+ return { command, args: args || undefined };
49
+ }
50
+ export class MessagingService {
51
+ deps;
52
+ tunnelAdapter = null;
53
+ commandExecutor = null;
54
+ notificationEmitter = null;
55
+ chatRelay = null;
56
+ sender = null;
57
+ started = false;
58
+ constructor(deps) {
59
+ this.deps = deps;
60
+ }
61
+ isConfigured() {
62
+ const { config } = this.deps;
63
+ if (!config.enabled || !config.gatewayUrl || !config.deviceId)
64
+ return false;
65
+ // The tunnel must start as soon as a route exists — not only after the
66
+ // user is fully paired. The auto-confirm flow requires this: the daemon
67
+ // needs to be receiving tunnel.request frames in order to see the
68
+ // inbound `/pair <code>` message from the user's first DM and call
69
+ // ConfirmMessagingPairingUseCase. If we gated on `paired && chatId`
70
+ // the user could never complete pairing without a manual chatId entry
71
+ // in the UI.
72
+ const telegramReady = !!config.telegram?.routeId;
73
+ const whatsappReady = !!config.whatsapp?.routeId;
74
+ return telegramReady || whatsappReady;
75
+ }
76
+ isConnected() {
77
+ return this.tunnelAdapter?.isConnected() ?? false;
78
+ }
79
+ async start() {
80
+ if (this.started || !this.isConfigured())
81
+ return;
82
+ const { config, accessToken, telegramClient, notificationBus, featureRepo } = this.deps;
83
+ const routeIds = this.collectRouteIds();
84
+ this.tunnelAdapter = new MessagingTunnelAdapter({
85
+ gatewayUrl: config.gatewayUrl,
86
+ accessToken,
87
+ deviceId: config.deviceId,
88
+ routeIds,
89
+ });
90
+ this.sender = new TelegramMessageSender(telegramClient, () => {
91
+ const chatId = this.deps.config.telegram?.chatId;
92
+ const botToken = this.deps.telegramBotToken;
93
+ if (!chatId || !botToken)
94
+ return null;
95
+ return { chatId, botToken };
96
+ });
97
+ this.commandExecutor = new MessagingCommandExecutor(featureRepo, this.deps.createFeature, this.deps.approveAgentRun, this.deps.rejectAgentRun, this.deps.stopAgentRun, this.deps.resumeFeature, this.deps.listFeatures, this.deps.showFeature, this.deps.listRepositories);
98
+ this.notificationEmitter = new MessagingNotificationEmitter(this.sender, notificationBus, config.debounceMs ?? 5_000);
99
+ this.chatRelay = new MessagingChatRelay(this.sender, config.chatBufferMs ?? 3_000);
100
+ this.tunnelAdapter.onRequest((req) => this.handleTunnelRequest(req));
101
+ try {
102
+ await this.tunnelAdapter.connect();
103
+ }
104
+ catch {
105
+ // Connection failure is non-fatal — the adapter reconnects automatically.
106
+ }
107
+ this.notificationEmitter.start();
108
+ this.started = true;
109
+ }
110
+ async stop() {
111
+ if (!this.started)
112
+ return;
113
+ this.notificationEmitter?.stop();
114
+ this.chatRelay?.stop();
115
+ await this.tunnelAdapter?.disconnect();
116
+ this.tunnelAdapter = null;
117
+ this.commandExecutor = null;
118
+ this.notificationEmitter = null;
119
+ this.chatRelay = null;
120
+ this.sender = null;
121
+ this.started = false;
122
+ }
123
+ async sendNotification(notification) {
124
+ await this.sender?.send(notification);
125
+ }
126
+ collectRouteIds() {
127
+ const out = [];
128
+ const { config } = this.deps;
129
+ if (config.telegram?.routeId)
130
+ out.push(config.telegram.routeId);
131
+ if (config.whatsapp?.routeId)
132
+ out.push(config.whatsapp.routeId);
133
+ return out;
134
+ }
135
+ async handleTunnelRequest(req) {
136
+ // Per-route → platform resolution.
137
+ const platform = this.platformForRoute(req.routeId);
138
+ if (!platform) {
139
+ return { status: 404 };
140
+ }
141
+ const parsed = platform === MessagingPlatform.Telegram
142
+ ? parseTelegramUpdate(req.body)
143
+ : parseWhatsAppUpdate(req.body);
144
+ if (!parsed) {
145
+ return { status: 200 };
146
+ }
147
+ // 1. Handle /pair <code> auto-confirmation before anything else.
148
+ const pair = parsePairCommand(parsed.text);
149
+ if (pair) {
150
+ await this.handlePairConfirm(platform, parsed.chatId, pair.code);
151
+ return { status: 200 };
152
+ }
153
+ // 2. Dispatch slash commands via the command executor. /chat and /end
154
+ // are handled specially because they manipulate the chat relay.
155
+ const slash = parseSlashCommand(parsed.text);
156
+ if (slash) {
157
+ if (slash.command === MessagingCommandType.Chat) {
158
+ await this.handleChatStart(platform, parsed.chatId, slash.featureId);
159
+ return { status: 200 };
160
+ }
161
+ if (slash.command === MessagingCommandType.End) {
162
+ await this.handleChatEnd(parsed.chatId);
163
+ return { status: 200 };
164
+ }
165
+ if (this.commandExecutor) {
166
+ const cmd = {
167
+ type: MessagingFrameType.Command,
168
+ command: slash.command,
169
+ featureId: slash.featureId,
170
+ args: slash.args,
171
+ chatId: parsed.chatId,
172
+ platform,
173
+ };
174
+ try {
175
+ const reply = await this.commandExecutor.execute(cmd);
176
+ await this.sendReply(parsed.chatId, reply);
177
+ }
178
+ catch (err) {
179
+ const msg = err instanceof Error ? err.message : String(err);
180
+ await this.sendReply(parsed.chatId, `Command failed: ${msg}`);
181
+ }
182
+ return { status: 200 };
183
+ }
184
+ }
185
+ // 3. If there's an active chat relay, forward the message to the
186
+ // interactive session.
187
+ if (this.chatRelay?.hasActiveRelay()) {
188
+ await this.handleChatMessage(parsed.chatId, parsed.text);
189
+ return { status: 200 };
190
+ }
191
+ // 4. Unknown message — ignore silently.
192
+ return { status: 200 };
193
+ }
194
+ async handleChatStart(platform, chatId, featureId) {
195
+ if (!featureId) {
196
+ await this.sendReply(chatId, 'Usage: /chat <feature_id>');
197
+ return;
198
+ }
199
+ if (!this.chatRelay)
200
+ return;
201
+ const feature = await this.deps.featureRepo.findById(featureId);
202
+ if (!feature) {
203
+ await this.sendReply(chatId, `Feature ${featureId} not found.`);
204
+ return;
205
+ }
206
+ if (!feature.worktreePath) {
207
+ await this.sendReply(chatId, `Feature ${featureId} has no worktree yet — it may not be checked out.`);
208
+ return;
209
+ }
210
+ // Subscribe to the interactive session's stream and forward deltas to
211
+ // the chat relay buffer. The unsubscribe handle is owned by the relay.
212
+ const unsubscribe = this.deps.interactiveSessionService.subscribeByFeature(feature.id, (chunk) => {
213
+ if (chunk.delta) {
214
+ this.chatRelay?.bufferAgentOutput(chunk.delta);
215
+ }
216
+ if (chunk.done) {
217
+ this.chatRelay?.flushBuffer();
218
+ }
219
+ });
220
+ const message = this.chatRelay.startRelay(feature.id, chatId, platform, feature.worktreePath, unsubscribe);
221
+ await this.sendReply(chatId, message);
222
+ }
223
+ async handleChatEnd(chatId) {
224
+ if (!this.chatRelay)
225
+ return;
226
+ const message = this.chatRelay.endRelay();
227
+ await this.sendReply(chatId, message);
228
+ }
229
+ async handleChatMessage(_chatId, text) {
230
+ if (!this.chatRelay?.hasActiveRelay())
231
+ return;
232
+ const featureId = this.chatRelay.getActiveFeatureId();
233
+ const worktreePath = this.chatRelay.getActiveWorktreePath();
234
+ if (!featureId || !worktreePath)
235
+ return;
236
+ try {
237
+ await this.deps.interactiveSessionService.sendUserMessage(featureId, text, worktreePath);
238
+ }
239
+ catch {
240
+ // Delivery failures surface as missing agent replies — no point
241
+ // spamming the user's chat with error toasts.
242
+ }
243
+ }
244
+ platformForRoute(routeId) {
245
+ const { config } = this.deps;
246
+ if (config.telegram?.routeId === routeId)
247
+ return MessagingPlatform.Telegram;
248
+ if (config.whatsapp?.routeId === routeId)
249
+ return MessagingPlatform.WhatsApp;
250
+ return null;
251
+ }
252
+ async handlePairConfirm(platform, chatId, code) {
253
+ const { config } = this.deps;
254
+ const platformCfg = platform === MessagingPlatform.Telegram ? config.telegram : config.whatsapp;
255
+ if (!platformCfg?.pendingPairingCode || platformCfg.pendingPairingCode !== code) {
256
+ await this.sendReply(chatId, 'Invalid or expired pairing code.');
257
+ return;
258
+ }
259
+ try {
260
+ await this.deps.confirmPairing.execute({ platform, chatId });
261
+ await this.sendReply(chatId, 'Paired with Shep. You can now send commands like /status, /list, or /help.');
262
+ }
263
+ catch (err) {
264
+ const msg = err instanceof Error ? err.message : String(err);
265
+ await this.sendReply(chatId, `Pairing failed: ${msg}`);
266
+ }
267
+ }
268
+ async sendReply(chatId, text) {
269
+ const botToken = this.deps.telegramBotToken;
270
+ if (!botToken || !text)
271
+ return;
272
+ try {
273
+ await this.deps.telegramClient.sendMessage({ botToken, chatId, text });
274
+ }
275
+ catch {
276
+ // Non-fatal — swallow so the tunnel response still completes.
277
+ }
278
+ }
279
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Messaging Notification Emitter
3
+ *
4
+ * Subscribes to Shep's existing NotificationEventBus and pushes
5
+ * events through the Gateway tunnel for delivery to messaging apps.
6
+ *
7
+ * Features:
8
+ * - Debouncing: events for the same feature+type are collapsed within
9
+ * a configurable window (default 5s) to avoid flooding
10
+ * - Content sanitization: all messages are scrubbed of paths, code, and secrets
11
+ * - Gate events are never debounced — delivered immediately
12
+ */
13
+ import type { NotificationBus } from '../notifications/notification-bus.js';
14
+ import type { IMessageSender } from '../../../application/ports/output/services/message-sender.interface.js';
15
+ /**
16
+ * Subscribes to the notification event bus and forwards events
17
+ * to the messaging tunnel for delivery to the user's phone.
18
+ */
19
+ export declare class MessagingNotificationEmitter {
20
+ private readonly sender;
21
+ private readonly notificationBus;
22
+ private readonly debounceMs;
23
+ private debounceTimers;
24
+ private listening;
25
+ private handler;
26
+ constructor(sender: IMessageSender, notificationBus: NotificationBus, debounceMs?: number);
27
+ /** Start listening for notification events */
28
+ start(): void;
29
+ /** Stop listening for notification events */
30
+ stop(): void;
31
+ private emitDebounced;
32
+ }
33
+ //# sourceMappingURL=notification-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-emitter.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/messaging/notification-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAE5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wEAAwE,CAAC;AAI7G;;;GAGG;AACH,qBAAa,4BAA4B;IAMrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP7B,OAAO,CAAC,cAAc,CAAoD;IAC1E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAqD;gBAGjD,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,eAAe,EAChC,UAAU,GAAE,MAA4B;IAG3D,8CAA8C;IAC9C,KAAK,IAAI,IAAI;IAwBb,6CAA6C;IAC7C,IAAI,IAAI,IAAI;IAgBZ,OAAO,CAAC,aAAa;CAiBtB"}