@clinebot/core 0.0.35 → 0.0.37

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 (441) hide show
  1. package/README.md +1 -2
  2. package/dist/ClineCore.d.ts +362 -39
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts.map +1 -1
  5. package/dist/account/index.d.ts +1 -1
  6. package/dist/account/index.d.ts.map +1 -1
  7. package/dist/account/rpc.d.ts +6 -6
  8. package/dist/account/rpc.d.ts.map +1 -1
  9. package/dist/cron/cron-event-ingress.d.ts +38 -0
  10. package/dist/cron/cron-event-ingress.d.ts.map +1 -0
  11. package/dist/cron/cron-materializer.d.ts +36 -0
  12. package/dist/cron/cron-materializer.d.ts.map +1 -0
  13. package/dist/cron/cron-reconciler.d.ts +62 -0
  14. package/dist/cron/cron-reconciler.d.ts.map +1 -0
  15. package/dist/cron/cron-report-writer.d.ts +41 -0
  16. package/dist/cron/cron-report-writer.d.ts.map +1 -0
  17. package/dist/cron/cron-runner.d.ts +43 -0
  18. package/dist/cron/cron-runner.d.ts.map +1 -0
  19. package/dist/cron/cron-schema.d.ts +3 -0
  20. package/dist/cron/cron-schema.d.ts.map +1 -0
  21. package/dist/cron/cron-service.d.ts +57 -0
  22. package/dist/cron/cron-service.d.ts.map +1 -0
  23. package/dist/cron/cron-spec-parser.d.ts +27 -0
  24. package/dist/cron/cron-spec-parser.d.ts.map +1 -0
  25. package/dist/cron/cron-watcher.d.ts +23 -0
  26. package/dist/cron/cron-watcher.d.ts.map +1 -0
  27. package/dist/cron/resource-limiter.d.ts +9 -0
  28. package/dist/cron/resource-limiter.d.ts.map +1 -0
  29. package/dist/cron/schedule-command-service.d.ts +10 -0
  30. package/dist/cron/schedule-command-service.d.ts.map +1 -0
  31. package/dist/cron/schedule-service.d.ts +100 -0
  32. package/dist/cron/schedule-service.d.ts.map +1 -0
  33. package/dist/cron/scheduler.d.ts +68 -0
  34. package/dist/cron/scheduler.d.ts.map +1 -0
  35. package/dist/cron/sqlite-cron-store.d.ts +230 -0
  36. package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
  37. package/dist/cron/sqlite-schedule-store.d.ts +52 -0
  38. package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
  39. package/dist/extensions/config/agent-config-loader.d.ts +4 -3
  40. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  41. package/dist/extensions/config/runtime-commands.d.ts +1 -0
  42. package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
  43. package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
  44. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  45. package/dist/extensions/context/agentic-compaction.d.ts +2 -2
  46. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
  47. package/dist/extensions/context/compaction-shared.d.ts +5 -4
  48. package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
  49. package/dist/extensions/context/compaction.d.ts.map +1 -1
  50. package/dist/extensions/plugin/plugin-config-loader.d.ts +15 -2
  51. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  52. package/dist/extensions/plugin/plugin-loader.d.ts +13 -7
  53. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  54. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
  55. package/dist/extensions/plugin/plugin-sandbox.d.ts +21 -2
  56. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  57. package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
  58. package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
  59. package/dist/extensions/plugin-sandbox-bootstrap.js +237 -276
  60. package/dist/extensions/tools/constants.d.ts +1 -0
  61. package/dist/extensions/tools/constants.d.ts.map +1 -1
  62. package/dist/extensions/tools/definitions.d.ts +3 -4
  63. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  64. package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
  65. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
  66. package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
  67. package/dist/extensions/tools/executors/search.d.ts +1 -1
  68. package/dist/extensions/tools/executors/search.d.ts.map +1 -1
  69. package/dist/extensions/tools/helpers.d.ts +1 -0
  70. package/dist/extensions/tools/helpers.d.ts.map +1 -1
  71. package/dist/extensions/tools/index.d.ts +3 -2
  72. package/dist/extensions/tools/index.d.ts.map +1 -1
  73. package/dist/extensions/tools/presets.d.ts +27 -44
  74. package/dist/extensions/tools/presets.d.ts.map +1 -1
  75. package/dist/extensions/tools/runtime.d.ts +25 -0
  76. package/dist/extensions/tools/runtime.d.ts.map +1 -0
  77. package/dist/extensions/tools/schemas.d.ts +25 -3
  78. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  79. package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
  80. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
  81. package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
  82. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
  83. package/dist/extensions/tools/team/team-tools.d.ts +1 -0
  84. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  85. package/dist/extensions/tools/types.d.ts +0 -5
  86. package/dist/extensions/tools/types.d.ts.map +1 -1
  87. package/dist/hooks/hook-bridge.d.ts +118 -0
  88. package/dist/hooks/hook-bridge.d.ts.map +1 -0
  89. package/dist/hooks/hook-file-hooks.d.ts +6 -2
  90. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  91. package/dist/hooks/hook-registry.d.ts +16 -0
  92. package/dist/hooks/hook-registry.d.ts.map +1 -0
  93. package/dist/hooks/index.d.ts +0 -1
  94. package/dist/hooks/index.d.ts.map +1 -1
  95. package/dist/hooks/subprocess.d.ts +8 -1
  96. package/dist/hooks/subprocess.d.ts.map +1 -1
  97. package/dist/hub/browser-websocket.d.ts +18 -0
  98. package/dist/hub/browser-websocket.d.ts.map +1 -0
  99. package/dist/hub/client.d.ts +51 -0
  100. package/dist/hub/client.d.ts.map +1 -0
  101. package/dist/hub/connect.d.ts +15 -0
  102. package/dist/hub/connect.d.ts.map +1 -0
  103. package/dist/hub/daemon-entry.d.ts +2 -0
  104. package/dist/hub/daemon-entry.d.ts.map +1 -0
  105. package/dist/hub/daemon-entry.js +1305 -0
  106. package/dist/hub/daemon.d.ts +5 -0
  107. package/dist/hub/daemon.d.ts.map +1 -0
  108. package/dist/hub/defaults.d.ts +17 -0
  109. package/dist/hub/defaults.d.ts.map +1 -0
  110. package/dist/hub/discovery.d.ts +29 -0
  111. package/dist/hub/discovery.d.ts.map +1 -0
  112. package/dist/hub/index.d.ts +15 -0
  113. package/dist/hub/index.d.ts.map +1 -0
  114. package/dist/hub/index.js +1294 -0
  115. package/dist/hub/native-transport.d.ts +17 -0
  116. package/dist/hub/native-transport.d.ts.map +1 -0
  117. package/dist/hub/runtime-handlers.d.ts +11 -0
  118. package/dist/hub/runtime-handlers.d.ts.map +1 -0
  119. package/dist/hub/server.d.ts +104 -0
  120. package/dist/hub/server.d.ts.map +1 -0
  121. package/dist/hub/session-client.d.ts +90 -0
  122. package/dist/hub/session-client.d.ts.map +1 -0
  123. package/dist/hub/start-shared-server.d.ts +19 -0
  124. package/dist/hub/start-shared-server.d.ts.map +1 -0
  125. package/dist/hub/transport.d.ts +8 -0
  126. package/dist/hub/transport.d.ts.map +1 -0
  127. package/dist/hub/ui-client.d.ts +45 -0
  128. package/dist/hub/ui-client.d.ts.map +1 -0
  129. package/dist/hub/workspace.d.ts +4 -0
  130. package/dist/hub/workspace.d.ts.map +1 -0
  131. package/dist/index.d.ts +29 -16
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +782 -471
  134. package/dist/llms/cline-recommended-models.d.ts +20 -0
  135. package/dist/llms/cline-recommended-models.d.ts.map +1 -0
  136. package/dist/llms/configured-provider-registry.d.ts +28 -0
  137. package/dist/llms/configured-provider-registry.d.ts.map +1 -0
  138. package/dist/llms/handler-factory.d.ts +16 -0
  139. package/dist/llms/handler-factory.d.ts.map +1 -0
  140. package/dist/llms/provider-defaults.d.ts +27 -0
  141. package/dist/llms/provider-defaults.d.ts.map +1 -0
  142. package/dist/llms/provider-settings.d.ts +245 -0
  143. package/dist/llms/provider-settings.d.ts.map +1 -0
  144. package/dist/llms/runtime-config.d.ts +4 -0
  145. package/dist/llms/runtime-config.d.ts.map +1 -0
  146. package/dist/llms/runtime-registry.d.ts +20 -0
  147. package/dist/llms/runtime-registry.d.ts.map +1 -0
  148. package/dist/llms/runtime-types.d.ts +85 -0
  149. package/dist/llms/runtime-types.d.ts.map +1 -0
  150. package/dist/runtime/agent-config-adapter.d.ts +148 -0
  151. package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
  152. package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
  153. package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
  154. package/dist/runtime/history.d.ts +6 -0
  155. package/dist/runtime/history.d.ts.map +1 -1
  156. package/dist/runtime/host.d.ts +1 -2
  157. package/dist/runtime/host.d.ts.map +1 -1
  158. package/dist/runtime/loop-detection.d.ts +59 -0
  159. package/dist/runtime/loop-detection.d.ts.map +1 -0
  160. package/dist/runtime/mistake-tracker.d.ts +69 -0
  161. package/dist/runtime/mistake-tracker.d.ts.map +1 -0
  162. package/dist/runtime/rules.d.ts +1 -0
  163. package/dist/runtime/rules.d.ts.map +1 -1
  164. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  165. package/dist/runtime/runtime-event-adapter.d.ts +102 -0
  166. package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
  167. package/dist/runtime/runtime-host.d.ts +49 -26
  168. package/dist/runtime/runtime-host.d.ts.map +1 -1
  169. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
  170. package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
  171. package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
  172. package/dist/runtime/session-runtime.d.ts +16 -21
  173. package/dist/runtime/session-runtime.d.ts.map +1 -1
  174. package/dist/runtime/user-input-builder.d.ts +24 -0
  175. package/dist/runtime/user-input-builder.d.ts.map +1 -0
  176. package/dist/services/global-settings.d.ts +12 -0
  177. package/dist/services/global-settings.d.ts.map +1 -0
  178. package/dist/services/index.js +28 -0
  179. package/dist/services/local-runtime-bootstrap.d.ts +9 -3
  180. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  181. package/dist/services/plugin-tools.d.ts +16 -0
  182. package/dist/services/plugin-tools.d.ts.map +1 -0
  183. package/dist/services/providers/local-provider-registry.d.ts +199 -23
  184. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  185. package/dist/services/providers/local-provider-service.d.ts +15 -13
  186. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  187. package/dist/services/session-data.d.ts +1 -1
  188. package/dist/services/session-data.d.ts.map +1 -1
  189. package/dist/services/session-telemetry.d.ts +7 -2
  190. package/dist/services/session-telemetry.d.ts.map +1 -1
  191. package/dist/services/storage/file-team-store.d.ts.map +1 -1
  192. package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
  193. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  194. package/dist/services/storage/provider-settings-manager.d.ts +1 -0
  195. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
  196. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
  197. package/dist/services/workspace-manifest.d.ts +11 -0
  198. package/dist/services/workspace-manifest.d.ts.map +1 -1
  199. package/dist/session/conversation-store.d.ts +30 -0
  200. package/dist/session/conversation-store.d.ts.map +1 -0
  201. package/dist/session/message-builder.d.ts +65 -0
  202. package/dist/session/message-builder.d.ts.map +1 -0
  203. package/dist/session/persistence-service.d.ts +11 -23
  204. package/dist/session/persistence-service.d.ts.map +1 -1
  205. package/dist/session/session-manifest-store.d.ts +22 -0
  206. package/dist/session/session-manifest-store.d.ts.map +1 -0
  207. package/dist/session/session-manifest.d.ts +1 -1
  208. package/dist/session/session-row.d.ts +93 -0
  209. package/dist/session/session-row.d.ts.map +1 -0
  210. package/dist/session/session-service.d.ts +2 -102
  211. package/dist/session/session-service.d.ts.map +1 -1
  212. package/dist/session/subagent-session-manager.d.ts +36 -0
  213. package/dist/session/subagent-session-manager.d.ts.map +1 -0
  214. package/dist/session/team-persistence-store.d.ts +24 -0
  215. package/dist/session/team-persistence-store.d.ts.map +1 -0
  216. package/dist/transports/hub.d.ts +58 -0
  217. package/dist/transports/hub.d.ts.map +1 -0
  218. package/dist/transports/local.d.ts +23 -9
  219. package/dist/transports/local.d.ts.map +1 -1
  220. package/dist/transports/remote.d.ts +10 -0
  221. package/dist/transports/remote.d.ts.map +1 -0
  222. package/dist/transports/runtime-host-support.d.ts +3 -2
  223. package/dist/transports/runtime-host-support.d.ts.map +1 -1
  224. package/dist/types/chat-schema.d.ts +15 -17
  225. package/dist/types/chat-schema.d.ts.map +1 -1
  226. package/dist/types/config.d.ts +17 -7
  227. package/dist/types/config.d.ts.map +1 -1
  228. package/dist/types/events.d.ts +7 -6
  229. package/dist/types/events.d.ts.map +1 -1
  230. package/dist/types/provider-settings.d.ts +4 -5
  231. package/dist/types/provider-settings.d.ts.map +1 -1
  232. package/dist/types/session.d.ts +7 -3
  233. package/dist/types/session.d.ts.map +1 -1
  234. package/dist/types.d.ts +11 -4
  235. package/dist/types.d.ts.map +1 -1
  236. package/package.json +20 -6
  237. package/src/ClineCore.ts +757 -44
  238. package/src/account/cline-account-service.ts +44 -6
  239. package/src/account/index.ts +3 -3
  240. package/src/account/rpc.ts +12 -12
  241. package/src/cron/cron-event-ingress.ts +357 -0
  242. package/src/cron/cron-materializer.ts +97 -0
  243. package/src/cron/cron-reconciler.ts +241 -0
  244. package/src/cron/cron-report-writer.ts +153 -0
  245. package/src/cron/cron-runner.ts +495 -0
  246. package/src/cron/cron-schema.ts +127 -0
  247. package/src/cron/cron-service.ts +163 -0
  248. package/src/cron/cron-spec-parser.ts +489 -0
  249. package/src/cron/cron-watcher.ts +102 -0
  250. package/src/cron/index.ts +15 -0
  251. package/src/cron/resource-limiter.ts +46 -0
  252. package/src/cron/schedule-command-service.ts +193 -0
  253. package/src/cron/schedule-service.ts +703 -0
  254. package/src/cron/scheduler.ts +772 -0
  255. package/src/cron/sqlite-cron-store.ts +1286 -0
  256. package/src/cron/sqlite-schedule-store.ts +708 -0
  257. package/src/extensions/config/agent-config-loader.ts +17 -7
  258. package/src/extensions/config/runtime-commands.ts +6 -0
  259. package/src/extensions/config/user-instruction-config-loader.ts +1 -0
  260. package/src/extensions/context/agentic-compaction.ts +3 -3
  261. package/src/extensions/context/basic-compaction.ts +2 -2
  262. package/src/extensions/context/compaction-shared.ts +5 -4
  263. package/src/extensions/context/compaction.ts +3 -3
  264. package/src/extensions/plugin/plugin-config-loader.ts +37 -2
  265. package/src/extensions/plugin/plugin-loader.ts +69 -9
  266. package/src/extensions/plugin/plugin-module-import.ts +0 -2
  267. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +243 -39
  268. package/src/extensions/plugin/plugin-sandbox.ts +173 -29
  269. package/src/extensions/plugin/plugin-targeting.ts +32 -0
  270. package/src/extensions/tools/constants.ts +2 -0
  271. package/src/extensions/tools/definitions.ts +61 -71
  272. package/src/extensions/tools/executors/apply-patch.ts +69 -80
  273. package/src/extensions/tools/executors/editor.ts +4 -3
  274. package/src/extensions/tools/executors/search.ts +195 -3
  275. package/src/extensions/tools/helpers.ts +24 -0
  276. package/src/extensions/tools/index.ts +11 -2
  277. package/src/extensions/tools/presets.ts +32 -47
  278. package/src/extensions/tools/runtime.ts +261 -0
  279. package/src/extensions/tools/schemas.ts +17 -20
  280. package/src/extensions/tools/team/delegated-agent.ts +8 -3
  281. package/src/extensions/tools/team/multi-agent.ts +135 -19
  282. package/src/extensions/tools/team/team-tools.ts +172 -91
  283. package/src/extensions/tools/types.ts +0 -6
  284. package/src/hooks/hook-bridge.ts +489 -0
  285. package/src/hooks/hook-file-hooks.ts +66 -5
  286. package/src/hooks/hook-registry.ts +257 -0
  287. package/src/hooks/index.ts +0 -7
  288. package/src/hooks/subprocess-runner.ts +1 -1
  289. package/src/hooks/subprocess.ts +9 -0
  290. package/src/hub/browser-websocket.ts +159 -0
  291. package/src/hub/client.ts +633 -0
  292. package/src/hub/connect.ts +156 -0
  293. package/src/hub/daemon-entry.ts +122 -0
  294. package/src/hub/daemon.ts +284 -0
  295. package/src/hub/defaults.ts +70 -0
  296. package/src/hub/discovery.ts +247 -0
  297. package/src/hub/index.ts +14 -0
  298. package/src/hub/native-transport.ts +31 -0
  299. package/src/hub/runtime-handlers.ts +141 -0
  300. package/src/hub/server.ts +2317 -0
  301. package/src/hub/session-client.ts +502 -0
  302. package/src/hub/start-shared-server.ts +61 -0
  303. package/src/hub/transport.ts +14 -0
  304. package/src/hub/ui-client.ts +126 -0
  305. package/src/hub/workspace.ts +19 -0
  306. package/src/index.ts +169 -68
  307. package/src/llms/cline-recommended-models.ts +167 -0
  308. package/src/llms/configured-provider-registry.ts +193 -0
  309. package/src/llms/handler-factory.ts +56 -0
  310. package/src/llms/provider-defaults.ts +653 -0
  311. package/src/llms/provider-settings.ts +310 -0
  312. package/src/llms/runtime-config.ts +43 -0
  313. package/src/llms/runtime-registry.ts +172 -0
  314. package/src/llms/runtime-types.ts +121 -0
  315. package/src/runtime/agent-config-adapter.ts +636 -0
  316. package/src/runtime/agent-runtime-config-builder.ts +205 -0
  317. package/src/runtime/error-feedback.ts +142 -0
  318. package/src/runtime/history.ts +137 -0
  319. package/src/runtime/host.ts +127 -267
  320. package/src/runtime/index.ts +1 -0
  321. package/src/runtime/loop-detection.ts +162 -0
  322. package/src/runtime/mistake-tracker.ts +221 -0
  323. package/src/runtime/rules.ts +12 -0
  324. package/src/runtime/runtime-builder.ts +85 -13
  325. package/src/runtime/runtime-event-adapter.ts +412 -0
  326. package/src/runtime/runtime-host.ts +134 -62
  327. package/src/runtime/runtime-oauth-token-manager.ts +11 -15
  328. package/src/runtime/session-runtime-orchestrator.ts +1253 -0
  329. package/src/runtime/session-runtime.ts +16 -26
  330. package/src/runtime/user-input-builder.ts +167 -0
  331. package/src/services/global-settings.ts +122 -0
  332. package/src/services/local-runtime-bootstrap.ts +175 -31
  333. package/src/services/plugin-tools.ts +86 -0
  334. package/src/services/providers/local-provider-registry.ts +277 -61
  335. package/src/services/providers/local-provider-service.ts +109 -44
  336. package/src/services/session-data.ts +18 -10
  337. package/src/services/session-telemetry.ts +6 -15
  338. package/src/services/storage/file-team-store.ts +1 -5
  339. package/src/services/storage/provider-settings-legacy-migration.ts +14 -51
  340. package/src/services/storage/provider-settings-manager.ts +17 -2
  341. package/src/services/storage/sqlite-team-store.ts +1 -5
  342. package/src/services/workspace-manifest.ts +18 -0
  343. package/src/session/conversation-store.ts +77 -0
  344. package/src/session/file-session-service.ts +1 -1
  345. package/src/session/index.ts +6 -27
  346. package/src/session/message-builder.ts +941 -0
  347. package/src/session/persistence-service.ts +119 -504
  348. package/src/session/session-manifest-store.ts +158 -0
  349. package/src/session/session-row.ts +199 -0
  350. package/src/session/session-service.ts +17 -376
  351. package/src/session/session-team-coordination.ts +1 -1
  352. package/src/session/subagent-session-manager.ts +397 -0
  353. package/src/session/team-persistence-store.ts +176 -0
  354. package/src/transports/hub.ts +1081 -0
  355. package/src/transports/local.ts +419 -93
  356. package/src/transports/remote.ts +27 -0
  357. package/src/transports/runtime-host-support.ts +63 -9
  358. package/src/types/chat-schema.ts +4 -5
  359. package/src/types/config.ts +17 -7
  360. package/src/types/events.ts +8 -6
  361. package/src/types/index.ts +3 -0
  362. package/src/types/provider-settings.ts +18 -7
  363. package/src/types/session.ts +7 -6
  364. package/src/types.ts +42 -2
  365. package/dist/hooks/persistent.d.ts +0 -64
  366. package/dist/hooks/persistent.d.ts.map +0 -1
  367. package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
  368. package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
  369. package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
  370. package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
  371. package/dist/services/telemetry/index.js +0 -15
  372. package/dist/session/rpc-session-service.d.ts +0 -16
  373. package/dist/session/rpc-session-service.d.ts.map +0 -1
  374. package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
  375. package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
  376. package/dist/transports/rpc.d.ts +0 -51
  377. package/dist/transports/rpc.d.ts.map +0 -1
  378. package/src/ClineCore.test.ts +0 -226
  379. package/src/account/cline-account-service.test.ts +0 -185
  380. package/src/account/featurebase-token.test.ts +0 -175
  381. package/src/account/rpc.test.ts +0 -63
  382. package/src/auth/bounded-ttl-cache.test.ts +0 -38
  383. package/src/auth/client.test.ts +0 -69
  384. package/src/auth/cline.test.ts +0 -267
  385. package/src/auth/codex.test.ts +0 -170
  386. package/src/auth/oca.test.ts +0 -340
  387. package/src/auth/server.test.ts +0 -287
  388. package/src/auth/utils.test.ts +0 -128
  389. package/src/extensions/config/agent-config-loader.test.ts +0 -236
  390. package/src/extensions/config/hooks-config-loader.test.ts +0 -20
  391. package/src/extensions/config/runtime-commands.test.ts +0 -115
  392. package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
  393. package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
  394. package/src/extensions/context/compaction.test.ts +0 -483
  395. package/src/extensions/mcp/config-loader.test.ts +0 -238
  396. package/src/extensions/mcp/manager.test.ts +0 -105
  397. package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
  398. package/src/extensions/plugin/plugin-loader.test.ts +0 -292
  399. package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
  400. package/src/extensions/tools/definitions.test.ts +0 -780
  401. package/src/extensions/tools/executors/bash.test.ts +0 -87
  402. package/src/extensions/tools/executors/editor.test.ts +0 -35
  403. package/src/extensions/tools/executors/file-read.test.ts +0 -125
  404. package/src/extensions/tools/model-tool-routing.test.ts +0 -86
  405. package/src/extensions/tools/presets.test.ts +0 -70
  406. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
  407. package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
  408. package/src/extensions/tools/team/team-tools.test.ts +0 -918
  409. package/src/hooks/checkpoint-hooks.test.ts +0 -168
  410. package/src/hooks/hook-file-hooks.test.ts +0 -311
  411. package/src/hooks/persistent.ts +0 -661
  412. package/src/runtime/history.test.ts +0 -114
  413. package/src/runtime/host.test.ts +0 -230
  414. package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
  415. package/src/runtime/rpc-runtime-ensure.ts +0 -659
  416. package/src/runtime/rpc-spawn-lease.test.ts +0 -81
  417. package/src/runtime/rpc-spawn-lease.ts +0 -156
  418. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
  419. package/src/runtime/runtime-builder.test.ts +0 -615
  420. package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
  421. package/src/runtime/runtime-parity.test.ts +0 -143
  422. package/src/services/providers/local-provider-service.test.ts +0 -1062
  423. package/src/services/session-data.test.ts +0 -160
  424. package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
  425. package/src/services/storage/provider-settings-manager.test.ts +0 -191
  426. package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  427. package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
  428. package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
  429. package/src/services/telemetry/TelemetryService.test.ts +0 -134
  430. package/src/services/telemetry/distinct-id.test.ts +0 -57
  431. package/src/services/workspace/file-indexer.d.ts +0 -11
  432. package/src/services/workspace/file-indexer.test.ts +0 -156
  433. package/src/services/workspace/mention-enricher.test.ts +0 -106
  434. package/src/session/persistence-service.test.ts +0 -300
  435. package/src/session/rpc-session-service.ts +0 -114
  436. package/src/session/session-service.team-persistence.test.ts +0 -48
  437. package/src/session/sqlite-rpc-session-backend.ts +0 -301
  438. package/src/transports/local.e2e.test.ts +0 -380
  439. package/src/transports/local.test.ts +0 -2559
  440. package/src/transports/rpc.test.ts +0 -82
  441. package/src/transports/rpc.ts +0 -665
