@clinebot/core 0.0.35 → 0.0.36

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 (335) hide show
  1. package/README.md +1 -2
  2. package/dist/ClineCore.d.ts +53 -39
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/index.d.ts +1 -1
  5. package/dist/account/index.d.ts.map +1 -1
  6. package/dist/account/rpc.d.ts +6 -6
  7. package/dist/account/rpc.d.ts.map +1 -1
  8. package/dist/cron/index.d.ts +6 -0
  9. package/dist/cron/index.d.ts.map +1 -0
  10. package/dist/cron/resource-limiter.d.ts +9 -0
  11. package/dist/cron/resource-limiter.d.ts.map +1 -0
  12. package/dist/cron/schedule-command-service.d.ts +10 -0
  13. package/dist/cron/schedule-command-service.d.ts.map +1 -0
  14. package/dist/cron/schedule-service.d.ts +100 -0
  15. package/dist/cron/schedule-service.d.ts.map +1 -0
  16. package/dist/cron/scheduler.d.ts +66 -0
  17. package/dist/cron/scheduler.d.ts.map +1 -0
  18. package/dist/cron/sqlite-schedule-store.d.ts +52 -0
  19. package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
  20. package/dist/extensions/config/agent-config-loader.d.ts +4 -3
  21. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  22. package/dist/extensions/config/runtime-commands.d.ts +1 -0
  23. package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
  24. package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
  25. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  26. package/dist/extensions/context/agentic-compaction.d.ts +2 -2
  27. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
  28. package/dist/extensions/context/compaction-shared.d.ts +5 -4
  29. package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
  30. package/dist/extensions/context/compaction.d.ts.map +1 -1
  31. package/dist/extensions/plugin/plugin-config-loader.d.ts +9 -2
  32. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  33. package/dist/extensions/plugin/plugin-loader.d.ts +5 -3
  34. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  35. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
  36. package/dist/extensions/plugin/plugin-sandbox.d.ts +15 -2
  37. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  38. package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
  39. package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
  40. package/dist/extensions/plugin-sandbox-bootstrap.js +211 -211
  41. package/dist/extensions/tools/definitions.d.ts +1 -1
  42. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  43. package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
  44. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
  45. package/dist/extensions/tools/executors/search.d.ts +1 -1
  46. package/dist/extensions/tools/executors/search.d.ts.map +1 -1
  47. package/dist/extensions/tools/index.d.ts +2 -0
  48. package/dist/extensions/tools/index.d.ts.map +1 -1
  49. package/dist/extensions/tools/presets.d.ts +26 -43
  50. package/dist/extensions/tools/presets.d.ts.map +1 -1
  51. package/dist/extensions/tools/runtime.d.ts +25 -0
  52. package/dist/extensions/tools/runtime.d.ts.map +1 -0
  53. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  54. package/dist/extensions/tools/team/team-tools.d.ts +1 -0
  55. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  56. package/dist/hooks/hook-file-hooks.d.ts +4 -1
  57. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  58. package/dist/hooks/index.d.ts +0 -1
  59. package/dist/hooks/index.d.ts.map +1 -1
  60. package/dist/hooks/subprocess.d.ts +8 -1
  61. package/dist/hooks/subprocess.d.ts.map +1 -1
  62. package/dist/hub/browser-websocket.d.ts +18 -0
  63. package/dist/hub/browser-websocket.d.ts.map +1 -0
  64. package/dist/hub/client.d.ts +45 -0
  65. package/dist/hub/client.d.ts.map +1 -0
  66. package/dist/hub/connect.d.ts +15 -0
  67. package/dist/hub/connect.d.ts.map +1 -0
  68. package/dist/hub/daemon-entry.d.ts +2 -0
  69. package/dist/hub/daemon-entry.d.ts.map +1 -0
  70. package/dist/hub/daemon-entry.js +1045 -0
  71. package/dist/hub/daemon.d.ts +5 -0
  72. package/dist/hub/daemon.d.ts.map +1 -0
  73. package/dist/hub/defaults.d.ts +13 -0
  74. package/dist/hub/defaults.d.ts.map +1 -0
  75. package/dist/hub/discovery.d.ts +29 -0
  76. package/dist/hub/discovery.d.ts.map +1 -0
  77. package/dist/hub/index.d.ts +15 -0
  78. package/dist/hub/index.d.ts.map +1 -0
  79. package/dist/hub/index.js +1044 -0
  80. package/dist/hub/native-transport.d.ts +17 -0
  81. package/dist/hub/native-transport.d.ts.map +1 -0
  82. package/dist/hub/runtime-handlers.d.ts +11 -0
  83. package/dist/hub/runtime-handlers.d.ts.map +1 -0
  84. package/dist/hub/server.d.ts +86 -0
  85. package/dist/hub/server.d.ts.map +1 -0
  86. package/dist/hub/session-client.d.ts +87 -0
  87. package/dist/hub/session-client.d.ts.map +1 -0
  88. package/dist/hub/start-shared-server.d.ts +19 -0
  89. package/dist/hub/start-shared-server.d.ts.map +1 -0
  90. package/dist/hub/transport.d.ts +8 -0
  91. package/dist/hub/transport.d.ts.map +1 -0
  92. package/dist/hub/ui-client.d.ts +44 -0
  93. package/dist/hub/ui-client.d.ts.map +1 -0
  94. package/dist/hub/workspace.d.ts +4 -0
  95. package/dist/hub/workspace.d.ts.map +1 -0
  96. package/dist/index.d.ts +26 -15
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +498 -476
  99. package/dist/llms/configured-provider-registry.d.ts +28 -0
  100. package/dist/llms/configured-provider-registry.d.ts.map +1 -0
  101. package/dist/llms/provider-defaults.d.ts +27 -0
  102. package/dist/llms/provider-defaults.d.ts.map +1 -0
  103. package/dist/llms/provider-settings.d.ts +202 -0
  104. package/dist/llms/provider-settings.d.ts.map +1 -0
  105. package/dist/llms/runtime-config.d.ts +4 -0
  106. package/dist/llms/runtime-config.d.ts.map +1 -0
  107. package/dist/llms/runtime-registry.d.ts +20 -0
  108. package/dist/llms/runtime-registry.d.ts.map +1 -0
  109. package/dist/llms/runtime-types.d.ts +85 -0
  110. package/dist/llms/runtime-types.d.ts.map +1 -0
  111. package/dist/runtime/host.d.ts +1 -2
  112. package/dist/runtime/host.d.ts.map +1 -1
  113. package/dist/runtime/rules.d.ts +1 -0
  114. package/dist/runtime/rules.d.ts.map +1 -1
  115. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  116. package/dist/runtime/runtime-host.d.ts +22 -24
  117. package/dist/runtime/runtime-host.d.ts.map +1 -1
  118. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
  119. package/dist/runtime/session-runtime.d.ts +1 -19
  120. package/dist/runtime/session-runtime.d.ts.map +1 -1
  121. package/dist/services/global-settings.d.ts +12 -0
  122. package/dist/services/global-settings.d.ts.map +1 -0
  123. package/dist/services/local-runtime-bootstrap.d.ts +9 -3
  124. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  125. package/dist/services/plugin-tools.d.ts +16 -0
  126. package/dist/services/plugin-tools.d.ts.map +1 -0
  127. package/dist/services/providers/local-provider-registry.d.ts +4 -4
  128. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  129. package/dist/services/providers/local-provider-service.d.ts +13 -13
  130. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  131. package/dist/services/session-data.d.ts +1 -1
  132. package/dist/services/session-data.d.ts.map +1 -1
  133. package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
  134. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  135. package/dist/services/telemetry/index.js +28 -15
  136. package/dist/services/workspace-manifest.d.ts +11 -0
  137. package/dist/services/workspace-manifest.d.ts.map +1 -1
  138. package/dist/session/persistence-service.d.ts +11 -23
  139. package/dist/session/persistence-service.d.ts.map +1 -1
  140. package/dist/session/session-manifest-store.d.ts +22 -0
  141. package/dist/session/session-manifest-store.d.ts.map +1 -0
  142. package/dist/session/session-row.d.ts +93 -0
  143. package/dist/session/session-row.d.ts.map +1 -0
  144. package/dist/session/session-service.d.ts +2 -102
  145. package/dist/session/session-service.d.ts.map +1 -1
  146. package/dist/session/subagent-session-manager.d.ts +36 -0
  147. package/dist/session/subagent-session-manager.d.ts.map +1 -0
  148. package/dist/session/team-persistence-store.d.ts +24 -0
  149. package/dist/session/team-persistence-store.d.ts.map +1 -0
  150. package/dist/transports/hub.d.ts +47 -0
  151. package/dist/transports/hub.d.ts.map +1 -0
  152. package/dist/transports/local.d.ts +10 -6
  153. package/dist/transports/local.d.ts.map +1 -1
  154. package/dist/transports/remote.d.ts +10 -0
  155. package/dist/transports/remote.d.ts.map +1 -0
  156. package/dist/transports/runtime-host-support.d.ts +3 -2
  157. package/dist/transports/runtime-host-support.d.ts.map +1 -1
  158. package/dist/types/chat-schema.d.ts +10 -12
  159. package/dist/types/chat-schema.d.ts.map +1 -1
  160. package/dist/types/config.d.ts +8 -7
  161. package/dist/types/config.d.ts.map +1 -1
  162. package/dist/types/provider-settings.d.ts +4 -5
  163. package/dist/types/provider-settings.d.ts.map +1 -1
  164. package/dist/types/session.d.ts +2 -1
  165. package/dist/types/session.d.ts.map +1 -1
  166. package/dist/types.d.ts +8 -1
  167. package/dist/types.d.ts.map +1 -1
  168. package/package.json +20 -6
  169. package/src/ClineCore.ts +68 -40
  170. package/src/account/index.ts +3 -3
  171. package/src/account/rpc.ts +12 -12
  172. package/src/cron/index.ts +5 -0
  173. package/src/cron/resource-limiter.ts +46 -0
  174. package/src/cron/schedule-command-service.ts +193 -0
  175. package/src/cron/schedule-service.ts +703 -0
  176. package/src/cron/scheduler.ts +637 -0
  177. package/src/cron/sqlite-schedule-store.ts +708 -0
  178. package/src/extensions/config/agent-config-loader.ts +17 -7
  179. package/src/extensions/config/runtime-commands.ts +6 -0
  180. package/src/extensions/config/user-instruction-config-loader.ts +1 -0
  181. package/src/extensions/context/agentic-compaction.ts +3 -3
  182. package/src/extensions/context/basic-compaction.ts +2 -2
  183. package/src/extensions/context/compaction-shared.ts +5 -4
  184. package/src/extensions/context/compaction.ts +3 -3
  185. package/src/extensions/plugin/plugin-config-loader.ts +17 -2
  186. package/src/extensions/plugin/plugin-loader.ts +48 -4
  187. package/src/extensions/plugin/plugin-module-import.ts +0 -2
  188. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +93 -39
  189. package/src/extensions/plugin/plugin-sandbox.ts +47 -27
  190. package/src/extensions/plugin/plugin-targeting.ts +32 -0
  191. package/src/extensions/tools/definitions.ts +30 -49
  192. package/src/extensions/tools/executors/apply-patch.ts +69 -80
  193. package/src/extensions/tools/executors/search.ts +195 -3
  194. package/src/extensions/tools/index.ts +10 -0
  195. package/src/extensions/tools/presets.ts +31 -46
  196. package/src/extensions/tools/runtime.ts +261 -0
  197. package/src/extensions/tools/schemas.ts +4 -2
  198. package/src/extensions/tools/team/team-tools.ts +21 -0
  199. package/src/hooks/hook-file-hooks.ts +8 -2
  200. package/src/hooks/index.ts +0 -7
  201. package/src/hooks/subprocess-runner.ts +1 -1
  202. package/src/hooks/subprocess.ts +9 -0
  203. package/src/hub/browser-websocket.ts +137 -0
  204. package/src/hub/client.ts +574 -0
  205. package/src/hub/connect.ts +156 -0
  206. package/src/hub/daemon-entry.ts +87 -0
  207. package/src/hub/daemon.ts +181 -0
  208. package/src/hub/defaults.ts +43 -0
  209. package/src/hub/discovery.ts +247 -0
  210. package/src/hub/index.ts +14 -0
  211. package/src/hub/native-transport.ts +31 -0
  212. package/src/hub/runtime-handlers.ts +140 -0
  213. package/src/hub/server.ts +1888 -0
  214. package/src/hub/session-client.ts +460 -0
  215. package/src/hub/start-shared-server.ts +58 -0
  216. package/src/hub/transport.ts +14 -0
  217. package/src/hub/ui-client.ts +122 -0
  218. package/src/hub/workspace.ts +19 -0
  219. package/src/index.ts +124 -68
  220. package/src/llms/configured-provider-registry.ts +193 -0
  221. package/src/llms/provider-defaults.ts +637 -0
  222. package/src/llms/provider-settings.ts +263 -0
  223. package/src/llms/runtime-config.ts +43 -0
  224. package/src/llms/runtime-registry.ts +171 -0
  225. package/src/llms/runtime-types.ts +121 -0
  226. package/src/runtime/host.ts +107 -269
  227. package/src/runtime/index.ts +1 -0
  228. package/src/runtime/rules.ts +12 -0
  229. package/src/runtime/runtime-builder.ts +24 -8
  230. package/src/runtime/runtime-host.ts +89 -61
  231. package/src/runtime/runtime-oauth-token-manager.ts +11 -15
  232. package/src/runtime/session-runtime.ts +0 -24
  233. package/src/services/global-settings.ts +122 -0
  234. package/src/services/local-runtime-bootstrap.ts +51 -13
  235. package/src/services/plugin-tools.ts +85 -0
  236. package/src/services/providers/local-provider-registry.ts +6 -6
  237. package/src/services/providers/local-provider-service.ts +42 -37
  238. package/src/services/session-data.ts +15 -9
  239. package/src/services/storage/provider-settings-legacy-migration.ts +6 -4
  240. package/src/services/storage/provider-settings-manager.ts +1 -1
  241. package/src/services/workspace-manifest.ts +18 -0
  242. package/src/session/file-session-service.ts +1 -1
  243. package/src/session/index.ts +6 -27
  244. package/src/session/persistence-service.ts +119 -504
  245. package/src/session/session-manifest-store.ts +158 -0
  246. package/src/session/session-row.ts +199 -0
  247. package/src/session/session-service.ts +17 -376
  248. package/src/session/session-team-coordination.ts +1 -1
  249. package/src/session/subagent-session-manager.ts +397 -0
  250. package/src/session/team-persistence-store.ts +176 -0
  251. package/src/transports/hub.ts +656 -0
  252. package/src/transports/local.ts +135 -40
  253. package/src/transports/remote.ts +26 -0
  254. package/src/transports/runtime-host-support.ts +63 -9
  255. package/src/types/chat-schema.ts +4 -5
  256. package/src/types/config.ts +8 -7
  257. package/src/types/provider-settings.ts +11 -7
  258. package/src/types/session.ts +2 -4
  259. package/src/types.ts +27 -1
  260. package/dist/hooks/persistent.d.ts +0 -64
  261. package/dist/hooks/persistent.d.ts.map +0 -1
  262. package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
  263. package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
  264. package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
  265. package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
  266. package/dist/session/rpc-session-service.d.ts +0 -16
  267. package/dist/session/rpc-session-service.d.ts.map +0 -1
  268. package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
  269. package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
  270. package/dist/transports/rpc.d.ts +0 -51
  271. package/dist/transports/rpc.d.ts.map +0 -1
  272. package/src/ClineCore.test.ts +0 -226
  273. package/src/account/cline-account-service.test.ts +0 -185
  274. package/src/account/featurebase-token.test.ts +0 -175
  275. package/src/account/rpc.test.ts +0 -63
  276. package/src/auth/bounded-ttl-cache.test.ts +0 -38
  277. package/src/auth/client.test.ts +0 -69
  278. package/src/auth/cline.test.ts +0 -267
  279. package/src/auth/codex.test.ts +0 -170
  280. package/src/auth/oca.test.ts +0 -340
  281. package/src/auth/server.test.ts +0 -287
  282. package/src/auth/utils.test.ts +0 -128
  283. package/src/extensions/config/agent-config-loader.test.ts +0 -236
  284. package/src/extensions/config/hooks-config-loader.test.ts +0 -20
  285. package/src/extensions/config/runtime-commands.test.ts +0 -115
  286. package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
  287. package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
  288. package/src/extensions/context/compaction.test.ts +0 -483
  289. package/src/extensions/mcp/config-loader.test.ts +0 -238
  290. package/src/extensions/mcp/manager.test.ts +0 -105
  291. package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
  292. package/src/extensions/plugin/plugin-loader.test.ts +0 -292
  293. package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
  294. package/src/extensions/tools/definitions.test.ts +0 -780
  295. package/src/extensions/tools/executors/bash.test.ts +0 -87
  296. package/src/extensions/tools/executors/editor.test.ts +0 -35
  297. package/src/extensions/tools/executors/file-read.test.ts +0 -125
  298. package/src/extensions/tools/model-tool-routing.test.ts +0 -86
  299. package/src/extensions/tools/presets.test.ts +0 -70
  300. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
  301. package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
  302. package/src/extensions/tools/team/team-tools.test.ts +0 -918
  303. package/src/hooks/checkpoint-hooks.test.ts +0 -168
  304. package/src/hooks/hook-file-hooks.test.ts +0 -311
  305. package/src/hooks/persistent.ts +0 -661
  306. package/src/runtime/history.test.ts +0 -114
  307. package/src/runtime/host.test.ts +0 -230
  308. package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
  309. package/src/runtime/rpc-runtime-ensure.ts +0 -659
  310. package/src/runtime/rpc-spawn-lease.test.ts +0 -81
  311. package/src/runtime/rpc-spawn-lease.ts +0 -156
  312. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
  313. package/src/runtime/runtime-builder.test.ts +0 -615
  314. package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
  315. package/src/runtime/runtime-parity.test.ts +0 -143
  316. package/src/services/providers/local-provider-service.test.ts +0 -1062
  317. package/src/services/session-data.test.ts +0 -160
  318. package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
  319. package/src/services/storage/provider-settings-manager.test.ts +0 -191
  320. package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  321. package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
  322. package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
  323. package/src/services/telemetry/TelemetryService.test.ts +0 -134
  324. package/src/services/telemetry/distinct-id.test.ts +0 -57
  325. package/src/services/workspace/file-indexer.d.ts +0 -11
  326. package/src/services/workspace/file-indexer.test.ts +0 -156
  327. package/src/services/workspace/mention-enricher.test.ts +0 -106
  328. package/src/session/persistence-service.test.ts +0 -300
  329. package/src/session/rpc-session-service.ts +0 -114
  330. package/src/session/session-service.team-persistence.test.ts +0 -48
  331. package/src/session/sqlite-rpc-session-backend.ts +0 -301
  332. package/src/transports/local.e2e.test.ts +0 -380
  333. package/src/transports/local.test.ts +0 -2559
  334. package/src/transports/rpc.test.ts +0 -82
  335. package/src/transports/rpc.ts +0 -665
