@jingyi0605/codingns 0.6.5 → 0.7.1

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 (225) hide show
  1. package/dist/public/assets/AdaptiveButlerPage-Cd8nPdO0.js +3 -0
  2. package/dist/public/assets/{App-B9HcTkMT.js → App-CyxK-Nos.js} +6 -6
  3. package/dist/public/assets/{BootstrapPage-BgLdZEKQ.js → BootstrapPage-DEwPKWR8.js} +1 -1
  4. package/dist/public/assets/ConversationPage-CxWtRhfz.js +6 -0
  5. package/dist/public/assets/{DesktopDetachPreviewPage-YCBnyC58.js → DesktopDetachPreviewPage-DDOWolgB.js} +1 -1
  6. package/dist/public/assets/{DesktopWindowPage-CrvndE23.js → DesktopWindowPage-CtS9D8FD.js} +1 -1
  7. package/dist/public/assets/{FileContextPanel-CdC7GGw5.js → FileContextPanel-CNOjhsi5.js} +1 -1
  8. package/dist/public/assets/GitSidebar-DpC4UhFy.js +6 -0
  9. package/dist/public/assets/{MobileCreateSessionSheet-Cb2HM-y3.js → MobileCreateSessionSheet-DE4pTyXj.js} +1 -1
  10. package/dist/public/assets/{MobileTopHeaderFrame-etF2HKlm.js → MobileTopHeaderFrame-D_ZbS0qi.js} +1 -1
  11. package/dist/public/assets/{MobileWorkspaceSwitcherHeader-CuGJ31kb.js → MobileWorkspaceSwitcherHeader-Dc12IAXc.js} +1 -1
  12. package/dist/public/assets/{RelayConnectEntryPage-BB6DbGtP.js → RelayConnectEntryPage-D8kyZfdm.js} +1 -1
  13. package/dist/public/assets/{ServerSettingsModal-Bl1sacZg.js → ServerSettingsModal-8eRu6VXr.js} +1 -1
  14. package/dist/public/assets/SessionIndexPage-DIi0JWKP.js +1 -0
  15. package/dist/public/assets/SettingsPage-OQq3kp32.js +2 -0
  16. package/dist/public/assets/{TerminalManagerPanel-BOm8Hi_v.js → TerminalManagerPanel-BEMzisSy.js} +1 -1
  17. package/dist/public/assets/{TerminalPage-B5JNFU6w.js → TerminalPage-CXLQfwjU.js} +18 -18
  18. package/dist/public/assets/{TerminalRuntimeFallbackModal-CM3LRKOJ.js → TerminalRuntimeFallbackModal-BY_VUAbq.js} +1 -1
  19. package/dist/public/assets/ToolFilesPage-CYx3DgHg.js +1 -0
  20. package/dist/public/assets/ToolGitPage-fgQcvF6v.js +1 -0
  21. package/dist/public/assets/ToolProcessesPage-BL6yDDPV.js +1 -0
  22. package/dist/public/assets/{ToolsHomePage-DsJp0y8A.js → ToolsHomePage-B1n2OeVw.js} +1 -1
  23. package/dist/public/assets/{WorkbenchLandingPage-DyPei0e-.js → WorkbenchLandingPage-Cu9yAWYo.js} +1 -1
  24. package/dist/public/assets/WorkbenchLayout-D6hGXWGE.js +244 -0
  25. package/dist/public/assets/{WorkbenchModal-LNfB69qx.js → WorkbenchModal-Bpb_G1-U.js} +1 -1
  26. package/dist/public/assets/WorkbenchShellRoute-BCjcGWhl.js +1 -0
  27. package/dist/public/assets/{WorkspaceDebugDetailPage-CaXj5zVI.js → WorkspaceDebugDetailPage-CZwT99iQ.js} +1 -1
  28. package/dist/public/assets/{WorkspaceDetailPage-DOexuuaw.js → WorkspaceDetailPage-DCM-olfU.js} +1 -1
  29. package/dist/public/assets/{WorkspaceHomePage-DkCHNjKD.js → WorkspaceHomePage-CsIIqIma.js} +1 -1
  30. package/dist/public/assets/{client-runtime-manager-6OoYHXGd.js → client-runtime-manager-CMK7kLp8.js} +1 -1
  31. package/dist/public/assets/file-tree-icon-Bv-apgA1.js +3 -0
  32. package/dist/public/assets/index-CkkzIvxs.css +1 -0
  33. package/dist/public/assets/index-O3gOb1E0.js +42 -0
  34. package/dist/public/assets/{login-direct-candidate-resolver-CLlYtBRq.js → login-direct-candidate-resolver-Bn4I5JHh.js} +1 -1
  35. package/dist/public/assets/model-switch-api-ZGnyVir7.js +1 -0
  36. package/dist/public/assets/{preferences-service-BCcfYP_d.js → preferences-service-scuqVhuA.js} +1 -1
  37. package/dist/public/assets/realtime-client-TRootbbB.js +1 -0
  38. package/dist/public/assets/{relay-entry-BmLkMKuq.js → relay-entry-eyCjVFMA.js} +1 -1
  39. package/dist/public/assets/styles-DkbkRgWw.css +1 -0
  40. package/dist/public/assets/{terminal-runtime-meta-0h-75uRy.js → terminal-runtime-meta-BGcnzxqn.js} +1 -1
  41. package/dist/public/assets/{useRegisteredDebugTemplates-rBVmAqh3.js → useRegisteredDebugTemplates-BdgPIDVM.js} +1 -1
  42. package/dist/public/index.html +2 -2
  43. package/dist/server/config/env.js +21 -1
  44. package/dist/server/config/env.js.map +1 -1
  45. package/dist/server/config/opencode-base-url-resolver.d.ts +16 -0
  46. package/dist/server/config/opencode-base-url-resolver.js +154 -0
  47. package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
  48. package/dist/server/helpers/wechat-claw-runtime/main.d.ts +1 -0
  49. package/dist/server/helpers/wechat-claw-runtime/main.js +38 -0
  50. package/dist/server/helpers/wechat-claw-runtime/main.js.map +1 -0
  51. package/dist/server/helpers/wechat-claw-runtime/modules/errors.d.ts +5 -0
  52. package/dist/server/helpers/wechat-claw-runtime/modules/errors.js +32 -0
  53. package/dist/server/helpers/wechat-claw-runtime/modules/errors.js.map +1 -0
  54. package/dist/server/helpers/wechat-claw-runtime/modules/login-service.d.ts +16 -0
  55. package/dist/server/helpers/wechat-claw-runtime/modules/login-service.js +209 -0
  56. package/dist/server/helpers/wechat-claw-runtime/modules/login-service.js.map +1 -0
  57. package/dist/server/helpers/wechat-claw-runtime/modules/poll-service.d.ts +18 -0
  58. package/dist/server/helpers/wechat-claw-runtime/modules/poll-service.js +135 -0
  59. package/dist/server/helpers/wechat-claw-runtime/modules/poll-service.js.map +1 -0
  60. package/dist/server/helpers/wechat-claw-runtime/modules/runtime-state-store.d.ts +34 -0
  61. package/dist/server/helpers/wechat-claw-runtime/modules/runtime-state-store.js +394 -0
  62. package/dist/server/helpers/wechat-claw-runtime/modules/runtime-state-store.js.map +1 -0
  63. package/dist/server/helpers/wechat-claw-runtime/modules/send-service.d.ts +9 -0
  64. package/dist/server/helpers/wechat-claw-runtime/modules/send-service.js +64 -0
  65. package/dist/server/helpers/wechat-claw-runtime/modules/send-service.js.map +1 -0
  66. package/dist/server/helpers/wechat-claw-runtime/modules/types.d.ts +167 -0
  67. package/dist/server/helpers/wechat-claw-runtime/modules/types.js +3 -0
  68. package/dist/server/helpers/wechat-claw-runtime/modules/types.js.map +1 -0
  69. package/dist/server/helpers/wechat-claw-runtime/modules/wechat-api-client.d.ts +34 -0
  70. package/dist/server/helpers/wechat-claw-runtime/modules/wechat-api-client.js +160 -0
  71. package/dist/server/helpers/wechat-claw-runtime/modules/wechat-api-client.js.map +1 -0
  72. package/dist/server/helpers/wechat-claw-runtime/routes/accounts.d.ts +9 -0
  73. package/dist/server/helpers/wechat-claw-runtime/routes/accounts.js +24 -0
  74. package/dist/server/helpers/wechat-claw-runtime/routes/accounts.js.map +1 -0
  75. package/dist/server/helpers/wechat-claw-runtime/server.d.ts +5 -0
  76. package/dist/server/helpers/wechat-claw-runtime/server.js +36 -0
  77. package/dist/server/helpers/wechat-claw-runtime/server.js.map +1 -0
  78. package/dist/server/middlewares/auth-guard.js +4 -1
  79. package/dist/server/middlewares/auth-guard.js.map +1 -1
  80. package/dist/server/modules/butler/butler-control-session-service.d.ts +16 -1
  81. package/dist/server/modules/butler/butler-control-session-service.js +106 -75
  82. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  83. package/dist/server/modules/butler/butler-session-service.js +44 -15
  84. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  85. package/dist/server/modules/channels/channel-bridge-service.d.ts +55 -0
  86. package/dist/server/modules/channels/channel-bridge-service.js +340 -0
  87. package/dist/server/modules/channels/channel-bridge-service.js.map +1 -0
  88. package/dist/server/modules/channels/channel-controller.d.ts +52 -0
  89. package/dist/server/modules/channels/channel-controller.js +54 -0
  90. package/dist/server/modules/channels/channel-controller.js.map +1 -0
  91. package/dist/server/modules/channels/channel-delivery-service.d.ts +63 -0
  92. package/dist/server/modules/channels/channel-delivery-service.js +429 -0
  93. package/dist/server/modules/channels/channel-delivery-service.js.map +1 -0
  94. package/dist/server/modules/channels/channel-gateway-controller.d.ts +15 -0
  95. package/dist/server/modules/channels/channel-gateway-controller.js +16 -0
  96. package/dist/server/modules/channels/channel-gateway-controller.js.map +1 -0
  97. package/dist/server/modules/channels/channel-gateway-service.d.ts +24 -0
  98. package/dist/server/modules/channels/channel-gateway-service.js +56 -0
  99. package/dist/server/modules/channels/channel-gateway-service.js.map +1 -0
  100. package/dist/server/modules/channels/channel-platform-adapters.d.ts +46 -0
  101. package/dist/server/modules/channels/channel-platform-adapters.js +315 -0
  102. package/dist/server/modules/channels/channel-platform-adapters.js.map +1 -0
  103. package/dist/server/modules/channels/channel-platform-catalog.d.ts +3 -0
  104. package/dist/server/modules/channels/channel-platform-catalog.js +42 -0
  105. package/dist/server/modules/channels/channel-platform-catalog.js.map +1 -0
  106. package/dist/server/modules/channels/channel-polling-scheduler.d.ts +31 -0
  107. package/dist/server/modules/channels/channel-polling-scheduler.js +93 -0
  108. package/dist/server/modules/channels/channel-polling-scheduler.js.map +1 -0
  109. package/dist/server/modules/channels/channel-polling-service.d.ts +46 -0
  110. package/dist/server/modules/channels/channel-polling-service.js +176 -0
  111. package/dist/server/modules/channels/channel-polling-service.js.map +1 -0
  112. package/dist/server/modules/channels/channel-service.d.ts +108 -0
  113. package/dist/server/modules/channels/channel-service.js +397 -0
  114. package/dist/server/modules/channels/channel-service.js.map +1 -0
  115. package/dist/server/modules/channels/wechat-claw-runtime-boundary.d.ts +4 -0
  116. package/dist/server/modules/channels/wechat-claw-runtime-boundary.js +13 -0
  117. package/dist/server/modules/channels/wechat-claw-runtime-boundary.js.map +1 -0
  118. package/dist/server/modules/channels/wechat-claw-runtime-client.d.ts +14 -0
  119. package/dist/server/modules/channels/wechat-claw-runtime-client.js +95 -0
  120. package/dist/server/modules/channels/wechat-claw-runtime-client.js.map +1 -0
  121. package/dist/server/modules/channels/wechat-claw-runtime-manager.d.ts +16 -0
  122. package/dist/server/modules/channels/wechat-claw-runtime-manager.js +133 -0
  123. package/dist/server/modules/channels/wechat-claw-runtime-manager.js.map +1 -0
  124. package/dist/server/modules/channels/wechat-claw-runtime-types.d.ts +1 -0
  125. package/dist/server/modules/channels/wechat-claw-runtime-types.js +2 -0
  126. package/dist/server/modules/channels/wechat-claw-runtime-types.js.map +1 -0
  127. package/dist/server/modules/git/git-controller.d.ts +3 -1
  128. package/dist/server/modules/git/git-controller.js +9 -2
  129. package/dist/server/modules/git/git-controller.js.map +1 -1
  130. package/dist/server/modules/git/git-read-service.js +2 -1
  131. package/dist/server/modules/git/git-read-service.js.map +1 -1
  132. package/dist/server/modules/git/git-remote-credential-service.d.ts +1 -0
  133. package/dist/server/modules/git/git-remote-credential-service.js +4 -0
  134. package/dist/server/modules/git/git-remote-credential-service.js.map +1 -1
  135. package/dist/server/modules/git/types.d.ts +1 -0
  136. package/dist/server/modules/opencli/opencli-bridge-skill-service.js +2 -1
  137. package/dist/server/modules/opencli/opencli-bridge-skill-service.js.map +1 -1
  138. package/dist/server/modules/provider/codex-model-options.js +14 -15
  139. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  140. package/dist/server/modules/provider/provider-catalog-service.d.ts +5 -6
  141. package/dist/server/modules/provider/provider-catalog-service.js +12 -57
  142. package/dist/server/modules/provider/provider-catalog-service.js.map +1 -1
  143. package/dist/server/modules/provider/provider-controller.d.ts +1 -0
  144. package/dist/server/modules/provider/provider-controller.js +5 -0
  145. package/dist/server/modules/provider/provider-controller.js.map +1 -1
  146. package/dist/server/modules/provider/provider-discovery-helper-process.js +2 -1
  147. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  148. package/dist/server/modules/provider/provider-runtime-state-service.d.ts +24 -0
  149. package/dist/server/modules/provider/provider-runtime-state-service.js +141 -0
  150. package/dist/server/modules/provider/provider-runtime-state-service.js.map +1 -0
  151. package/dist/server/modules/sessions/session-history-service.d.ts +3 -3
  152. package/dist/server/modules/sessions/session-history-service.js +150 -47
  153. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  154. package/dist/server/modules/sessions/session-live-runtime-service.js +9 -11
  155. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  156. package/dist/server/modules/sessions/session-provider-config-service.d.ts +1 -0
  157. package/dist/server/modules/sessions/session-provider-config-service.js +28 -7
  158. package/dist/server/modules/sessions/session-provider-config-service.js.map +1 -1
  159. package/dist/server/modules/sessions/session-provider-error-mapper.js +7 -0
  160. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  161. package/dist/server/modules/tasks/task-types.d.ts +2 -0
  162. package/dist/server/modules/tasks/task-types.js +2 -0
  163. package/dist/server/modules/tasks/task-types.js.map +1 -1
  164. package/dist/server/routes/channels.d.ts +3 -0
  165. package/dist/server/routes/channels.js +16 -0
  166. package/dist/server/routes/channels.js.map +1 -0
  167. package/dist/server/routes/providers.js +1 -0
  168. package/dist/server/routes/providers.js.map +1 -1
  169. package/dist/server/routes/public.d.ts +2 -1
  170. package/dist/server/routes/public.js +3 -1
  171. package/dist/server/routes/public.js.map +1 -1
  172. package/dist/server/server/create-server.d.ts +22 -0
  173. package/dist/server/server/create-server.js +63 -4
  174. package/dist/server/server/create-server.js.map +1 -1
  175. package/dist/server/shared/http/error-handler.js +59 -3
  176. package/dist/server/shared/http/error-handler.js.map +1 -1
  177. package/dist/server/storage/repositories/channel-account-repository.d.ts +12 -0
  178. package/dist/server/storage/repositories/channel-account-repository.js +153 -0
  179. package/dist/server/storage/repositories/channel-account-repository.js.map +1 -0
  180. package/dist/server/storage/repositories/channel-delivery-repository.d.ts +13 -0
  181. package/dist/server/storage/repositories/channel-delivery-repository.js +156 -0
  182. package/dist/server/storage/repositories/channel-delivery-repository.js.map +1 -0
  183. package/dist/server/storage/repositories/channel-inbound-event-repository.d.ts +12 -0
  184. package/dist/server/storage/repositories/channel-inbound-event-repository.js +144 -0
  185. package/dist/server/storage/repositories/channel-inbound-event-repository.js.map +1 -0
  186. package/dist/server/storage/repositories/channel-thread-repository.d.ts +12 -0
  187. package/dist/server/storage/repositories/channel-thread-repository.js +152 -0
  188. package/dist/server/storage/repositories/channel-thread-repository.js.map +1 -0
  189. package/dist/server/storage/repositories/provider-runtime-state-repository.d.ts +9 -0
  190. package/dist/server/storage/repositories/provider-runtime-state-repository.js +50 -0
  191. package/dist/server/storage/repositories/provider-runtime-state-repository.js.map +1 -0
  192. package/dist/server/storage/sqlite/schema.sql +114 -0
  193. package/dist/server/types/domain.d.ts +82 -0
  194. package/dist/server/ws/workbench-ws-hub.js +8 -2
  195. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  196. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +6 -0
  197. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +398 -0
  198. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -1
  199. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +75 -15
  200. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  201. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +61 -8
  202. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  203. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +32 -4
  204. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  205. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  206. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +94 -21
  207. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  208. package/package.json +5 -1
  209. package/dist/public/assets/AdaptiveButlerPage-CfsUVZKl.js +0 -3
  210. package/dist/public/assets/ConversationPage-Cj8go7L0.js +0 -4
  211. package/dist/public/assets/GitSidebar-z2SBinQh.js +0 -6
  212. package/dist/public/assets/SessionIndexPage-NbF9gJnp.js +0 -1
  213. package/dist/public/assets/SettingsPage-DGsmQpLv.js +0 -1
  214. package/dist/public/assets/ToolFilesPage-GSqKQsj_.js +0 -1
  215. package/dist/public/assets/ToolGitPage-BVFWMMQp.js +0 -1
  216. package/dist/public/assets/ToolProcessesPage-DZ456fYz.js +0 -1
  217. package/dist/public/assets/WorkbenchLayout-DlbgBT3n.js +0 -4
  218. package/dist/public/assets/WorkbenchShellRoute-BsxumYx5.js +0 -1
  219. package/dist/public/assets/file-tree-icon-9pt1OStn.js +0 -31
  220. package/dist/public/assets/index-BwlbvwaA.css +0 -1
  221. package/dist/public/assets/index-DSw-TkQL.js +0 -42
  222. package/dist/public/assets/model-switch-api-C-l8-E1S.js +0 -1
  223. package/dist/public/assets/session-runtime-machine-DgtvREca.js +0 -21
  224. package/dist/public/assets/styles-CsEMfdaS.css +0 -1
  225. /package/dist/public/assets/{styles-DRVvx_kv.js → styles-JKFlsYFv.js} +0 -0