@@ -1,85 +1,42 @@
1
- import {
2
- appendFileSync,
3
- existsSync,
4
- mkdirSync,
5
- readFileSync,
6
- writeFileSync,
7
- } from "node:fs";
8
- import { dirname, join } from "node:path";
1
+ import { dirname } from "node:path";
9
2
  import type * as LlmsProviders from "@clinebot/llms";
10
3
  import type { AgentResult } from "@clinebot/shared";
11
- import { resolveRootSessionId } from "@clinebot/shared";
12
- import { ensureHookLogDir } from "@clinebot/shared/storage";
13
4
  import { nanoid } from "nanoid";
14
- import { z } from "zod";
15
5
  import type {
16
6
  SubAgentEndContext,
17
7
  SubAgentStartContext,
18
8
  } from "../extensions/tools/team";
19
9
  import type { HookEventPayload } from "../hooks";
20
10
  import { deleteCheckpointRefs } from "../hooks/checkpoint-hooks";
21
- import {
22
- nowIso,
23
- SessionArtifacts,
24
- unlinkIfExists,
25
- } from "../services/session-artifacts";
11
+ import { nowIso, unlinkIfExists } from "../services/session-artifacts";
26
12
  import {
27
13
  buildManifestFromRow,
28
- buildMessagesFilePayload,
29
14
  deriveTitleFromPrompt,
30
15
  normalizeStoredMessagesForPersistence,
31
16
  normalizeTitle,
32
- resolveMessagesFileContext,
33
17
  resolveMetadataWithTitle,
34
18
  sanitizeMetadata,
35
19
  withLatestAssistantTurnMetadata,
36
20
  withOccRetry,
37
- writeEmptyMessagesFile,
38
21
  } from "../services/session-data";