@@ -0,0 +1,460 @@
1
+ import type {
2
+ ChatRunTurnRequest,
3
+ ChatStartSessionRequest,
4
+ ChatStartSessionResponse,
5
+ ChatTurnResult,
6
+ HubEventEnvelope,
7
+ TeamProgressProjectionEvent,
8
+ } from "@clinebot/shared";
9
+ import { NodeHubClient } from "./client";
10
+
11
+ export interface HubSessionClientOptions {
12
+ address: string;
13
+ clientId?: string;
14
+ clientType?: string;
15
+ displayName?: string;
16
+ workspaceRoot?: string;
17
+ cwd?: string;
18
+ metadata?: Record<string, unknown>;
19
+ }
20
+
21
+ export interface HubSessionRow {
22
+ sessionId: string;
23
+ parentSessionId?: string;
24
+ metadata?: Record<string, unknown>;
25
+ messagesPath?: string;
26
+ }
27
+
28
+ export interface HubStreamEvent {
29
+ sessionId: string;
30
+ eventType: string;
31
+ payload: Record<string, unknown>;
32
+ }
33
+
34
+ export interface HubEventStreamHandlers {
35
+ onEvent?: (event: HubStreamEvent) => void;
36
+ onError?: (error: Error) => void;
37
+ }
38
+
39
+ export interface HubTeamProgressHandlers {
40
+ onProjection?: (event: TeamProgressProjectionEvent) => void;
41
+ onError?: (error: Error) => void;
42
+ }
43
+
44
+ function cloneRecord(
45
+ value: Record<string, unknown> | undefined,
46
+ ): Record<string, unknown> {
47
+ return value ? JSON.parse(JSON.stringify(value)) : {};
48
+ }
49
+
50
+ function extractSessionRow(
51
+ payload: Record<string, unknown> | undefined,
52
+ ): HubSessionRow | undefined {
53
+ const session =
54
+ payload?.session && typeof payload.session === "object"
55
+ ? (payload.session as Record<string, unknown>)
56
+ : undefined;
57
+ if (!session) {
58
+ return undefined;
59
+ }
60
+ const metadata =
61
+ session.metadata && typeof session.metadata === "object"
62
+ ? cloneRecord(session.metadata as Record<string, unknown>)
63
+ : undefined;
64
+ return {
65
+ sessionId: typeof session.sessionId === "string" ? session.sessionId : "",
66
+ parentSessionId:
67
+ typeof metadata?.parentSessionId === "string"
68
+ ? metadata.parentSessionId
69
+ : undefined,
70
+ messagesPath:
71
+ typeof metadata?.messagesPath === "string"
72
+ ? metadata.messagesPath
73
+ : undefined,
74
+ metadata,
75
+ };
76
+ }
77
+
78
+ function mapHubEvent(event: HubEventEnvelope): HubStreamEvent | undefined {
79
+ const sessionId = event.sessionId?.trim();
80
+ if (!sessionId) {
81
+ return undefined;
82
+ }
83
+ switch (event.event) {
84
+ case "assistant.delta":
85
+ return {
86
+ sessionId,
87
+ eventType: "runtime.chat.text_delta",
88
+ payload: cloneRecord(event.payload),
89
+ };
90
+ case "tool.started":
91
+ return {
92
+ sessionId,
93
+ eventType: "runtime.chat.tool_call_start",
94
+ payload: cloneRecord(event.payload),
95
+ };
96
+ case "tool.finished":
97
+ return {
98
+ sessionId,
99
+ eventType: "runtime.chat.tool_call_end",
100
+ payload: cloneRecord(event.payload),
101
+ };
102
+ case "approval.requested":
103
+ return {
104
+ sessionId,
105
+ eventType: "approval.requested",
106
+ payload: cloneRecord(event.payload),
107
+ };
108
+ case "run.aborted":
109
+ return {
110
+ sessionId,
111
+ eventType: "runtime.chat.aborted",
112
+ payload: cloneRecord(event.payload),
113
+ };
114
+ case "run.completed":
115
+ return {
116
+ sessionId,
117
+ eventType: "runtime.chat.completed",
118
+ payload: cloneRecord(event.payload),
119
+ };
120
+ default:
121
+ return undefined;
122
+ }
123
+ }
124
+
125
+ export class HubSessionClient {
126
+ private readonly client: NodeHubClient;
127
+ private metadataApplied = false;
128
+
129
+ constructor(private readonly options: HubSessionClientOptions) {
130
+ this.client = new NodeHubClient({
131
+ url: options.address,
132
+ clientId: options.clientId,
133
+ clientType: options.clientType ?? "hub-session-client",
134
+ displayName: options.displayName ?? "hub session client",
135
+ workspaceRoot: options.workspaceRoot,
136
+ cwd: options.cwd,
137
+ });
138
+ }
139
+
140
+ private async ensureMetadataApplied(): Promise<void> {
141
+ if (this.metadataApplied || !this.options.metadata) {
142
+ if (!this.options.metadata) {
143
+ await this.client.connect();
144
+ }
145
+ return;
146
+ }
147
+ await this.client.connect();
148
+ await this.client.command("client.update", {
149
+ metadata: this.options.metadata,
150
+ });
151
+ this.metadataApplied = true;
152
+ }
153
+
154
+ async connect(): Promise<void> {
155
+ await this.ensureMetadataApplied();
156
+ }
157
+
158
+ close(): void {
159
+ this.client.close();
160
+ }
161
+
162
+ async startRuntimeSession(
163
+ request: ChatStartSessionRequest,
164
+ ): Promise<ChatStartSessionResponse> {
165
+ await this.ensureMetadataApplied();
166
+ const reply = await this.client.command("session.create", {
167
+ workspaceRoot: request.workspaceRoot,
168
+ cwd: request.cwd,
169
+ sessionConfig: {
170
+ providerId: request.provider,
171
+ modelId: request.model,
172
+ apiKey: request.apiKey,
173
+ cwd: request.cwd ?? request.workspaceRoot,
174
+ workspaceRoot: request.workspaceRoot,
175
+ systemPrompt: request.systemPrompt ?? "",
176
+ mode: request.mode ?? "act",
177
+ rules: request.rules,
178
+ maxIterations: request.maxIterations,
179
+ enableTools: request.enableTools,
180
+ enableSpawnAgent: request.enableSpawn !== false,
181
+ enableAgentTeams: request.enableTeams !== false,
182
+ disableMcpSettingsTools: request.disableMcpSettingsTools,
183
+ missionLogIntervalSteps: request.missionStepInterval,
184
+ missionLogIntervalMs: request.missionTimeIntervalMs,
185
+ },
186
+ metadata: {
187
+ source: request.source ?? "cli",
188
+ provider: request.provider,
189
+ model: request.model,
190
+ enableTools: request.enableTools,
191
+ enableSpawn: request.enableSpawn,
192
+ enableTeams: request.enableTeams,
193
+ prompt: undefined,
194
+ interactive: request.interactive !== false,
195
+ },
196
+ runtimeOptions: {
197
+ mode: request.mode,
198
+ systemPrompt: request.systemPrompt,
199
+ maxIterations: request.maxIterations,
200
+ enableTools: request.enableTools,
201
+ enableSpawn: request.enableSpawn,
202
+ enableTeams: request.enableTeams,
203
+ autoApproveTools: request.autoApproveTools,
204
+ },
205
+ modelSelection: {
206
+ provider: request.provider,
207
+ model: request.model,
208
+ apiKey: request.apiKey,
209
+ },
210
+ toolPolicies: request.toolPolicies,
211
+ initialMessages: request.initialMessages,
212
+ });
213
+ const row = extractSessionRow(reply.payload);
214
+ if (!row?.sessionId) {
215
+ throw new Error("hub session create returned no session id");
216
+ }
217
+ return {
218
+ sessionId: row.sessionId,
219
+ startResult: {
220
+ sessionId: row.sessionId,
221
+ manifestPath: "",
222
+ messagesPath: row.messagesPath ?? "",
223
+ },
224
+ };
225
+ }
226
+
227
+ async sendRuntimeSession(
228
+ sessionId: string,
229
+ request: ChatRunTurnRequest,
230
+ ): Promise<{ result?: ChatTurnResult }> {
231
+ await this.ensureMetadataApplied();
232
+ const reply = await this.client.command(
233
+ "session.send_input",
234
+ {
235
+ prompt: request.prompt,
236
+ attachments: request.attachments,
237
+ delivery: request.delivery,
238
+ },
239
+ sessionId,
240
+ );
241
+ return {
242
+ result: reply.payload?.result as ChatTurnResult | undefined,
243
+ };
244
+ }
245
+
246
+ async stopRuntimeSession(sessionId: string): Promise<{ applied: boolean }> {
247
+ await this.ensureMetadataApplied();
248
+ await this.client.command("session.detach", { sessionId }, sessionId);
249
+ return { applied: true };
250
+ }
251
+
252
+ async abortRuntimeSession(sessionId: string): Promise<{ applied: boolean }> {
253
+ await this.ensureMetadataApplied();
254
+ await this.client.command("run.abort", { sessionId }, sessionId);
255
+ return { applied: true };
256
+ }
257
+
258
+ async updateSession(input: {
259
+ sessionId: string;
260
+ metadata?: Record<string, unknown>;
261
+ }): Promise<{ updated: boolean }> {
262
+ await this.ensureMetadataApplied();
263
+ await this.client.command(
264
+ "session.update",
265
+ {
266
+ sessionId: input.sessionId,
267
+ metadata: input.metadata,
268
+ },
269
+ input.sessionId,
270
+ );
271
+ return { updated: true };
272
+ }
273
+
274
+ async getSession(sessionId: string): Promise<HubSessionRow | undefined> {
275
+ await this.ensureMetadataApplied();
276
+ const reply = await this.client.command(
277
+ "session.get",
278
+ undefined,
279
+ sessionId,
280
+ );
281
+ return extractSessionRow(reply.payload);
282
+ }
283
+
284
+ async listSessions(input?: { limit?: number }): Promise<HubSessionRow[]> {
285
+ await this.ensureMetadataApplied();
286
+ const reply = await this.client.command("session.list", {
287
+ limit: input?.limit ?? 200,
288
+ });
289
+ const sessions = Array.isArray(reply.payload?.sessions)
290
+ ? (reply.payload?.sessions as Record<string, unknown>[])
291
+ : [];
292
+ return sessions
293
+ .map((session) => extractSessionRow({ session }))
294
+ .filter((row): row is HubSessionRow => Boolean(row?.sessionId));
295
+ }
296
+
297
+ async deleteSession(
298
+ sessionId: string,
299
+ deleteCheckpointRefs = true,
300
+ ): Promise<boolean> {
301
+ await this.ensureMetadataApplied();
302
+ const reply = await this.client.command("session.delete", {
303
+ sessionId,
304
+ deleteCheckpointRefs,
305
+ });
306
+ return reply.payload?.deleted === true;
307
+ }
308
+
309
+ async respondToolApproval(input: {
310
+ approvalId: string;
311
+ approved: boolean;
312
+ reason?: string;
313
+ responderClientId?: string;
314
+ }): Promise<void> {
315
+ await this.ensureMetadataApplied();
316
+ await this.client.command("approval.respond", {
317
+ approvalId: input.approvalId,
318
+ approved: input.approved,
319
+ payload: input.reason ? { reason: input.reason } : undefined,
320
+ responderClientId: input.responderClientId,
321
+ });
322
+ }
323
+
324
+ streamEvents(
325
+ input: { clientId?: string; sessionIds?: string[] },
326
+ handlers: HubEventStreamHandlers,
327
+ ): () => void {
328
+ const allowed = new Set(
329
+ (input.sessionIds ?? []).map((id) => id.trim()).filter(Boolean),
330
+ );
331
+ const unsubscribe = this.client.subscribe((event: HubEventEnvelope) => {
332
+ const mapped = mapHubEvent(event);
333
+ if (!mapped) {
334
+ return;
335
+ }
336
+ if (allowed.size > 0 && !allowed.has(mapped.sessionId)) {
337
+ return;
338
+ }
339
+ handlers.onEvent?.(mapped);
340
+ });
341
+ void this.ensureMetadataApplied().catch((error) => {
342
+ handlers.onError?.(
343
+ error instanceof Error ? error : new Error(String(error)),
344
+ );
345
+ });
346
+ return unsubscribe;
347
+ }
348
+
349
+ streamTeamProgress(
350
+ _input: { clientId?: string },
351
+ handlers: HubTeamProgressHandlers,
352
+ ): () => void {
353
+ const unsubscribe = this.client.subscribe((event: HubEventEnvelope) => {
354
+ if (event.event !== "team.progress" || !event.payload) {
355
+ return;
356
+ }
357
+ handlers.onProjection?.(
358
+ event.payload as unknown as TeamProgressProjectionEvent,
359
+ );
360
+ });
361
+ void this.ensureMetadataApplied().catch((error) => {
362
+ handlers.onError?.(
363
+ error instanceof Error ? error : new Error(String(error)),
364
+ );
365
+ });
366
+ return unsubscribe;
367
+ }
368
+
369
+ async createSchedule(input: Record<string, unknown>): Promise<any> {
370
+ await this.ensureMetadataApplied();
371
+ const reply = await this.client.command("schedule.create", input);
372
+ return reply.payload?.schedule;
373
+ }
374
+
375
+ async listSchedules(_input?: { limit?: number }): Promise<any[]> {
376
+ await this.ensureMetadataApplied();
377
+ const reply = await this.client.command("schedule.list");
378
+ return Array.isArray(reply.payload?.schedules)
379
+ ? (reply.payload?.schedules as any[])
380
+ : [];
381
+ }
382
+
383
+ async getSchedule(scheduleId: string): Promise<any | undefined> {
384
+ await this.ensureMetadataApplied();
385
+ const reply = await this.client.command("schedule.get", { scheduleId });
386
+ return reply.payload?.schedule;
387
+ }
388
+
389
+ async updateSchedule(
390
+ scheduleId: string,
391
+ input: Record<string, unknown>,
392
+ ): Promise<any> {
393
+ await this.ensureMetadataApplied();
394
+ const reply = await this.client.command("schedule.update", {
395
+ scheduleId,
396
+ ...input,
397
+ });
398
+ return reply.payload?.schedule;
399
+ }
400
+
401
+ async pauseSchedule(scheduleId: string): Promise<any> {
402
+ await this.ensureMetadataApplied();
403
+ const reply = await this.client.command("schedule.disable", { scheduleId });
404
+ return reply.payload?.schedule;
405
+ }
406
+
407
+ async resumeSchedule(scheduleId: string): Promise<any> {
408
+ await this.ensureMetadataApplied();
409
+ const reply = await this.client.command("schedule.enable", { scheduleId });
410
+ return reply.payload?.schedule;
411
+ }
412
+
413
+ async deleteSchedule(scheduleId: string): Promise<boolean> {
414
+ await this.ensureMetadataApplied();
415
+ const reply = await this.client.command("schedule.delete", { scheduleId });
416
+ return reply.payload?.deleted === true;
417
+ }
418
+
419
+ async triggerScheduleNow(scheduleId: string): Promise<any> {
420
+ await this.ensureMetadataApplied();
421
+ const reply = await this.client.command("schedule.trigger", { scheduleId });
422
+ return reply.payload?.execution;
423
+ }
424
+
425
+ async listScheduleExecutions(
426
+ scheduleId: string,
427
+ limit?: number,
428
+ ): Promise<any[]> {
429
+ await this.ensureMetadataApplied();
430
+ const reply = await this.client.command("schedule.list_executions", {
431
+ scheduleId,
432
+ limit,
433
+ });
434
+ return Array.isArray(reply.payload?.executions)
435
+ ? (reply.payload?.executions as any[])
436
+ : [];
437
+ }
438
+
439
+ async getScheduleStats(): Promise<any> {
440
+ await this.ensureMetadataApplied();
441
+ const reply = await this.client.command("schedule.stats");
442
+ return reply.payload?.stats;
443
+ }
444
+
445
+ async getActiveScheduledExecutions(): Promise<any[]> {
446
+ await this.ensureMetadataApplied();
447
+ const reply = await this.client.command("schedule.active");
448
+ return Array.isArray(reply.payload?.executions)
449
+ ? (reply.payload?.executions as any[])
450
+ : [];
451
+ }
452
+
453
+ async getUpcomingScheduledRuns(limit?: number): Promise<any[]> {
454
+ await this.ensureMetadataApplied();
455
+ const reply = await this.client.command("schedule.upcoming", { limit });
456
+ return Array.isArray(reply.payload?.upcoming)
457
+ ? (reply.payload?.upcoming as any[])
458
+ : [];
459
+ }
460
+ }
@@ -0,0 +1,58 @@
1
+ import { resolveHubEndpointOptions } from "./defaults";
2
+ import {
3
+ type EnsuredHubWebSocketServerResult,
4
+ type EnsureHubWebSocketServerOptions,
5
+ ensureHubWebSocketServer,
6
+ type HubWebSocketServer,
7
+ type HubWebSocketServerOptions,
8
+ startHubWebSocketServer,
9
+ } from "./server";
10
+ import { resolveSharedHubOwnerContext } from "./workspace";
11
+
12
+ export type HubServer = HubWebSocketServer;
13
+ export type EnsureHubServerResult = EnsuredHubWebSocketServerResult;
14
+
15
+ export interface StartHubServerOptions
16
+ extends Omit<HubWebSocketServerOptions, "owner"> {}
17
+
18
+ export interface EnsureHubServerOptions
19
+ extends Omit<EnsureHubWebSocketServerOptions, "owner"> {}
20
+
21
+ /**
22
+ * Start a hub WebSocket server bound to the process-local shared owner
23
+ * context. Callers that need a custom owner should invoke
24
+ * {@link startHubWebSocketServer} directly.
25
+ */
26
+ export async function startHubServer(
27
+ options: StartHubServerOptions,
28
+ ): Promise<HubServer> {
29
+ const endpoint = resolveHubEndpointOptions({
30
+ host: options.host,
31
+ port: options.port,
32
+ pathname: options.pathname,
33
+ });
34
+ return await startHubWebSocketServer({
35
+ ...options,
36
+ ...endpoint,
37
+ owner: resolveSharedHubOwnerContext(),
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Ensure a hub WebSocket server is running in the process-local shared owner
43
+ * context, reusing a compatible in-process instance when available.
44
+ */
45
+ export async function ensureHubServer(
46
+ options: EnsureHubServerOptions,
47
+ ): Promise<EnsureHubServerResult> {
48
+ const endpoint = resolveHubEndpointOptions({
49
+ host: options.host,
50
+ port: options.port,
51
+ pathname: options.pathname,
52
+ });
53
+ return await ensureHubWebSocketServer({
54
+ ...options,
55
+ ...endpoint,
56
+ owner: resolveSharedHubOwnerContext(),
57
+ });
58
+ }
@@ -0,0 +1,14 @@
1
+ import type {
2
+ HubCommandEnvelope,
3
+ HubEventEnvelope,
4
+ HubReplyEnvelope,
5
+ } from "@clinebot/shared";
6
+
7
+ export interface HubCommandTransport {
8
+ command(envelope: HubCommandEnvelope): Promise<HubReplyEnvelope>;
9
+ subscribe(
10
+ clientId: string,
11
+ listener: (event: HubEventEnvelope) => void,
12
+ options?: { sessionId?: string },
13
+ ): Promise<() => void> | (() => void);
14
+ }
@@ -0,0 +1,122 @@
1
+ import type {
2
+ HubClientRecord,
3
+ HubEventEnvelope,
4
+ HubUINotifyPayload,
5
+ HubUIShowWindowPayload,
6
+ SessionRecord,
7
+ } from "@clinebot/shared";
8
+ import { NodeHubClient } from "./client";
9
+
10
+ export interface HubUIClientOptions {
11
+ address: string;
12
+ clientId?: string;
13
+ clientType?: string;
14
+ displayName?: string;
15
+ }
16
+
17
+ /**
18
+ * A lightweight hub client for UI/notification concerns.
19
+ * Used by the menu bar app and other UI clients to send/receive
20
+ * UI events (notifications, show window, client tracking).
21
+ */
22
+ export class HubUIClient {
23
+ private readonly client: NodeHubClient;
24
+
25
+ constructor(options: HubUIClientOptions) {
26
+ this.client = new NodeHubClient({
27
+ url: options.address,
28
+ clientId: options.clientId,
29
+ clientType: options.clientType ?? "hub-ui-client",
30
+ displayName: options.displayName ?? "hub ui client",
31
+ });
32
+ }
33
+
34
+ async connect(): Promise<void> {
35
+ await this.client.connect();
36
+ }
37
+
38
+ close(): void {
39
+ this.client.close();
40
+ }
41
+
42
+ getClientId(): string {
43
+ return this.client.getClientId();
44
+ }
45
+
46
+ /**
47
+ * Send a notification request to the hub.
48
+ * The hub will broadcast a "ui.notify" event to all subscribers (e.g. the menu bar app).
49
+ */
50
+ async sendNotify(payload: HubUINotifyPayload): Promise<void> {
51
+ await this.client.command(
52
+ "ui.notify",
53
+ payload as unknown as Record<string, unknown>,
54
+ );
55
+ }
56
+
57
+ /**
58
+ * Request the hub to broadcast a "ui.show_window" event to all subscribers.
59
+ */
60
+ async sendShowWindow(payload?: HubUIShowWindowPayload): Promise<void> {
61
+ await this.client.command(
62
+ "ui.show_window",
63
+ (payload ?? {}) as Record<string, unknown>,
64
+ );
65
+ }
66
+
67
+ async listClients(): Promise<HubClientRecord[]> {
68
+ const reply = await this.client.command("client.list");
69
+ return Array.isArray(reply.payload?.clients)
70
+ ? (reply.payload.clients as HubClientRecord[])
71
+ : [];
72
+ }
73
+
74
+ async listSessions(limit = 200): Promise<SessionRecord[]> {
75
+ const reply = await this.client.command("session.list", { limit });
76
+ return Array.isArray(reply.payload?.sessions)
77
+ ? (reply.payload.sessions as SessionRecord[])
78
+ : [];
79
+ }
80
+
81
+ /**
82
+ * Subscribe to UI-relevant hub events.
83
+ * Returns an unsubscribe function.
84
+ */
85
+ subscribeUI(handlers: {
86
+ onNotify?: (payload: HubUINotifyPayload) => void;
87
+ onShowWindow?: (payload: HubUIShowWindowPayload) => void;
88
+ onClientRegistered?: (payload: Record<string, unknown>) => void;
89
+ onClientDisconnected?: (payload: Record<string, unknown>) => void;
90
+ onSessionCreated?: (payload: Record<string, unknown>) => void;
91
+ onSessionUpdated?: (payload: Record<string, unknown>) => void;
92
+ onSessionDetached?: (payload: Record<string, unknown>) => void;
93
+ }): () => void {
94
+ return this.client.subscribe((event: HubEventEnvelope) => {
95
+ switch (event.event) {
96
+ case "ui.notify":
97
+ handlers.onNotify?.(event.payload as unknown as HubUINotifyPayload);
98
+ break;
99
+ case "ui.show_window":
100
+ handlers.onShowWindow?.(
101
+ event.payload as unknown as HubUIShowWindowPayload,
102
+ );
103
+ break;
104
+ case "hub.client.registered":
105
+ handlers.onClientRegistered?.(event.payload ?? {});
106
+ break;
107
+ case "hub.client.disconnected":
108
+ handlers.onClientDisconnected?.(event.payload ?? {});
109
+ break;
110
+ case "session.created":
111
+ handlers.onSessionCreated?.(event.payload ?? {});
112
+ break;
113
+ case "session.updated":
114
+ handlers.onSessionUpdated?.(event.payload ?? {});
115
+ break;
116
+ case "session.detached":
117
+ handlers.onSessionDetached?.(event.payload ?? {});
118
+ break;
119
+ }
120
+ });
121
+ }
122
+ }
@@ -0,0 +1,19 @@
1
+ import { normalizeWorkspacePath } from "../services/workspace-manifest";
2
+ import { type HubOwnerContext, resolveHubOwnerContext } from "./discovery";
3
+
4
+ const DEFAULT_SHARED_HUB_OWNER_LABEL = "shared:cline";
5
+
6
+ export function resolveWorkspaceHubOwnerContext(
7
+ workspaceRoot: string,
8
+ ): HubOwnerContext {
9
+ const normalized = normalizeWorkspacePath(workspaceRoot.trim());
10
+ return resolveHubOwnerContext(
11
+ `workspace:${normalized || workspaceRoot.trim()}`,
12
+ );
13
+ }
14
+
15
+ export function resolveSharedHubOwnerContext(
16
+ label = DEFAULT_SHARED_HUB_OWNER_LABEL,
17
+ ): HubOwnerContext {
18
+ return resolveHubOwnerContext(label);
19
+ }