@@ -0,0 +1,144 @@
1
+ export class ChannelInboundEventRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ findById(id) {
7
+ const row = this.db
8
+ .prepare(`SELECT
9
+ id,
10
+ channel_account_id,
11
+ external_event_id,
12
+ external_conversation_key,
13
+ external_user_id,
14
+ control_session_id,
15
+ session_id,
16
+ text_content,
17
+ payload_json,
18
+ status,
19
+ error_message,
20
+ received_at,
21
+ processed_at
22
+ FROM channel_inbound_events
23
+ WHERE id = ?
24
+ LIMIT 1`)
25
+ .get(id);
26
+ return row ? mapChannelInboundEventRow(row) : null;
27
+ }
28
+ listByAccountId(channelAccountId, limit = 50) {
29
+ return this.db
30
+ .prepare(`SELECT
31
+ id,
32
+ channel_account_id,
33
+ external_event_id,
34
+ external_conversation_key,
35
+ external_user_id,
36
+ control_session_id,
37
+ session_id,
38
+ text_content,
39
+ payload_json,
40
+ status,
41
+ error_message,
42
+ received_at,
43
+ processed_at
44
+ FROM channel_inbound_events
45
+ WHERE channel_account_id = ?
46
+ ORDER BY received_at DESC
47
+ LIMIT ?`)
48
+ .all(channelAccountId, limit)
49
+ .map((row) => mapChannelInboundEventRow(row));
50
+ }
51
+ countByAccountId(channelAccountId) {
52
+ const row = this.db
53
+ .prepare(`SELECT COUNT(*) AS count
54
+ FROM channel_inbound_events
55
+ WHERE channel_account_id = ?`)
56
+ .get(channelAccountId);
57
+ return row.count;
58
+ }
59
+ findByAccountAndExternalEventId(channelAccountId, externalEventId) {
60
+ const row = this.db
61
+ .prepare(`SELECT
62
+ id,
63
+ channel_account_id,
64
+ external_event_id,
65
+ external_conversation_key,
66
+ external_user_id,
67
+ control_session_id,
68
+ session_id,
69
+ text_content,
70
+ payload_json,
71
+ status,
72
+ error_message,
73
+ received_at,
74
+ processed_at
75
+ FROM channel_inbound_events
76
+ WHERE channel_account_id = ?
77
+ AND external_event_id = ?`)
78
+ .get(channelAccountId, externalEventId);
79
+ return row ? mapChannelInboundEventRow(row) : null;
80
+ }
81
+ create(record) {
82
+ this.db
83
+ .prepare(`INSERT INTO channel_inbound_events (
84
+ id,
85
+ channel_account_id,
86
+ external_event_id,
87
+ external_conversation_key,
88
+ external_user_id,
89
+ control_session_id,
90
+ session_id,
91
+ text_content,
92
+ payload_json,
93
+ status,
94
+ error_message,
95
+ received_at,
96
+ processed_at
97
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
98
+ .run(record.id, record.channelAccountId, record.externalEventId, record.externalConversationKey, record.externalUserId, record.controlSessionId, record.sessionId, record.textContent, JSON.stringify(record.payload), record.status, record.errorMessage, record.receivedAt, record.processedAt);
99
+ return record;
100
+ }
101
+ update(record) {
102
+ this.db
103
+ .prepare(`UPDATE channel_inbound_events
104
+ SET control_session_id = ?,
105
+ session_id = ?,
106
+ text_content = ?,
107
+ payload_json = ?,
108
+ status = ?,
109
+ error_message = ?,
110
+ processed_at = ?
111
+ WHERE id = ?`)
112
+ .run(record.controlSessionId, record.sessionId, record.textContent, JSON.stringify(record.payload), record.status, record.errorMessage, record.processedAt, record.id);
113
+ return record;
114
+ }
115
+ }
116
+ function mapChannelInboundEventRow(row) {
117
+ return {
118
+ id: row.id,
119
+ channelAccountId: row.channel_account_id,
120
+ externalEventId: row.external_event_id,
121
+ externalConversationKey: row.external_conversation_key,
122
+ externalUserId: row.external_user_id,
123
+ controlSessionId: row.control_session_id,
124
+ sessionId: row.session_id,
125
+ textContent: row.text_content,
126
+ payload: parseJsonObject(row.payload_json),
127
+ status: row.status,
128
+ errorMessage: row.error_message,
129
+ receivedAt: row.received_at,
130
+ processedAt: row.processed_at
131
+ };
132
+ }
133
+ function parseJsonObject(raw) {
134
+ try {
135
+ const parsed = JSON.parse(raw);
136
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
137
+ ? parsed
138
+ : {};
139
+ }
140
+ catch {
141
+ return {};
142
+ }
143
+ }
144
+ //# sourceMappingURL=channel-inbound-event-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-inbound-event-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/channel-inbound-event-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { ChannelThread } from "../../types/domain.js";
3
+ export declare class ChannelThreadRepository {
4
+ private readonly db;
5
+ constructor(db: Database.Database);
6
+ findById(id: string): ChannelThread | null;
7
+ listByAccountId(channelAccountId: string, limit?: number): ChannelThread[];
8
+ countByAccountId(channelAccountId: string): number;
9
+ findByAccountAndConversationKey(channelAccountId: string, externalConversationKey: string): ChannelThread | null;
10
+ create(record: ChannelThread): ChannelThread;
11
+ update(record: ChannelThread): ChannelThread;
12
+ }
@@ -0,0 +1,152 @@
1
+ export class ChannelThreadRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ findById(id) {
7
+ const row = this.db
8
+ .prepare(`SELECT
9
+ id,
10
+ channel_account_id,
11
+ external_conversation_key,
12
+ external_user_id,
13
+ external_thread_key,
14
+ control_session_id,
15
+ session_id,
16
+ title,
17
+ status,
18
+ last_inbound_at,
19
+ last_outbound_at,
20
+ last_transport_context_json,
21
+ created_at,
22
+ updated_at
23
+ FROM channel_threads
24
+ WHERE id = ?
25
+ LIMIT 1`)
26
+ .get(id);
27
+ return row ? mapChannelThreadRow(row) : null;
28
+ }
29
+ listByAccountId(channelAccountId, limit = 50) {
30
+ return this.db
31
+ .prepare(`SELECT
32
+ id,
33
+ channel_account_id,
34
+ external_conversation_key,
35
+ external_user_id,
36
+ external_thread_key,
37
+ control_session_id,
38
+ session_id,
39
+ title,
40
+ status,
41
+ last_inbound_at,
42
+ last_outbound_at,
43
+ last_transport_context_json,
44
+ created_at,
45
+ updated_at
46
+ FROM channel_threads
47
+ WHERE channel_account_id = ?
48
+ ORDER BY updated_at DESC, created_at DESC
49
+ LIMIT ?`)
50
+ .all(channelAccountId, limit)
51
+ .map((row) => mapChannelThreadRow(row));
52
+ }
53
+ countByAccountId(channelAccountId) {
54
+ const row = this.db
55
+ .prepare(`SELECT COUNT(*) AS count
56
+ FROM channel_threads
57
+ WHERE channel_account_id = ?`)
58
+ .get(channelAccountId);
59
+ return row.count;
60
+ }
61
+ findByAccountAndConversationKey(channelAccountId, externalConversationKey) {
62
+ const row = this.db
63
+ .prepare(`SELECT
64
+ id,
65
+ channel_account_id,
66
+ external_conversation_key,
67
+ external_user_id,
68
+ external_thread_key,
69
+ control_session_id,
70
+ session_id,
71
+ title,
72
+ status,
73
+ last_inbound_at,
74
+ last_outbound_at,
75
+ last_transport_context_json,
76
+ created_at,
77
+ updated_at
78
+ FROM channel_threads
79
+ WHERE channel_account_id = ?
80
+ AND external_conversation_key = ?`)
81
+ .get(channelAccountId, externalConversationKey);
82
+ return row ? mapChannelThreadRow(row) : null;
83
+ }
84
+ create(record) {
85
+ this.db
86
+ .prepare(`INSERT INTO channel_threads (
87
+ id,
88
+ channel_account_id,
89
+ external_conversation_key,
90
+ external_user_id,
91
+ external_thread_key,
92
+ control_session_id,
93
+ session_id,
94
+ title,
95
+ status,
96
+ last_inbound_at,
97
+ last_outbound_at,
98
+ last_transport_context_json,
99
+ created_at,
100
+ updated_at
101
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
102
+ .run(record.id, record.channelAccountId, record.externalConversationKey, record.externalUserId, record.externalThreadKey, record.controlSessionId, record.sessionId, record.title, record.status, record.lastInboundAt, record.lastOutboundAt, JSON.stringify(record.lastTransportContext), record.createdAt, record.updatedAt);
103
+ return record;
104
+ }
105
+ update(record) {
106
+ this.db
107
+ .prepare(`UPDATE channel_threads
108
+ SET external_user_id = ?,
109
+ external_thread_key = ?,
110
+ control_session_id = ?,
111
+ session_id = ?,
112
+ title = ?,
113
+ status = ?,
114
+ last_inbound_at = ?,
115
+ last_outbound_at = ?,
116
+ last_transport_context_json = ?,
117
+ updated_at = ?
118
+ WHERE id = ?`)
119
+ .run(record.externalUserId, record.externalThreadKey, record.controlSessionId, record.sessionId, record.title, record.status, record.lastInboundAt, record.lastOutboundAt, JSON.stringify(record.lastTransportContext), record.updatedAt, record.id);
120
+ return record;
121
+ }
122
+ }
123
+ function mapChannelThreadRow(row) {
124
+ return {
125
+ id: row.id,
126
+ channelAccountId: row.channel_account_id,
127
+ externalConversationKey: row.external_conversation_key,
128
+ externalUserId: row.external_user_id,
129
+ externalThreadKey: row.external_thread_key,
130
+ controlSessionId: row.control_session_id,
131
+ sessionId: row.session_id,
132
+ title: row.title,
133
+ status: row.status,
134
+ lastInboundAt: row.last_inbound_at,
135
+ lastOutboundAt: row.last_outbound_at,
136
+ lastTransportContext: parseJsonObject(row.last_transport_context_json),
137
+ createdAt: row.created_at,
138
+ updatedAt: row.updated_at
139
+ };
140
+ }
141
+ function parseJsonObject(raw) {
142
+ try {
143
+ const parsed = JSON.parse(raw);
144
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
145
+ ? parsed
146
+ : {};
147
+ }
148
+ catch {
149
+ return {};
150
+ }
151
+ }
152
+ //# sourceMappingURL=channel-thread-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-thread-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/channel-thread-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { ProviderRuntimeStateRecord } from "../../types/domain.js";
3
+ export declare class ProviderRuntimeStateRepository {
4
+ private readonly db;
5
+ constructor(db: Database.Database);
6
+ list(): ProviderRuntimeStateRecord[];
7
+ get(providerId: string): ProviderRuntimeStateRecord | null;
8
+ upsert(record: ProviderRuntimeStateRecord): ProviderRuntimeStateRecord;
9
+ }
@@ -0,0 +1,50 @@
1
+ export class ProviderRuntimeStateRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ list() {
7
+ return this.db
8
+ .prepare(`SELECT provider_id, install_state, version, updated_at
9
+ FROM provider_runtime_states
10
+ ORDER BY provider_id ASC`)
11
+ .all()
12
+ .map((row) => mapProviderRuntimeStateRow(row));
13
+ }
14
+ get(providerId) {
15
+ const normalizedProviderId = providerId.trim();
16
+ if (!normalizedProviderId) {
17
+ return null;
18
+ }
19
+ const row = this.db
20
+ .prepare(`SELECT provider_id, install_state, version, updated_at
21
+ FROM provider_runtime_states
22
+ WHERE provider_id = ?`)
23
+ .get(normalizedProviderId);
24
+ return row ? mapProviderRuntimeStateRow(row) : null;
25
+ }
26
+ upsert(record) {
27
+ this.db
28
+ .prepare(`INSERT INTO provider_runtime_states (
29
+ provider_id,
30
+ install_state,
31
+ version,
32
+ updated_at
33
+ ) VALUES (?, ?, ?, ?)
34
+ ON CONFLICT(provider_id) DO UPDATE SET
35
+ install_state = excluded.install_state,
36
+ version = excluded.version,
37
+ updated_at = excluded.updated_at`)
38
+ .run(record.providerId, record.installState, record.version, record.updatedAt);
39
+ return record;
40
+ }
41
+ }
42
+ function mapProviderRuntimeStateRow(row) {
43
+ return {
44
+ providerId: row.provider_id,
45
+ installState: row.install_state,
46
+ version: row.version,
47
+ updatedAt: row.updated_at
48
+ };
49
+ }
50
+ //# sourceMappingURL=provider-runtime-state-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-runtime-state-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/provider-runtime-state-repository.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,8BAA8B;IACZ;IAA7B,YAA6B,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;IAAG,CAAC;IAEtD,IAAI;QACF,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;kCAE0B,CAC3B;aACA,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,0BAA0B,CAAC,GAA8B,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,MAAM,oBAAoB,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QAE/C,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN;;+BAEuB,CACxB;aACA,GAAG,CAAC,oBAAoB,CAAwC,CAAC;QAEpE,OAAO,GAAG,CAAC,CAAC,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,MAAkC;QACvC,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;;;;;;;;;4CASoC,CACrC;aACA,GAAG,CACF,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,SAAS,CACjB,CAAC;QAEJ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AASD,SAAS,0BAA0B,CAAC,GAA4B;IAC9D,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,YAAY,EAAE,GAAG,CAAC,aAAa;QAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
@@ -476,6 +476,16 @@ CREATE TABLE IF NOT EXISTS provider_control_profiles (
476
476
  CREATE INDEX IF NOT EXISTS idx_provider_control_profiles_enabled
477
477
  ON provider_control_profiles(enabled, updated_at DESC);
478
478
 
479
+ CREATE TABLE IF NOT EXISTS provider_runtime_states (
480
+ provider_id TEXT PRIMARY KEY,
481
+ install_state TEXT NOT NULL CHECK (install_state IN ('ready', 'missing', 'unknown')),
482
+ version TEXT,
483
+ updated_at TEXT NOT NULL
484
+ );
485
+
486
+ CREATE INDEX IF NOT EXISTS idx_provider_runtime_states_install
487
+ ON provider_runtime_states(install_state, updated_at DESC);
488
+
479
489
  CREATE TABLE IF NOT EXISTS git_remote_credentials (
480
490
  user_id TEXT NOT NULL,
481
491
  remote_url TEXT NOT NULL,
@@ -1230,6 +1240,110 @@ CREATE INDEX IF NOT EXISTS idx_verification_runs_project_created_at
1230
1240
  CREATE INDEX IF NOT EXISTS idx_verification_runs_project_status
1231
1241
  ON verification_runs(project_id, status, created_at DESC);
1232
1242
 
1243
+ CREATE TABLE IF NOT EXISTS channel_accounts (
1244
+ id TEXT PRIMARY KEY,
1245
+ user_id TEXT NOT NULL,
1246
+ platform_code TEXT NOT NULL CHECK (
1247
+ platform_code IN ('wechat-claw', 'telegram')
1248
+ ),
1249
+ display_name TEXT NOT NULL,
1250
+ provider_id TEXT NOT NULL CHECK (provider_id IN ('codex', 'claude-code')),
1251
+ connection_mode TEXT NOT NULL CHECK (connection_mode IN ('webhook', 'polling', 'bridge')),
1252
+ status TEXT NOT NULL CHECK (status IN ('active', 'disabled', 'degraded')),
1253
+ config_json TEXT NOT NULL,
1254
+ runtime_state_json TEXT NOT NULL,
1255
+ last_inbound_at TEXT,
1256
+ last_outbound_at TEXT,
1257
+ last_error TEXT,
1258
+ created_at TEXT NOT NULL,
1259
+ updated_at TEXT NOT NULL,
1260
+ FOREIGN KEY (user_id) REFERENCES auth_users(id)
1261
+ );
1262
+
1263
+ CREATE INDEX IF NOT EXISTS idx_channel_accounts_user_updated_at
1264
+ ON channel_accounts(user_id, updated_at DESC);
1265
+ CREATE INDEX IF NOT EXISTS idx_channel_accounts_platform_status
1266
+ ON channel_accounts(platform_code, status, updated_at DESC);
1267
+
1268
+ CREATE TABLE IF NOT EXISTS channel_threads (
1269
+ id TEXT PRIMARY KEY,
1270
+ channel_account_id TEXT NOT NULL,
1271
+ external_conversation_key TEXT NOT NULL,
1272
+ external_user_id TEXT,
1273
+ external_thread_key TEXT,
1274
+ control_session_id TEXT,
1275
+ session_id TEXT,
1276
+ title TEXT,
1277
+ status TEXT NOT NULL CHECK (status IN ('active', 'closed', 'failed')),
1278
+ last_inbound_at TEXT,
1279
+ last_outbound_at TEXT,
1280
+ last_transport_context_json TEXT NOT NULL,
1281
+ created_at TEXT NOT NULL,
1282
+ updated_at TEXT NOT NULL,
1283
+ FOREIGN KEY (channel_account_id) REFERENCES channel_accounts(id) ON DELETE CASCADE,
1284
+ FOREIGN KEY (control_session_id) REFERENCES butler_control_sessions(id),
1285
+ UNIQUE(channel_account_id, external_conversation_key)
1286
+ );
1287
+
1288
+ CREATE INDEX IF NOT EXISTS idx_channel_threads_account_updated_at
1289
+ ON channel_threads(channel_account_id, updated_at DESC);
1290
+ CREATE INDEX IF NOT EXISTS idx_channel_threads_account_status
1291
+ ON channel_threads(channel_account_id, status, updated_at DESC);
1292
+ CREATE INDEX IF NOT EXISTS idx_channel_threads_control_session
1293
+ ON channel_threads(control_session_id, updated_at DESC);
1294
+
1295
+ CREATE TABLE IF NOT EXISTS channel_inbound_events (
1296
+ id TEXT PRIMARY KEY,
1297
+ channel_account_id TEXT NOT NULL,
1298
+ external_event_id TEXT NOT NULL,
1299
+ external_conversation_key TEXT NOT NULL,
1300
+ external_user_id TEXT,
1301
+ control_session_id TEXT,
1302
+ session_id TEXT,
1303
+ text_content TEXT NOT NULL,
1304
+ payload_json TEXT NOT NULL,
1305
+ status TEXT NOT NULL CHECK (status IN ('received', 'dispatched', 'replied', 'failed', 'ignored')),
1306
+ error_message TEXT,
1307
+ received_at TEXT NOT NULL,
1308
+ processed_at TEXT,
1309
+ FOREIGN KEY (channel_account_id) REFERENCES channel_accounts(id) ON DELETE CASCADE,
1310
+ FOREIGN KEY (control_session_id) REFERENCES butler_control_sessions(id),
1311
+ UNIQUE(channel_account_id, external_event_id)
1312
+ );
1313
+
1314
+ CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_account_received_at
1315
+ ON channel_inbound_events(channel_account_id, received_at DESC);
1316
+ CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_account_status
1317
+ ON channel_inbound_events(channel_account_id, status, received_at DESC);
1318
+ CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_control_session
1319
+ ON channel_inbound_events(control_session_id, received_at DESC);
1320
+
1321
+ CREATE TABLE IF NOT EXISTS channel_deliveries (
1322
+ id TEXT PRIMARY KEY,
1323
+ channel_account_id TEXT NOT NULL,
1324
+ thread_id TEXT,
1325
+ inbound_event_id TEXT,
1326
+ control_session_id TEXT,
1327
+ session_id TEXT,
1328
+ text_content TEXT NOT NULL,
1329
+ provider_message_ref TEXT,
1330
+ status TEXT NOT NULL CHECK (status IN ('sent', 'failed', 'skipped')),
1331
+ error_message TEXT,
1332
+ created_at TEXT NOT NULL,
1333
+ updated_at TEXT NOT NULL,
1334
+ FOREIGN KEY (channel_account_id) REFERENCES channel_accounts(id) ON DELETE CASCADE,
1335
+ FOREIGN KEY (thread_id) REFERENCES channel_threads(id) ON DELETE SET NULL,
1336
+ FOREIGN KEY (inbound_event_id) REFERENCES channel_inbound_events(id) ON DELETE SET NULL,
1337
+ FOREIGN KEY (control_session_id) REFERENCES butler_control_sessions(id)
1338
+ );
1339
+
1340
+ CREATE INDEX IF NOT EXISTS idx_channel_deliveries_account_created_at
1341
+ ON channel_deliveries(channel_account_id, created_at DESC);
1342
+ CREATE INDEX IF NOT EXISTS idx_channel_deliveries_account_status
1343
+ ON channel_deliveries(channel_account_id, status, created_at DESC);
1344
+ CREATE INDEX IF NOT EXISTS idx_channel_deliveries_thread_created_at
1345
+ ON channel_deliveries(thread_id, created_at DESC);
1346
+
1233
1347
  CREATE TABLE IF NOT EXISTS instance_tailscale_config (
1234
1348
  id TEXT PRIMARY KEY CHECK (id = 'default'),
1235
1349
  activated INTEGER NOT NULL DEFAULT 0 CHECK (activated IN (0, 1)),
@@ -74,6 +74,13 @@ export interface AuthLoginAttemptRecord {
74
74
  createdAt: string;
75
75
  updatedAt: string;
76
76
  }
77
+ export type ProviderInstallState = "ready" | "missing" | "unknown";
78
+ export interface ProviderRuntimeStateRecord {
79
+ providerId: string;
80
+ installState: ProviderInstallState;
81
+ version: string | null;
82
+ updatedAt: string;
83
+ }
77
84
  export interface Workspace {
78
85
  id: string;
79
86
  name: string;
@@ -427,6 +434,13 @@ export interface GitRemoteCredentialRecord {
427
434
  updatedAt: string;
428
435
  }
429
436
  export type ButlerProfileProviderId = "codex" | "claude-code";
437
+ export type ChannelPlatformCode = "wechat-claw" | "telegram";
438
+ export type ChannelConnectionMode = "webhook" | "polling" | "bridge";
439
+ export type ChannelAccountStatus = "active" | "disabled" | "degraded";
440
+ export type ChannelMultiSessionSupportLevel = "supported" | "limited";
441
+ export type ChannelThreadStatus = "active" | "closed" | "failed";
442
+ export type ChannelInboundEventStatus = "received" | "dispatched" | "replied" | "failed" | "ignored";
443
+ export type ChannelDeliveryStatus = "sent" | "failed" | "skipped";
430
444
  export type ButlerAgentsMode = "inline" | "file";
431
445
  export type ButlerControlSessionStatus = "idle" | "running" | "failed" | "closed";
432
446
  export type ButlerControlTimerStatus = "active" | "completed" | "cancelled" | "failed";
@@ -489,6 +503,74 @@ export interface ButlerProfile {
489
503
  initializedAt: string;
490
504
  updatedAt: string;
491
505
  }
506
+ export interface ChannelPlatformCapability {
507
+ code: ChannelPlatformCode;
508
+ displayName: string;
509
+ supportedConnectionModes: ChannelConnectionMode[];
510
+ multiSessionSupportLevel: ChannelMultiSessionSupportLevel;
511
+ stageOneLimitations: string[];
512
+ }
513
+ export interface ChannelAccount {
514
+ id: string;
515
+ userId: string;
516
+ platformCode: ChannelPlatformCode;
517
+ displayName: string;
518
+ providerId: ButlerProfileProviderId;
519
+ connectionMode: ChannelConnectionMode;
520
+ status: ChannelAccountStatus;
521
+ config: Record<string, unknown>;
522
+ runtimeState: Record<string, unknown>;
523
+ lastInboundAt: string | null;
524
+ lastOutboundAt: string | null;
525
+ lastError: string | null;
526
+ createdAt: string;
527
+ updatedAt: string;
528
+ }
529
+ export interface ChannelThread {
530
+ id: string;
531
+ channelAccountId: string;
532
+ externalConversationKey: string;
533
+ externalUserId: string | null;
534
+ externalThreadKey: string | null;
535
+ controlSessionId: string | null;
536
+ sessionId: string | null;
537
+ title: string | null;
538
+ status: ChannelThreadStatus;
539
+ lastInboundAt: string | null;
540
+ lastOutboundAt: string | null;
541
+ lastTransportContext: Record<string, unknown>;
542
+ createdAt: string;
543
+ updatedAt: string;
544
+ }
545
+ export interface ChannelInboundEvent {
546
+ id: string;
547
+ channelAccountId: string;
548
+ externalEventId: string;
549
+ externalConversationKey: string;
550
+ externalUserId: string | null;
551
+ controlSessionId: string | null;
552
+ sessionId: string | null;
553
+ textContent: string;
554
+ payload: Record<string, unknown>;
555
+ status: ChannelInboundEventStatus;
556
+ errorMessage: string | null;
557
+ receivedAt: string;
558
+ processedAt: string | null;
559
+ }
560
+ export interface ChannelDelivery {
561
+ id: string;
562
+ channelAccountId: string;
563
+ threadId: string | null;
564
+ inboundEventId: string | null;
565
+ controlSessionId: string | null;
566
+ sessionId: string | null;
567
+ textContent: string;
568
+ providerMessageRef: string | null;
569
+ status: ChannelDeliveryStatus;
570
+ errorMessage: string | null;
571
+ createdAt: string;
572
+ updatedAt: string;
573
+ }
492
574
  export interface ButlerControlSession {
493
575
  id: string;
494
576
  providerId: ButlerProfileProviderId;
@@ -48,7 +48,11 @@ export class WorkbenchWsHub {
48
48
  case "workbench.subscribe":
49
49
  void this.sendWorkbenchSnapshotToClient(client, userId, channel, message.knownRevision);
50
50
  if (this.workbenchService.shouldRefreshSnapshot()) {
51
- this.workbenchService.scheduleSnapshotRefresh(userId);
51
+ void this.refreshAndBroadcast(userId, false, {
52
+ awaitDiscovery: true
53
+ }).catch((error) => {
54
+ this.reportAsyncError("workbenchSubscribeRefresh", error, { userId });
55
+ });
52
56
  }
53
57
  return true;
54
58
  case "workbench.refresh":
@@ -316,7 +320,9 @@ export class WorkbenchWsHub {
316
320
  if (!this.workbenchService.shouldRefreshSnapshot()) {
317
321
  return;
318
322
  }
319
- void this.refreshAndBroadcast(userId).catch((error) => {
323
+ void this.refreshAndBroadcast(userId, false, {
324
+ awaitDiscovery: true
325
+ }).catch((error) => {
320
326
  this.reportAsyncError("workbenchTimer", error, { userId });
321
327
  });
322
328
  }, WORKBENCH_REFRESH_INTERVAL_MS);