39
- import { SessionSource, type SessionStatus } from "../types/common";
22
+ import type { SessionStatus } from "../types/common";
40
23
  import type {
41
24
  PersistedSessionUpdateInput,
42
25
  SessionMessagesArtifactUploader,
43
26
  SessionPersistenceAdapter,
44
27
  StoredMessageWithMetadata,
45
28
  } from "../types/session";
46
- import {
47
- deriveSubsessionStatus,
48
- makeSubSessionId,
49
- makeTeamTaskSubSessionId,
50
- } from "./session-graph";
51
- import {
52
- type SessionManifest,
53
- SessionManifestSchema,
54
- } from "./session-manifest";
55
- import type {
56
- CreateRootSessionWithArtifactsInput,
57
- RootSessionArtifacts,
58
- SessionRow,
59
- UpsertSubagentInput,
60
- } from "./session-service";
29
+ import { SessionManifestStore } from "./session-manifest-store";
30
+ import type { SessionRow } from "./session-row";
31
+ import { SubagentSessionManager } from "./subagent-session-manager";
61
32
 
62
33
  export type { PersistedSessionUpdateInput, SessionPersistenceAdapter };
63
34
 
64
- const SUBSESSION_SOURCE = SessionSource.SUBAGENT;
65
35
  const OCC_MAX_RETRIES = 4;
66
36
 
67
- const SpawnAgentInputSchema = z.looseObject({
68
- task: z.string().optional(),
69
- systemPrompt: z.string().optional(),
70
- });
71
-
72
- // ── Service ───────────────────────────────────────────────────────────
73
-
74
37
  export class UnifiedSessionPersistenceService {
75
- private readonly teamTaskSessionsByAgent = new Map<string, string[]>();
76
- private readonly teamTaskLastHeartbeatBySession = new Map<string, number>();
77
- private readonly teamTaskLastProgressLineBySession = new Map<
78
- string,
79
- string
80
- >();
81
- protected readonly artifacts: SessionArtifacts;
82
- private readonly messagesArtifactUploader?: SessionMessagesArtifactUploader;
38
+ private readonly manifestStore: SessionManifestStore;
39
+ private readonly subagents: SubagentSessionManager;
83
40
  private static readonly STALE_REASON = "failed_external_process_exit";
84
41
  private static readonly STALE_SOURCE = "stale_session_reconciler";
85
42
  private static readonly TEAM_HEARTBEAT_LOG_INTERVAL_MS = 30_000;
@@ -90,23 +47,16 @@ export class UnifiedSessionPersistenceService {
90
47
  messagesArtifactUploader?: SessionMessagesArtifactUploader;
91
48
  } = {},
92
49
  ) {
93
- this.artifacts = new SessionArtifacts(() => this.ensureSessionsDir());
94
- this.messagesArtifactUploader = options.messagesArtifactUploader;
95
- }
96
-
97
- ensureSessionsDir(): string {
98
- return this.adapter.ensureSessionsDir();
99
- }
100
-
101
- private initializeMessagesFile(
102
- sessionId: string,
103
- path: string,
104
- startedAt: string,
105
- ): void {
106
- writeEmptyMessagesFile(
107
- path,
108
- startedAt,
109
- resolveMessagesFileContext(sessionId),
50
+ this.manifestStore = new SessionManifestStore(
51
+ adapter,
52
+ options.messagesArtifactUploader,
53
+ );
54
+ this.subagents = new SubagentSessionManager(
55
+ adapter,
56
+ this.manifestStore,
57
+ (messages, result, previousMessages) =>
58
+ this.toPersistedMessages(messages, result, previousMessages),
59
+ UnifiedSessionPersistenceService.TEAM_HEARTBEAT_LOG_INTERVAL_MS,
110
60
  );
111
61
  }
112
62
 
@@ -127,99 +77,45 @@ export class UnifiedSessionPersistenceService {
127
77
  );
128
78
  }
129
79
 
130
- // ── Manifest I/O ──────────────────────────────────────────────────
80
+ ensureSessionsDir(): string {
81
+ return this.manifestStore.ensureSessionsDir();
82
+ }
131
83
 
132
- private writeManifestFile(
84
+ writeSessionManifest(
133
85
  manifestPath: string,
134
- manifest: SessionManifest,
86
+ manifest: import("./session-manifest").SessionManifest,
135
87
  ): void {
136
- mkdirSync(dirname(manifestPath), { recursive: true });
137
- writeFileSync(
138
- manifestPath,
139
- `${JSON.stringify(SessionManifestSchema.parse(manifest), null, 2)}\n`,
140
- "utf8",
141
- );
88
+ this.manifestStore.writeSessionManifest(manifestPath, manifest);
142
89
  }
143
90
 
144
- writeSessionManifest(manifestPath: string, manifest: SessionManifest): void {
145
- this.writeManifestFile(manifestPath, manifest);
146
- }
147
-
148
- readSessionManifest(sessionId: string): SessionManifest | undefined {
149
- return this.readManifestFile(sessionId).manifest;
150
- }
151
-
152
- private readManifestFile(sessionId: string): {
153
- path: string;
154
- manifest?: SessionManifest;
155
- } {
156
- const manifestPath = this.artifacts.sessionManifestPath(sessionId, false);
157
- if (!existsSync(manifestPath)) return { path: manifestPath };
158
- try {
159
- return {
160
- path: manifestPath,
161
- manifest: SessionManifestSchema.parse(
162
- JSON.parse(readFileSync(manifestPath, "utf8")) as SessionManifest,
163
- ),
164
- };
165
- } catch {
166
- return { path: manifestPath };
167
- }
168
- }
169
-
170
- // ── Path resolution ───────────────────────────────────────────────
171
-
172
- private async resolveArtifactPath(
91
+ readSessionManifest(
173
92
  sessionId: string,
174
- kind: "messagesPath",
175
- fallback: (id: string) => string,
176
- ): Promise<string> {
177
- const row = await this.adapter.getSession(sessionId);
178
- const value = row?.[kind];
179
- return typeof value === "string" && value.trim().length > 0
180
- ? value
181
- : fallback(sessionId);
182
- }
183
-
184
- // ── Team task queue ───────────────────────────────────────────────
185
-
186
- private teamTaskQueueKey(rootSessionId: string, agentId: string): string {
187
- return `${rootSessionId}::${agentId}`;
188
- }
189
-
190
- private activeTeamTaskSessionId(
191
- rootSessionId: string,
192
- parentAgentId: string,
193
- ): string | undefined {
194
- const queue = this.teamTaskSessionsByAgent.get(
195
- this.teamTaskQueueKey(rootSessionId, parentAgentId),
196
- );
197
- return queue?.at(-1);
93
+ ): import("./session-manifest").SessionManifest | undefined {
94
+ return this.manifestStore.readSessionManifest(sessionId);
198
95
  }
199
96
 
200
- // ── Root session ──────────────────────────────────────────────────
201
-
202
97
  async createRootSessionWithArtifacts(
203
- input: CreateRootSessionWithArtifactsInput,
204
- ): Promise<RootSessionArtifacts> {
98
+ input: import("./session-row").CreateRootSessionWithArtifactsInput,
99
+ ): Promise<import("./session-row").RootSessionArtifacts> {
205
100
  const startedAt = input.startedAt ?? nowIso();
206
101
  const providedId = input.sessionId.trim();
207
102
  const sessionId =
208
103
  providedId.length > 0 ? providedId : `${Date.now()}_${nanoid(5)}`;
209
- const messagesPath = this.artifacts.sessionMessagesPath(sessionId);
210
- const manifestPath = this.artifacts.sessionManifestPath(sessionId);
211
-
104
+ const messagesPath =
105
+ this.manifestStore.artifacts.sessionMessagesPath(sessionId);
106
+ const manifestPath =
107
+ this.manifestStore.artifacts.sessionManifestPath(sessionId);
212
108
  const metadata = resolveMetadataWithTitle({
213
109
  metadata: input.metadata,
214
110
  prompt: input.prompt,
215
111
  });
216
- const manifest = SessionManifestSchema.parse({
217
- version: 1,
112
+ const manifest = {
113
+ version: 1 as const,
218
114
  session_id: sessionId,
219
115
  source: input.source,
220
116
  pid: input.pid,
221
117
  started_at: startedAt,
222
- status: "running",
118
+ status: "running" as const,
223
119
  interactive: input.interactive,
224
120
  provider: input.provider,
225
121
  model: input.model,
@@ -232,7 +128,7 @@ export class UnifiedSessionPersistenceService {
232
128
  prompt: input.prompt?.trim() || undefined,
233
129
  metadata,
234
130
  messages_path: messagesPath,
235
- });
131
+ };
236
132
 
237
133
  await this.adapter.upsertSession({
238
134
  sessionId,
@@ -264,13 +160,15 @@ export class UnifiedSessionPersistenceService {
264
160
  updatedAt: nowIso(),
265
161
  });
266
162
 
267
- this.initializeMessagesFile(sessionId, messagesPath, startedAt);
268
- this.writeManifestFile(manifestPath, manifest);
163
+ this.manifestStore.initializeMessagesFile(
164
+ sessionId,
165
+ messagesPath,
166
+ startedAt,
167
+ );
168
+ this.manifestStore.writeSessionManifest(manifestPath, manifest);
269
169
  return { manifestPath, messagesPath, manifest };
270
170
  }
271
171
 
272
- // ── Session status updates ────────────────────────────────────────
273
-
274
172
  async updateSessionStatus(
275
173
  sessionId: string,
276
174
  status: SessionStatus,
@@ -293,7 +191,10 @@ export class UnifiedSessionPersistenceService {
293
191
  );
294
192
  if (result.updated) {
295
193
  if (status === "cancelled") {
296
- await this.applyStatusToRunningChildSessions(sessionId, "cancelled");
194
+ await this.subagents.applyStatusToRunningChildSessions(
195
+ sessionId,
196
+ "cancelled",
197
+ );
297
198
  }
298
199
  return { updated: true, endedAt };
299
200
  }
@@ -352,9 +253,8 @@ export class UnifiedSessionPersistenceService {
352
253
  });
353
254
  if (!changed.updated) continue;
354
255
 
355
- const { path: manifestPath, manifest } = this.readManifestFile(
356
- input.sessionId,
357
- );
256
+ const { path: manifestPath, manifest } =
257
+ this.manifestStore.readManifestFile(input.sessionId);
358
258
  if (manifest) {
359
259
  if (input.prompt !== undefined) {
360
260
  manifest.prompt = input.prompt ?? undefined;
@@ -366,411 +266,130 @@ export class UnifiedSessionPersistenceService {
366
266
  if (nextTitle) manifestMeta.title = nextTitle;
367
267
  manifest.metadata =
368
268
  Object.keys(manifestMeta).length > 0 ? manifestMeta : undefined;
369
- this.writeManifestFile(manifestPath, manifest);
269
+ this.manifestStore.writeSessionManifest(manifestPath, manifest);
370
270
  }
371
271
  return { updated: true };
372
272
  }
373
273
  return { updated: false };
374
274
  }
375
275
 
376
- // ── Spawn queue ───────────────────────────────────────────────────
377
-
378
- async queueSpawnRequest(event: HookEventPayload): Promise<void> {
379
- if (event.hookName !== "tool_call" || event.parent_agent_id !== null)
380
- return;
381
- if (event.tool_call?.name !== "spawn_agent") return;
382
-
383
- const rootSessionId = resolveRootSessionId(event.sessionContext);
384
- if (!rootSessionId) return;
385
-
386
- const parsed = SpawnAgentInputSchema.safeParse(event.tool_call.input);
387
- await this.adapter.enqueueSpawnRequest({
388
- rootSessionId,
389
- parentAgentId: event.agent_id,
390
- task: parsed.success ? parsed.data.task : undefined,
391
- systemPrompt: parsed.success ? parsed.data.systemPrompt : undefined,
392
- });
393
- }
394
-
395
- // ── Subagent sessions ─────────────────────────────────────────────
396
-
397
- private buildSubsessionRow(
398
- root: SessionRow,
399
- opts: {
400
- sessionId: string;
401
- parentSessionId: string;
402
- parentAgentId: string;
403
- agentId: string;
404
- conversationId?: string | null;
405
- prompt: string;
406
- startedAt: string;
407
- messagesPath: string;
408
- },
409
- ): SessionRow {
410
- return {
411
- sessionId: opts.sessionId,
412
- source: SUBSESSION_SOURCE,
413
- pid: process.ppid,
414
- startedAt: opts.startedAt,
415
- endedAt: null,
416
- exitCode: null,
417
- status: "running",
418
- statusLock: 0,
419
- interactive: false,
420
- provider: root.provider,
421
- model: root.model,
422
- cwd: root.cwd,
423
- workspaceRoot: root.workspaceRoot,
424
- teamName: root.teamName ?? null,
425
- enableTools: root.enableTools,
426
- enableSpawn: root.enableSpawn,
427
- enableTeams: root.enableTeams,
428
- parentSessionId: opts.parentSessionId,
429
- parentAgentId: opts.parentAgentId,
430
- agentId: opts.agentId,
431
- conversationId: opts.conversationId ?? null,
432
- isSubagent: true,
433
- prompt: opts.prompt,
434
- metadata: resolveMetadataWithTitle({ prompt: opts.prompt }),
435
- hookPath: "",
436
- messagesPath: opts.messagesPath,
437
- updatedAt: opts.startedAt,
438
- };
276
+ queueSpawnRequest(event: HookEventPayload): Promise<void> {
277
+ return this.subagents.queueSpawnRequest(event);
439
278
  }
440
279
 
441
- async upsertSubagentSession(
442
- input: UpsertSubagentInput,
280
+ upsertSubagentSession(
281
+ input: import("./session-row").UpsertSubagentInput,
443
282
  ): Promise<string | undefined> {
444
- const rootSessionId = input.rootSessionId;
445
- if (!rootSessionId) return undefined;
446
-
447
- const root = await this.adapter.getSession(rootSessionId);
448
- if (!root) return undefined;
449
-
450
- const sessionId = makeSubSessionId(rootSessionId, input.agentId);
451
- const existing = await this.adapter.getSession(sessionId);
452
- const startedAt = nowIso();
453
- const artifactPaths = this.artifacts.subagentArtifactPaths(
454
- sessionId,
455
- input.agentId,
456
- this.activeTeamTaskSessionId(rootSessionId, input.parentAgentId),
457
- );
458
-
459
- let prompt = input.prompt ?? existing?.prompt ?? undefined;
460
- if (!prompt) {
461
- prompt =
462
- (await this.adapter.claimSpawnRequest(
463
- rootSessionId,
464
- input.parentAgentId,
465
- )) ?? `Subagent run by ${input.parentAgentId}`;
466
- }
467
-
468
- if (!existing) {
469
- await this.adapter.upsertSession(
470
- this.buildSubsessionRow(root, {
471
- sessionId,
472
- parentSessionId: rootSessionId,
473
- parentAgentId: input.parentAgentId,
474
- agentId: input.agentId,
475
- conversationId: input.conversationId,
476
- prompt,
477
- startedAt,
478
- ...artifactPaths,
479
- }),
480
- );
481
- this.initializeMessagesFile(
482
- sessionId,
483
- artifactPaths.messagesPath,
484
- startedAt,
485
- );
486
- return sessionId;
487
- }
488
-
489
- await this.adapter.updateSession({
490
- sessionId,
491
- setRunning: true,
492
- parentSessionId: rootSessionId,
493
- parentAgentId: input.parentAgentId,
494
- agentId: input.agentId,
495
- conversationId: input.conversationId,
496
- prompt: existing.prompt ?? prompt ?? null,
497
- metadata: resolveMetadataWithTitle({
498
- metadata: existing.metadata ?? undefined,
499
- prompt: existing.prompt ?? prompt ?? null,
500
- }),
501
- expectedStatusLock: existing.statusLock,
502
- });
503
- return sessionId;
283
+ return this.subagents.upsertSubagentSession(input);
504
284
  }
505
285
 
506
- async upsertSubagentSessionFromHook(
286
+ upsertSubagentSessionFromHook(
507
287
  event: HookEventPayload,
508
288
  ): Promise<string | undefined> {
509
- if (!event.parent_agent_id) return undefined;
510
-
511
- const rootSessionId = resolveRootSessionId(event.sessionContext);
512
- if (!rootSessionId) return undefined;
513
-
514
- if (event.hookName === "session_shutdown") {
515
- const sessionId = makeSubSessionId(rootSessionId, event.agent_id);
516
- const existing = await this.adapter.getSession(sessionId);
517
- return existing ? sessionId : undefined;
518
- }
519
- return await this.upsertSubagentSession({
520
- agentId: event.agent_id,
521
- parentAgentId: event.parent_agent_id,
522
- conversationId: event.taskId,
523
- rootSessionId,
524
- });
289
+ return this.subagents.upsertSubagentSessionFromHook(event);
525
290
  }
526
291
 
527
- // ── Subagent audit / transcript ───────────────────────────────────
528
-
529
- async appendSubagentHookAudit(
530
- subSessionId: string,
292
+ appendSubagentHookAudit(
293
+ _subSessionId: string,
531
294
  event: HookEventPayload,
532
295
  ): Promise<void> {
533
- void subSessionId;
534
- const envPath = process.env.CLINE_HOOKS_LOG_PATH?.trim() || undefined;
535
- const logPath = envPath ?? join(ensureHookLogDir(), "hooks.jsonl");
536
- appendFileSync(
537
- logPath,
538
- `${JSON.stringify({ ts: nowIso(), ...event })}\n`,
539
- "utf8",
540
- );
296
+ this.subagents.appendSubagentHookAudit(event);
297
+ return Promise.resolve();
541
298
  }
542
299
 
543
- async persistSessionMessages(
300
+ persistSessionMessages(
544
301
  sessionId: string,
545
302
  messages: LlmsProviders.Message[],
546
303
  systemPrompt?: string,
547
304
  ): Promise<void> {
548
- const path = await this.resolveArtifactPath(
549
- sessionId,
550
- "messagesPath",
551
- (id) => this.artifacts.sessionMessagesPath(id),
552
- );
553
305
  const normalizedMessages = normalizeStoredMessagesForPersistence(
554
306
  messages as LlmsProviders.MessageWithMetadata[],
555
307
  );
556
- const payload = buildMessagesFilePayload({
557
- updatedAt: nowIso(),
558
- context: resolveMessagesFileContext(sessionId),
559
- messages: normalizedMessages,
308
+ return this.manifestStore.persistSessionMessages(
309
+ sessionId,
310
+ normalizedMessages,
560
311
  systemPrompt,
561
- });
562
- const contents = `${JSON.stringify(payload, null, 2)}\n`;
563
- mkdirSync(dirname(path), { recursive: true });
564
- writeFileSync(path, contents, "utf8");
565
- if (!this.messagesArtifactUploader) {
566
- return;
567
- }
568
- try {
569
- const row = await this.adapter.getSession(sessionId);
570
- await this.messagesArtifactUploader.uploadMessagesFile({
571
- sessionId,
572
- path,
573
- contents,
574
- row,
575
- });
576
- } catch (error) {
577
- console.warn(
578
- `Failed to upload persisted session messages for ${sessionId}`,
579
- error,
580
- );
581
- }
312
+ );
582
313
  }
583
314
 
584
- // ── Subagent status ───────────────────────────────────────────────
585
-
586
- async applySubagentStatus(
315
+ applySubagentStatus(
587
316
  subSessionId: string,
588
317
  event: HookEventPayload,
589
318
  ): Promise<void> {
590
- await this.applySubagentStatusBySessionId(
591
- subSessionId,
592
- deriveSubsessionStatus(event),
593
- );
319
+ return this.subagents.applySubagentStatus(subSessionId, event);
594
320
  }
595
321
 
596
- async applySubagentStatusBySessionId(
322
+ applySubagentStatusBySessionId(
597
323
  subSessionId: string,
598
324
  status: SessionStatus,
599
325
  ): Promise<void> {
600
- const row = await this.adapter.getSession(subSessionId);
601
- if (!row) return;
602
-
603
- const endedAt = status === "running" ? null : nowIso();
604
- const exitCode = status === "running" ? null : status === "failed" ? 1 : 0;
605
- await this.adapter.updateSession({
606
- sessionId: subSessionId,
607
- status,
608
- endedAt,
609
- exitCode,
610
- expectedStatusLock: row.statusLock,
611
- });
326
+ return this.subagents.applySubagentStatusBySessionId(subSessionId, status);
612
327
  }
613
328
 
614
- async applyStatusToRunningChildSessions(
329
+ applyStatusToRunningChildSessions(
615
330
  parentSessionId: string,
616
331
  status: Exclude<SessionStatus, "running">,
617
332
  ): Promise<void> {
618
- if (!parentSessionId) return;
619
- const rows = await this.adapter.listSessions({
620
- limit: 2000,
333
+ return this.subagents.applyStatusToRunningChildSessions(
621
334
  parentSessionId,
622
- status: "running",
623
- });
624
- for (const row of rows) {
625
- await this.applySubagentStatusBySessionId(row.sessionId, status);
626
- }
335
+ status,
336
+ );
627
337
  }
628
338
 
629
- // ── Team tasks ────────────────────────────────────────────────────
630
-
631
- async onTeamTaskStart(
339
+ onTeamTaskStart(
632
340
  rootSessionId: string,
633
341
  agentId: string,
634
342
  message: string,
635
343
  ): Promise<void> {
636
- const root = await this.adapter.getSession(rootSessionId);
637
- if (!root) return;
638
-
639
- const sessionId = makeTeamTaskSubSessionId(rootSessionId, agentId);
640
- const startedAt = nowIso();
641
- const { messagesPath } = this.artifacts.subagentArtifactPaths(
642
- sessionId,
643
- agentId,
644
- );
645
-
646
- await this.adapter.upsertSession(
647
- this.buildSubsessionRow(root, {
648
- sessionId,
649
- parentSessionId: rootSessionId,
650
- parentAgentId: "lead",
651
- agentId,
652
- prompt: message || `Team task for ${agentId}`,
653
- startedAt,
654
- messagesPath,
655
- }),
656
- );
657
- this.initializeMessagesFile(sessionId, messagesPath, startedAt);
658
-
659
- const key = this.teamTaskQueueKey(rootSessionId, agentId);
660
- const queue = this.teamTaskSessionsByAgent.get(key) ?? [];
661
- queue.push(sessionId);
662
- this.teamTaskSessionsByAgent.set(key, queue);
344
+ return this.subagents.onTeamTaskStart(rootSessionId, agentId, message);
663
345
  }
664
346
 
665
- async onTeamTaskEnd(
347
+ onTeamTaskEnd(
666
348
  rootSessionId: string,
667
349
  agentId: string,
668
350
  status: SessionStatus,
669
- _summary?: string,
351
+ summary?: string,
670
352
  result?: AgentResult,
671
353
  messages?: LlmsProviders.Message[],
672
354
  ): Promise<void> {
673
- const key = this.teamTaskQueueKey(rootSessionId, agentId);
674
- const queue = this.teamTaskSessionsByAgent.get(key);
675
- if (!queue || queue.length === 0) return;
676
-
677
- const sessionId = queue.shift();
678
- if (queue.length === 0) this.teamTaskSessionsByAgent.delete(key);
679
- if (!sessionId) return;
680
-
681
- const teammateMessages = result?.messages ?? messages;
682
- const persistedMessages = this.toPersistedMessages(
683
- teammateMessages,
355
+ return this.subagents.onTeamTaskEnd(
356
+ rootSessionId,
357
+ agentId,
358
+ status,
359
+ summary,
684
360
  result,
685
361
  messages,
686
362
  );
687
- if (persistedMessages) {
688
- await this.persistSessionMessages(sessionId, persistedMessages);
689
- }
690
- await this.applySubagentStatusBySessionId(sessionId, status);
691
- this.teamTaskLastHeartbeatBySession.delete(sessionId);
692
- this.teamTaskLastProgressLineBySession.delete(sessionId);
693
363
  }
694
364
 
695
- async onTeamTaskProgress(
365
+ onTeamTaskProgress(
696
366
  rootSessionId: string,
697
367
  agentId: string,
698
368
  progress: string,
699
369
  options?: { kind?: "heartbeat" | "progress" | "text" },
700
370
  ): Promise<void> {
701
- const key = this.teamTaskQueueKey(rootSessionId, agentId);
702
- const sessionId = this.teamTaskSessionsByAgent.get(key)?.[0];
703
- if (!sessionId) return;
704
-
705
- const trimmed = progress.trim();
706
- if (!trimmed) return;
707
-
708
- const kind = options?.kind ?? "progress";
709
- if (kind === "heartbeat") {
710
- const now = Date.now();
711
- const last = this.teamTaskLastHeartbeatBySession.get(sessionId) ?? 0;
712
- if (
713
- now - last <
714
- UnifiedSessionPersistenceService.TEAM_HEARTBEAT_LOG_INTERVAL_MS
715
- ) {
716
- return;
717
- }
718
- this.teamTaskLastHeartbeatBySession.set(sessionId, now);
719
- }
720
-
721
- const line =
722
- kind === "heartbeat"
723
- ? "[progress] heartbeat"
724
- : kind === "text"
725
- ? `[progress] text: ${trimmed}`
726
- : `[progress] ${trimmed}`;
727
- if (this.teamTaskLastProgressLineBySession.get(sessionId) === line) return;
728
- this.teamTaskLastProgressLineBySession.set(sessionId, line);
371
+ return this.subagents.onTeamTaskProgress(
372
+ rootSessionId,
373
+ agentId,
374
+ progress,
375
+ options,
376
+ );
729
377
  }
730
378
 
731
- // ── SubAgent lifecycle ────────────────────────────────────────────
732
-
733
- async handleSubAgentStart(
379
+ handleSubAgentStart(
734
380
  rootSessionId: string,
735
381
  context: SubAgentStartContext,
736
382
  ): Promise<void> {
737
- const subSessionId = await this.upsertSubagentSession({
738
- agentId: context.subAgentId,
739
- parentAgentId: context.parentAgentId,
740
- conversationId: context.conversationId,
741
- prompt: context.input.task,
742
- rootSessionId,
743
- });
744
- if (!subSessionId) return;
745
- await this.applySubagentStatusBySessionId(subSessionId, "running");
383
+ return this.subagents.handleSubAgentStart(rootSessionId, context);
746
384
  }
747
385
 
748
- async handleSubAgentEnd(
386
+ handleSubAgentEnd(
749
387
  rootSessionId: string,
750
388
  context: SubAgentEndContext,
751
389
  ): Promise<void> {
752
- const subSessionId = await this.upsertSubagentSession({
753
- agentId: context.subAgentId,
754
- parentAgentId: context.parentAgentId,
755
- conversationId: context.conversationId,
756
- prompt: context.input.task,
757
- rootSessionId,
758
- });
759
- if (!subSessionId) return;
760
-
761
- if (context.error) {
762
- await this.applySubagentStatusBySessionId(subSessionId, "failed");
763
- return;
764
- }
765
- const reason = context.result?.finishReason ?? "completed";
766
- await this.applySubagentStatusBySessionId(
767
- subSessionId,
768
- reason === "aborted" ? "cancelled" : "completed",
769
- );
390
+ return this.subagents.handleSubAgentEnd(rootSessionId, context);
770
391
  }
771
392
 
772
- // ── Stale session reconciliation ──────────────────────────────────
773
-
774
393
  private isPidAlive(pid: number): boolean {
775
394
  if (!Number.isFinite(pid) || pid <= 0) return false;
776
395
  try {
@@ -817,7 +436,10 @@ export class UnifiedSessionPersistenceService {
817
436
  });
818
437
  if (!changed.updated) continue;
819
438
 
820
- await this.applyStatusToRunningChildSessions(latest.sessionId, "failed");
439
+ await this.subagents.applyStatusToRunningChildSessions(
440
+ latest.sessionId,
441
+ "failed",
442
+ );
821
443
 
822
444
  const manifest = buildManifestFromRow(latest, {
823
445
  status: "failed",
@@ -825,25 +447,17 @@ export class UnifiedSessionPersistenceService {
825
447
  exitCode: 1,
826
448
  metadata: nextMetadata,
827
449
  });
828
- const { path: manifestPath } = this.readManifestFile(latest.sessionId);
829
- this.writeManifestFile(manifestPath, manifest);
830
-
831
- {
832
- const envPath = process.env.CLINE_HOOKS_LOG_PATH?.trim() || undefined;
833
- const logPath = envPath ?? join(ensureHookLogDir(), "hooks.jsonl");
834
- appendFileSync(
835
- logPath,
836
- `${JSON.stringify({
837
- ts: detectedAt,
838
- hookName: "session_shutdown",
839
- reason,
840
- sessionId: latest.sessionId,
841
- pid: latest.pid,
842
- source: UnifiedSessionPersistenceService.STALE_SOURCE,
843
- })}\n`,
844
- "utf8",
845
- );
846
- }
450
+ const { path: manifestPath } = this.manifestStore.readManifestFile(
451
+ latest.sessionId,
452
+ );
453
+ this.manifestStore.writeSessionManifest(manifestPath, manifest);
454
+ this.manifestStore.appendStaleSessionHookLog(
455
+ detectedAt,
456
+ latest.sessionId,
457
+ latest.pid,
458
+ reason,
459
+ UnifiedSessionPersistenceService.STALE_SOURCE,
460
+ );
847
461
  return {
848
462
  ...latest,
849
463
  status: "failed",
@@ -857,8 +471,6 @@ export class UnifiedSessionPersistenceService {
857
471
  return await this.adapter.getSession(row.sessionId);
858
472
  }
859
473
 
860
- // ── List / reconcile / delete ─────────────────────────────────────
861
-
862
474
  async listSessions(limit = 200): Promise<SessionRow[]> {
863
475
  const requestedLimit = Math.max(1, Math.floor(limit));
864
476
  const scanLimit = Math.min(requestedLimit * 5, 2000);
@@ -867,7 +479,7 @@ export class UnifiedSessionPersistenceService {
867
479
  const rows = await this.adapter.listSessions({ limit: scanLimit });
868
480
  return rows.slice(0, requestedLimit).map((row) => {
869
481
  const meta = sanitizeMetadata(row.metadata ?? undefined);
870
- const { manifest } = this.readManifestFile(row.sessionId);
482
+ const manifest = this.manifestStore.readSessionManifest(row.sessionId);
871
483
  const manifestTitle = normalizeTitle(
872
484
  typeof manifest?.metadata?.title === "string"
873
485
  ? (manifest.metadata.title as string)
@@ -913,9 +525,12 @@ export class UnifiedSessionPersistenceService {
913
525
  await deleteCheckpointRefs(child.cwd, child.sessionId);
914
526
  unlinkIfExists(child.messagesPath);
915
527
  unlinkIfExists(
916
- this.artifacts.sessionManifestPath(child.sessionId, false),
528
+ this.manifestStore.artifacts.sessionManifestPath(
529
+ child.sessionId,
530
+ false,
531
+ ),
917
532
  );
918
- this.artifacts.removeSessionDirIfEmpty(child.sessionId);
533
+ this.manifestStore.artifacts.removeSessionDirIfEmpty(child.sessionId);
919
534
  }),
920
535
  );
921
536
  }
@@ -923,12 +538,12 @@ export class UnifiedSessionPersistenceService {
923
538
  await deleteCheckpointRefs(row.cwd, id);
924
539
 
925
540
  unlinkIfExists(row.messagesPath);
926
- unlinkIfExists(this.artifacts.sessionManifestPath(id, false));
541
+ unlinkIfExists(this.manifestStore.artifacts.sessionManifestPath(id, false));
927
542
  if (row.isSubagent) {
928
- this.artifacts.removeSessionDirIfEmpty(id);
543
+ this.manifestStore.artifacts.removeSessionDirIfEmpty(id);
929
544
  } else {
930
545
  const candidateDirs = new Set<string>([
931
- this.artifacts.sessionArtifactsDir(id),
546
+ this.manifestStore.artifacts.sessionArtifactsDir(id),
932
547
  ]);
933
548
  for (const path of [row.messagesPath]) {
934
549
  if (typeof path === "string" && path.trim().length > 0) {
@@ -936,7 +551,7 @@ export class UnifiedSessionPersistenceService {
936
551
  }
937
552
  }
938
553
  for (const dir of candidateDirs) {
939
- this.artifacts.removeDir(dir);
554
+ this.manifestStore.artifacts.removeDir(dir);
940
555
  }
941
556
  }
942
557
  return { deleted: true };