@clinebot/core 0.0.28 → 0.0.29

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 (339) hide show
  1. package/README.md +7 -0
  2. package/dist/ClineCore.d.ts +28 -2
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts +1 -1
  5. package/dist/account/cline-account-service.d.ts.map +1 -1
  6. package/dist/account/index.d.ts +1 -1
  7. package/dist/account/index.d.ts.map +1 -1
  8. package/dist/account/types.d.ts +5 -0
  9. package/dist/account/types.d.ts.map +1 -1
  10. package/dist/auth/bounded-ttl-cache.d.ts +14 -0
  11. package/dist/auth/bounded-ttl-cache.d.ts.map +1 -0
  12. package/dist/auth/cline.d.ts +27 -2
  13. package/dist/auth/cline.d.ts.map +1 -1
  14. package/dist/auth/oca.d.ts.map +1 -1
  15. package/dist/chat/chat-schema.d.ts +11 -11
  16. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -0
  17. package/dist/{agents → extensions/config}/agent-config-parser.d.ts +2 -2
  18. package/dist/extensions/config/agent-config-parser.d.ts.map +1 -0
  19. package/dist/{agents → extensions/config}/hooks-config-loader.d.ts +1 -1
  20. package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -0
  21. package/dist/{agents → extensions/config}/index.d.ts +2 -4
  22. package/dist/extensions/config/index.d.ts.map +1 -0
  23. package/dist/{runtime/commands.d.ts → extensions/config/runtime-commands.d.ts} +2 -3
  24. package/dist/extensions/config/runtime-commands.d.ts.map +1 -0
  25. package/dist/extensions/config/unified-config-file-watcher.d.ts.map +1 -0
  26. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -0
  27. package/dist/extensions/context/agentic-compaction.d.ts +13 -0
  28. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -0
  29. package/dist/extensions/context/basic-compaction.d.ts +9 -0
  30. package/dist/extensions/context/basic-compaction.d.ts.map +1 -0
  31. package/dist/extensions/context/compaction-shared.d.ts +60 -0
  32. package/dist/extensions/context/compaction-shared.d.ts.map +1 -0
  33. package/dist/extensions/context/compaction.d.ts +20 -0
  34. package/dist/extensions/context/compaction.d.ts.map +1 -0
  35. package/dist/extensions/index.d.ts +5 -0
  36. package/dist/extensions/index.d.ts.map +1 -0
  37. package/dist/extensions/mcp/client.d.ts +3 -0
  38. package/dist/extensions/mcp/client.d.ts.map +1 -0
  39. package/dist/extensions/mcp/config-loader.d.ts.map +1 -0
  40. package/dist/extensions/mcp/index.d.ts +9 -0
  41. package/dist/extensions/mcp/index.d.ts.map +1 -0
  42. package/dist/{mcp → extensions/mcp}/manager.d.ts +1 -2
  43. package/dist/extensions/mcp/manager.d.ts.map +1 -0
  44. package/dist/extensions/mcp/name-transform.d.ts +3 -0
  45. package/dist/extensions/mcp/name-transform.d.ts.map +1 -0
  46. package/dist/extensions/mcp/policies.d.ts +15 -0
  47. package/dist/extensions/mcp/policies.d.ts.map +1 -0
  48. package/dist/extensions/mcp/tools.d.ts +4 -0
  49. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  50. package/dist/{mcp → extensions/mcp}/types.d.ts +29 -1
  51. package/dist/extensions/mcp/types.d.ts.map +1 -0
  52. package/dist/{agents → extensions/plugin}/plugin-config-loader.d.ts +1 -1
  53. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -0
  54. package/dist/{agents → extensions/plugin}/plugin-loader.d.ts +1 -1
  55. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -0
  56. package/dist/extensions/plugin/plugin-module-import.d.ts +5 -0
  57. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -0
  58. package/dist/{agents → extensions/plugin}/plugin-sandbox.d.ts +1 -1
  59. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -0
  60. package/dist/extensions/plugin-sandbox-bootstrap.js +485 -0
  61. package/dist/hooks/index.d.ts +4 -0
  62. package/dist/hooks/index.d.ts.map +1 -0
  63. package/dist/hooks/persistent.d.ts +64 -0
  64. package/dist/hooks/persistent.d.ts.map +1 -0
  65. package/dist/hooks/subprocess-runner.d.ts +22 -0
  66. package/dist/hooks/subprocess-runner.d.ts.map +1 -0
  67. package/dist/hooks/subprocess.d.ts +189 -0
  68. package/dist/hooks/subprocess.d.ts.map +1 -0
  69. package/dist/index.d.ts +22 -25
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +560 -447
  72. package/dist/prompt/default-system.d.ts +2 -0
  73. package/dist/prompt/default-system.d.ts.map +1 -0
  74. package/dist/providers/local-provider-service.d.ts +1 -1
  75. package/dist/providers/local-provider-service.d.ts.map +1 -1
  76. package/dist/runtime/checkpoint-hooks.d.ts +21 -0
  77. package/dist/runtime/checkpoint-hooks.d.ts.map +1 -0
  78. package/dist/runtime/hook-file-hooks.d.ts +1 -1
  79. package/dist/runtime/hook-file-hooks.d.ts.map +1 -1
  80. package/dist/runtime/rules.d.ts +1 -1
  81. package/dist/runtime/rules.d.ts.map +1 -1
  82. package/dist/runtime/runtime-builder.d.ts +1 -1
  83. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  84. package/dist/runtime/session-runtime.d.ts +25 -5
  85. package/dist/runtime/session-runtime.d.ts.map +1 -1
  86. package/dist/runtime/subprocess-sandbox.d.ts.map +1 -0
  87. package/dist/runtime/team-runtime-registry.d.ts +1 -1
  88. package/dist/runtime/team-runtime-registry.d.ts.map +1 -1
  89. package/dist/runtime/tool-approval.d.ts +1 -1
  90. package/dist/session/default-session-manager.d.ts +4 -3
  91. package/dist/session/default-session-manager.d.ts.map +1 -1
  92. package/dist/session/file-session-service.d.ts +1 -1
  93. package/dist/session/file-session-service.d.ts.map +1 -1
  94. package/dist/session/{unified-session-persistence-service.d.ts → persistence-service.d.ts} +11 -42
  95. package/dist/session/persistence-service.d.ts.map +1 -0
  96. package/dist/session/rpc-session-service.d.ts +1 -1
  97. package/dist/session/rpc-session-service.d.ts.map +1 -1
  98. package/dist/session/session-agent-events.d.ts +1 -1
  99. package/dist/session/session-artifacts.d.ts.map +1 -1
  100. package/dist/session/session-config-builder.d.ts.map +1 -1
  101. package/dist/session/session-graph.d.ts +1 -1
  102. package/dist/session/session-graph.d.ts.map +1 -1
  103. package/dist/session/session-host.d.ts.map +1 -1
  104. package/dist/session/session-manager.d.ts +6 -5
  105. package/dist/session/session-manager.d.ts.map +1 -1
  106. package/dist/session/session-manifest.d.ts +1 -1
  107. package/dist/session/session-service.d.ts +3 -2
  108. package/dist/session/session-service.d.ts.map +1 -1
  109. package/dist/session/session-team-coordination.d.ts +2 -1
  110. package/dist/session/session-team-coordination.d.ts.map +1 -1
  111. package/dist/session/utils/helpers.d.ts +51 -3
  112. package/dist/session/utils/helpers.d.ts.map +1 -1
  113. package/dist/session/utils/types.d.ts +41 -7
  114. package/dist/session/utils/types.d.ts.map +1 -1
  115. package/dist/session/workspace-manager.d.ts +1 -2
  116. package/dist/session/workspace-manager.d.ts.map +1 -1
  117. package/dist/session/workspace-manifest.d.ts +1 -22
  118. package/dist/session/workspace-manifest.d.ts.map +1 -1
  119. package/dist/storage/file-team-store.d.ts +2 -1
  120. package/dist/storage/file-team-store.d.ts.map +1 -1
  121. package/dist/storage/sqlite-team-store.d.ts +4 -1
  122. package/dist/storage/sqlite-team-store.d.ts.map +1 -1
  123. package/dist/storage/team-store.d.ts.map +1 -1
  124. package/dist/team/delegated-agent.d.ts +44 -0
  125. package/dist/team/delegated-agent.d.ts.map +1 -0
  126. package/dist/team/index.d.ts +1 -0
  127. package/dist/team/index.d.ts.map +1 -1
  128. package/dist/team/multi-agent.d.ts +229 -0
  129. package/dist/team/multi-agent.d.ts.map +1 -0
  130. package/dist/team/projections.d.ts +2 -2
  131. package/dist/team/projections.d.ts.map +1 -1
  132. package/dist/team/runtime.d.ts +5 -0
  133. package/dist/team/runtime.d.ts.map +1 -0
  134. package/dist/team/spawn-agent-tool.d.ts +85 -0
  135. package/dist/team/spawn-agent-tool.d.ts.map +1 -0
  136. package/dist/team/subagent-prompts.d.ts +4 -0
  137. package/dist/team/subagent-prompts.d.ts.map +1 -0
  138. package/dist/team/team-tools.d.ts +35 -0
  139. package/dist/team/team-tools.d.ts.map +1 -0
  140. package/dist/telemetry/OpenTelemetryProvider.d.ts +11 -1
  141. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
  142. package/dist/telemetry/{LoggerTelemetryAdapter.d.ts → TelemetryLoggerSink.d.ts} +10 -4
  143. package/dist/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
  144. package/dist/telemetry/TelemetryService.d.ts.map +1 -1
  145. package/dist/telemetry/index.js +15 -28
  146. package/dist/tools/definitions.d.ts +4 -3
  147. package/dist/tools/definitions.d.ts.map +1 -1
  148. package/dist/tools/index.d.ts +5 -5
  149. package/dist/tools/index.d.ts.map +1 -1
  150. package/dist/tools/model-tool-routing.d.ts.map +1 -1
  151. package/dist/tools/presets.d.ts +26 -0
  152. package/dist/tools/presets.d.ts.map +1 -1
  153. package/dist/tools/schemas.d.ts +8 -0
  154. package/dist/tools/schemas.d.ts.map +1 -1
  155. package/dist/tools/types.d.ts +23 -2
  156. package/dist/tools/types.d.ts.map +1 -1
  157. package/dist/types/config.d.ts +47 -3
  158. package/dist/types/config.d.ts.map +1 -1
  159. package/dist/types/events.d.ts +1 -1
  160. package/dist/types/provider-settings.d.ts +1 -1
  161. package/dist/types/provider-settings.d.ts.map +1 -1
  162. package/dist/types/storage.d.ts +2 -1
  163. package/dist/types/storage.d.ts.map +1 -1
  164. package/dist/types.d.ts +7 -16
  165. package/dist/types.d.ts.map +1 -1
  166. package/package.json +15 -12
  167. package/src/ClineCore.test.ts +150 -0
  168. package/src/ClineCore.ts +114 -8
  169. package/src/account/cline-account-service.test.ts +84 -0
  170. package/src/account/cline-account-service.ts +2 -2
  171. package/src/account/index.ts +1 -0
  172. package/src/account/types.ts +6 -0
  173. package/src/auth/bounded-ttl-cache.test.ts +38 -0
  174. package/src/auth/bounded-ttl-cache.ts +53 -0
  175. package/src/auth/cline.test.ts +173 -36
  176. package/src/auth/cline.ts +395 -93
  177. package/src/auth/oca.test.ts +125 -0
  178. package/src/auth/oca.ts +17 -4
  179. package/src/{agents → extensions/config}/agent-config-loader.test.ts +1 -1
  180. package/src/{agents → extensions/config}/agent-config-parser.ts +2 -2
  181. package/src/{agents → extensions/config}/hooks-config-loader.ts +1 -1
  182. package/src/{agents → extensions/config}/index.ts +7 -11
  183. package/src/{runtime/commands.test.ts → extensions/config/runtime-commands.test.ts} +20 -3
  184. package/src/{runtime/commands.ts → extensions/config/runtime-commands.ts} +1 -8
  185. package/src/{agents → extensions/config}/unified-config-file-watcher.ts +15 -2
  186. package/src/{agents → extensions/config}/user-instruction-config-loader.test.ts +90 -2
  187. package/src/{agents → extensions/config}/user-instruction-config-loader.ts +126 -12
  188. package/src/extensions/context/agentic-compaction.ts +119 -0
  189. package/src/extensions/context/basic-compaction.ts +275 -0
  190. package/src/extensions/context/compaction-shared.ts +458 -0
  191. package/src/extensions/context/compaction.test.ts +477 -0
  192. package/src/extensions/context/compaction.ts +203 -0
  193. package/src/extensions/index.ts +12 -0
  194. package/src/extensions/mcp/client.ts +420 -0
  195. package/src/{mcp → extensions/mcp}/index.ts +16 -0
  196. package/src/{mcp → extensions/mcp}/manager.test.ts +1 -2
  197. package/src/{mcp → extensions/mcp}/manager.ts +3 -5
  198. package/src/extensions/mcp/name-transform.ts +33 -0
  199. package/src/extensions/mcp/policies.ts +47 -0
  200. package/src/extensions/mcp/tools.ts +47 -0
  201. package/src/{mcp → extensions/mcp}/types.ts +35 -7
  202. package/src/{agents → extensions/plugin}/plugin-config-loader.test.ts +18 -13
  203. package/src/{agents → extensions/plugin}/plugin-config-loader.ts +1 -1
  204. package/src/{agents → extensions/plugin}/plugin-loader.test.ts +41 -4
  205. package/src/extensions/plugin/plugin-loader.ts +106 -0
  206. package/src/extensions/plugin/plugin-module-import.ts +278 -0
  207. package/src/{agents → extensions/plugin}/plugin-sandbox-bootstrap.ts +30 -92
  208. package/src/{agents → extensions/plugin}/plugin-sandbox.test.ts +60 -3
  209. package/src/{agents → extensions/plugin}/plugin-sandbox.ts +146 -56
  210. package/src/hooks/index.ts +25 -0
  211. package/src/hooks/persistent.ts +661 -0
  212. package/src/hooks/subprocess-runner.ts +196 -0
  213. package/src/hooks/subprocess.ts +669 -0
  214. package/src/index.ts +200 -118
  215. package/src/prompt/default-system.ts +21 -0
  216. package/src/providers/local-provider-registry.ts +1 -1
  217. package/src/providers/local-provider-service.test.ts +23 -2
  218. package/src/providers/local-provider-service.ts +2 -2
  219. package/src/runtime/checkpoint-hooks.test.ts +167 -0
  220. package/src/runtime/checkpoint-hooks.ts +186 -0
  221. package/src/runtime/hook-file-hooks.test.ts +40 -1
  222. package/src/runtime/hook-file-hooks.ts +35 -16
  223. package/src/runtime/index.ts +4 -19
  224. package/src/runtime/rules.ts +4 -1
  225. package/src/runtime/runtime-builder.team-persistence.test.ts +3 -6
  226. package/src/runtime/runtime-builder.test.ts +266 -160
  227. package/src/runtime/runtime-builder.ts +120 -47
  228. package/src/runtime/runtime-parity.test.ts +22 -22
  229. package/src/runtime/session-runtime.ts +36 -6
  230. package/src/runtime/{sandbox/subprocess-sandbox.ts → subprocess-sandbox.ts} +24 -3
  231. package/src/runtime/team-runtime-registry.ts +1 -4
  232. package/src/runtime/tool-approval.ts +1 -1
  233. package/src/session/default-session-manager.e2e.test.ts +2 -2
  234. package/src/session/default-session-manager.test.ts +553 -9
  235. package/src/session/default-session-manager.ts +140 -46
  236. package/src/session/file-session-service.ts +3 -3
  237. package/src/session/index.ts +6 -6
  238. package/src/session/persistence-service.test.ts +212 -0
  239. package/src/session/{unified-session-persistence-service.ts → persistence-service.ts} +106 -172
  240. package/src/session/rpc-session-service.ts +3 -3
  241. package/src/session/runtime-oauth-token-manager.ts +1 -1
  242. package/src/session/session-agent-events.ts +1 -1
  243. package/src/session/session-artifacts.ts +32 -4
  244. package/src/session/session-config-builder.ts +22 -9
  245. package/src/session/session-graph.ts +1 -1
  246. package/src/session/session-host.ts +19 -11
  247. package/src/session/session-manager.ts +11 -6
  248. package/src/session/session-service.team-persistence.test.ts +1 -1
  249. package/src/session/session-service.ts +6 -9
  250. package/src/session/session-team-coordination.ts +7 -3
  251. package/src/session/session-telemetry.ts +1 -1
  252. package/src/session/utils/helpers.test.ts +160 -0
  253. package/src/session/utils/helpers.ts +289 -42
  254. package/src/session/utils/types.ts +47 -7
  255. package/src/session/workspace-manager.ts +5 -3
  256. package/src/session/workspace-manifest.ts +3 -49
  257. package/src/storage/file-team-store.ts +2 -5
  258. package/src/storage/provider-settings-legacy-migration.ts +2 -2
  259. package/src/storage/provider-settings-manager.test.ts +1 -1
  260. package/src/storage/sqlite-team-store.ts +212 -125
  261. package/src/storage/team-store.ts +1 -5
  262. package/src/team/delegated-agent.ts +131 -0
  263. package/src/team/index.ts +1 -0
  264. package/src/team/multi-agent.lifecycle.test.ts +201 -0
  265. package/src/team/multi-agent.ts +1666 -0
  266. package/src/team/projections.ts +2 -4
  267. package/src/team/runtime.ts +54 -0
  268. package/src/team/spawn-agent-tool.test.ts +387 -0
  269. package/src/team/spawn-agent-tool.ts +207 -0
  270. package/src/team/subagent-prompts.ts +41 -0
  271. package/src/team/team-tools.test.ts +802 -0
  272. package/src/team/team-tools.ts +792 -0
  273. package/src/telemetry/OpenTelemetryProvider.test.ts +25 -3
  274. package/src/telemetry/OpenTelemetryProvider.ts +108 -18
  275. package/src/telemetry/TelemetryLoggerSink.test.ts +42 -0
  276. package/src/telemetry/{LoggerTelemetryAdapter.ts → TelemetryLoggerSink.ts} +21 -14
  277. package/src/telemetry/TelemetryService.test.ts +7 -7
  278. package/src/telemetry/TelemetryService.ts +2 -4
  279. package/src/tools/definitions.test.ts +76 -0
  280. package/src/tools/definitions.ts +41 -2
  281. package/src/tools/executors/apply-patch.ts +1 -1
  282. package/src/tools/executors/editor.ts +1 -1
  283. package/src/tools/executors/file-read.ts +1 -1
  284. package/src/tools/executors/search.ts +1 -1
  285. package/src/tools/executors/web-fetch.ts +1 -1
  286. package/src/tools/index.ts +6 -1
  287. package/src/tools/model-tool-routing.ts +2 -0
  288. package/src/tools/presets.test.ts +8 -0
  289. package/src/tools/presets.ts +40 -2
  290. package/src/tools/schemas.ts +19 -0
  291. package/src/tools/types.ts +31 -2
  292. package/src/types/config.ts +61 -7
  293. package/src/types/events.ts +1 -1
  294. package/src/types/index.ts +0 -1
  295. package/src/types/provider-settings.ts +1 -1
  296. package/src/types/storage.ts +2 -5
  297. package/src/types.ts +32 -44
  298. package/dist/agents/agent-config-loader.d.ts.map +0 -1
  299. package/dist/agents/agent-config-parser.d.ts.map +0 -1
  300. package/dist/agents/hooks-config-loader.d.ts.map +0 -1
  301. package/dist/agents/index.d.ts.map +0 -1
  302. package/dist/agents/plugin-config-loader.d.ts.map +0 -1
  303. package/dist/agents/plugin-loader.d.ts.map +0 -1
  304. package/dist/agents/plugin-sandbox-bootstrap.js +0 -446
  305. package/dist/agents/plugin-sandbox.d.ts.map +0 -1
  306. package/dist/agents/unified-config-file-watcher.d.ts.map +0 -1
  307. package/dist/agents/user-instruction-config-loader.d.ts.map +0 -1
  308. package/dist/mcp/config-loader.d.ts.map +0 -1
  309. package/dist/mcp/index.d.ts +0 -5
  310. package/dist/mcp/index.d.ts.map +0 -1
  311. package/dist/mcp/manager.d.ts.map +0 -1
  312. package/dist/mcp/types.d.ts.map +0 -1
  313. package/dist/runtime/commands.d.ts.map +0 -1
  314. package/dist/runtime/sandbox/subprocess-sandbox.d.ts.map +0 -1
  315. package/dist/runtime/skills.d.ts +0 -14
  316. package/dist/runtime/skills.d.ts.map +0 -1
  317. package/dist/runtime/workflows.d.ts +0 -14
  318. package/dist/runtime/workflows.d.ts.map +0 -1
  319. package/dist/session/unified-session-persistence-service.d.ts.map +0 -1
  320. package/dist/telemetry/LoggerTelemetryAdapter.d.ts.map +0 -1
  321. package/dist/types/workspace.d.ts +0 -8
  322. package/dist/types/workspace.d.ts.map +0 -1
  323. package/src/agents/plugin-loader.ts +0 -175
  324. package/src/runtime/skills.ts +0 -44
  325. package/src/runtime/workflows.test.ts +0 -119
  326. package/src/runtime/workflows.ts +0 -45
  327. package/src/session/unified-session-persistence-service.test.ts +0 -85
  328. package/src/telemetry/LoggerTelemetryAdapter.test.ts +0 -42
  329. package/src/types/workspace.ts +0 -7
  330. /package/dist/{agents → extensions/config}/agent-config-loader.d.ts +0 -0
  331. /package/dist/{agents → extensions/config}/unified-config-file-watcher.d.ts +0 -0
  332. /package/dist/{agents → extensions/config}/user-instruction-config-loader.d.ts +0 -0
  333. /package/dist/{mcp → extensions/mcp}/config-loader.d.ts +0 -0
  334. /package/dist/runtime/{sandbox/subprocess-sandbox.d.ts → subprocess-sandbox.d.ts} +0 -0
  335. /package/src/{agents → extensions/config}/agent-config-loader.ts +0 -0
  336. /package/src/{agents → extensions/config}/hooks-config-loader.test.ts +0 -0
  337. /package/src/{agents → extensions/config}/unified-config-file-watcher.test.ts +0 -0
  338. /package/src/{mcp → extensions/mcp}/config-loader.test.ts +0 -0
  339. /package/src/{mcp → extensions/mcp}/config-loader.ts +0 -0
@@ -0,0 +1,186 @@
1
+ import { execFile as execFileCallback } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import type { AgentHooks, BasicLogger } from "@clinebot/shared";
4
+
5
+ const execFile = promisify(execFileCallback);
6
+
7
+ export interface CheckpointEntry {
8
+ ref: string;
9
+ createdAt: number;
10
+ runCount: number;
11
+ kind?: "stash" | "commit";
12
+ }
13
+
14
+ export interface CheckpointMetadata {
15
+ latest: CheckpointEntry;
16
+ history: CheckpointEntry[];
17
+ }
18
+
19
+ type CreateCheckpointHooksOptions = {
20
+ cwd: string;
21
+ sessionId: string;
22
+ logger?: BasicLogger;
23
+ readSessionMetadata: () => Promise<Record<string, unknown> | undefined>;
24
+ writeSessionMetadata: (
25
+ metadata: Record<string, unknown>,
26
+ ) => Promise<void> | void;
27
+ };
28
+
29
+ function warn(logger: BasicLogger | undefined, message: string): void {
30
+ logger?.log(message, { severity: "warn" });
31
+ }
32
+
33
+ function readCheckpointMetadata(
34
+ metadata: Record<string, unknown> | undefined,
35
+ ): CheckpointMetadata | undefined {
36
+ const candidate = metadata?.checkpoint;
37
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
38
+ return undefined;
39
+ }
40
+ const record = candidate as Partial<CheckpointMetadata>;
41
+ if (!record.latest || !Array.isArray(record.history)) {
42
+ return undefined;
43
+ }
44
+ const latest = record.latest as Partial<CheckpointEntry>;
45
+ const history = record.history.filter(
46
+ (entry): entry is CheckpointEntry =>
47
+ !!entry &&
48
+ typeof entry === "object" &&
49
+ typeof (entry as Partial<CheckpointEntry>).ref === "string" &&
50
+ typeof (entry as Partial<CheckpointEntry>).createdAt === "number" &&
51
+ typeof (entry as Partial<CheckpointEntry>).runCount === "number",
52
+ );
53
+ if (
54
+ typeof latest.ref !== "string" ||
55
+ typeof latest.createdAt !== "number" ||
56
+ typeof latest.runCount !== "number"
57
+ ) {
58
+ return undefined;
59
+ }
60
+ return {
61
+ latest: latest as CheckpointEntry,
62
+ history,
63
+ };
64
+ }
65
+
66
+ async function runGit(
67
+ cwd: string,
68
+ args: string[],
69
+ ): Promise<{ stdout: string; stderr: string }> {
70
+ const result = await execFile("git", ["-C", cwd, ...args], {
71
+ windowsHide: true,
72
+ });
73
+ return {
74
+ stdout: result.stdout.trim(),
75
+ stderr: result.stderr.trim(),
76
+ };
77
+ }
78
+
79
+ export function createCheckpointHooks(
80
+ options: CreateCheckpointHooksOptions,
81
+ ): AgentHooks {
82
+ let runCount = 0;
83
+ let repoSupported: boolean | undefined;
84
+
85
+ const ensureGitRepository = async (): Promise<boolean> => {
86
+ if (repoSupported !== undefined) {
87
+ return repoSupported;
88
+ }
89
+ try {
90
+ const result = await runGit(options.cwd, [
91
+ "rev-parse",
92
+ "--is-inside-work-tree",
93
+ ]);
94
+ repoSupported = result.stdout === "true";
95
+ } catch {
96
+ repoSupported = false;
97
+ }
98
+ return repoSupported;
99
+ };
100
+
101
+ const createCheckpoint = async (): Promise<CheckpointEntry | undefined> => {
102
+ if (!(await ensureGitRepository())) {
103
+ return undefined;
104
+ }
105
+
106
+ const message = `cline checkpoint session=${options.sessionId} run=${runCount}`;
107
+ let ref = "";
108
+ try {
109
+ const result = await runGit(options.cwd, ["stash", "create", message]);
110
+ ref = result.stdout.trim();
111
+ } catch (error) {
112
+ warn(
113
+ options.logger,
114
+ `Checkpoint snapshot failed: ${error instanceof Error ? error.message : String(error)}`,
115
+ );
116
+ return undefined;
117
+ }
118
+ if (!ref) {
119
+ try {
120
+ const result = await runGit(options.cwd, ["rev-parse", "HEAD"]);
121
+ ref = result.stdout.trim();
122
+ } catch (error) {
123
+ warn(
124
+ options.logger,
125
+ `Checkpoint HEAD fallback failed: ${error instanceof Error ? error.message : String(error)}`,
126
+ );
127
+ return undefined;
128
+ }
129
+ if (!ref) {
130
+ return undefined;
131
+ }
132
+ return {
133
+ ref,
134
+ createdAt: Date.now(),
135
+ runCount,
136
+ kind: "commit",
137
+ };
138
+ }
139
+
140
+ try {
141
+ await runGit(options.cwd, ["stash", "store", "-m", message, ref]);
142
+ } catch (error) {
143
+ warn(
144
+ options.logger,
145
+ `Checkpoint store failed: ${error instanceof Error ? error.message : String(error)}`,
146
+ );
147
+ return undefined;
148
+ }
149
+
150
+ return {
151
+ ref,
152
+ createdAt: Date.now(),
153
+ runCount,
154
+ kind: "stash",
155
+ };
156
+ };
157
+
158
+ return {
159
+ onRunStart: async ({ parentAgentId }) => {
160
+ if (parentAgentId === null) {
161
+ runCount += 1;
162
+ }
163
+ return undefined;
164
+ },
165
+ onBeforeAgentStart: async ({ parentAgentId, iteration }) => {
166
+ if (parentAgentId !== null || iteration !== 1 || runCount < 1) {
167
+ return undefined;
168
+ }
169
+ const entry = await createCheckpoint();
170
+ if (!entry) {
171
+ return undefined;
172
+ }
173
+ const metadata = await options.readSessionMetadata();
174
+ const existing = readCheckpointMetadata(metadata);
175
+ const history = [...(existing?.history ?? []), entry];
176
+ await options.writeSessionMetadata({
177
+ ...(metadata ?? {}),
178
+ checkpoint: {
179
+ latest: entry,
180
+ history,
181
+ } satisfies CheckpointMetadata,
182
+ });
183
+ return undefined;
184
+ },
185
+ };
186
+ }
@@ -2,7 +2,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { describe, expect, it } from "vitest";
5
- import { createHookConfigFileHooks } from "./hook-file-hooks";
5
+ import { createHookConfigFileHooks, mergeAgentHooks } from "./hook-file-hooks";
6
6
 
7
7
  async function waitForFile(
8
8
  filePath: string,
@@ -234,4 +234,43 @@ describe("createHookConfigFileHooks", () => {
234
234
  await rm(workspace, { recursive: true, force: true });
235
235
  }
236
236
  });
237
+
238
+ it("merges before-agent-start controls across hook layers", async () => {
239
+ const hooks = mergeAgentHooks([
240
+ {
241
+ onBeforeAgentStart: async () => ({
242
+ systemPrompt: "system-a",
243
+ }),
244
+ },
245
+ {
246
+ onBeforeAgentStart: async () => ({
247
+ appendMessages: [
248
+ {
249
+ role: "user",
250
+ content: [{ type: "text", text: "ctx-a" }],
251
+ },
252
+ ],
253
+ }),
254
+ },
255
+ ]);
256
+
257
+ const control = await hooks?.onBeforeAgentStart?.({
258
+ agentId: "agent_1",
259
+ conversationId: "conv_1",
260
+ parentAgentId: null,
261
+ iteration: 1,
262
+ systemPrompt: "base",
263
+ messages: [],
264
+ });
265
+
266
+ expect(control).toMatchObject({
267
+ systemPrompt: "system-a",
268
+ appendMessages: [
269
+ {
270
+ role: "user",
271
+ content: [{ type: "text", text: "ctx-a" }],
272
+ },
273
+ ],
274
+ });
275
+ });
237
276
  });
@@ -1,13 +1,15 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { appendFileSync, readFileSync } from "node:fs";
3
- import type {
4
- AgentHooks,
5
- HookEventName,
6
- HookEventPayload,
7
- } from "@clinebot/agents";
8
- import type { BasicLogger, HookSessionContext } from "@clinebot/shared";
3
+ import type { AgentHooks } from "@clinebot/agents";
4
+ import {
5
+ augmentNodeCommandForDebug,
6
+ type BasicLogger,
7
+ type HookSessionContext,
8
+ withResolvedClineBuildEnv,
9
+ } from "@clinebot/shared";
9
10
  import { ensureParentDir } from "@clinebot/shared/storage";
10
- import { listHookConfigFiles } from "../agents/hooks-config-loader";
11
+ import { listHookConfigFiles } from "../extensions/config/hooks-config-loader";
12
+ import type { HookEventName, HookEventPayload } from "../hooks";
11
13
 
12
14
  type HookContextBase = {
13
15
  agentId: string;
@@ -64,8 +66,15 @@ function logHookError(
64
66
  ): void {
65
67
  const detail = error instanceof Error ? `: ${error.message}` : "";
66
68
  const text = `${message}${detail}`;
67
- if (logger?.warn) {
68
- logger.warn(text);
69
+ if (logger) {
70
+ try {
71
+ logger.log(text, {
72
+ severity: "warn",
73
+ ...(error !== undefined ? { error } : {}),
74
+ });
75
+ } catch {
76
+ // Logging failures must not break hook execution.
77
+ }
69
78
  return;
70
79
  }
71
80
  console.warn(text);
@@ -264,9 +273,13 @@ async function runHookCommand(
264
273
  if (options.command.length === 0) {
265
274
  throw new Error("runHookCommand requires non-empty command");
266
275
  }
267
- const child = spawn(options.command[0], options.command.slice(1), {
268
- cwd: options.cwd,
276
+ const command = augmentNodeCommandForDebug(options.command, {
269
277
  env: options.env,
278
+ debugRole: "hook-worker",
279
+ });
280
+ const child = spawn(command[0], command.slice(1), {
281
+ cwd: options.cwd,
282
+ env: withResolvedClineBuildEnv(options.env),
270
283
  stdio: options.detached
271
284
  ? ["pipe", "ignore", "ignore"]
272
285
  : ["pipe", "pipe", "pipe"],
@@ -386,7 +399,9 @@ function inferHookCommand(path: string): string[] {
386
399
  lowered.endsWith(".mjs") ||
387
400
  lowered.endsWith(".cjs")
388
401
  ) {
389
- return ["node", path];
402
+ return augmentNodeCommandForDebug(["node", path], {
403
+ debugRole: "hook-worker",
404
+ });
390
405
  }
391
406
  if (
392
407
  lowered.endsWith(".ts") ||
@@ -415,9 +430,10 @@ function createHookCommandMap(workspacePath: string): HookCommandMap {
415
430
  if (!file.hookEventName) {
416
431
  continue;
417
432
  }
418
- const existing = map[file.hookEventName] ?? [];
433
+ const hookEventName = file.hookEventName;
434
+ const existing = map[hookEventName] ?? [];
419
435
  existing.push(inferHookCommand(file.path));
420
- map[file.hookEventName] = existing;
436
+ map[hookEventName] = existing;
421
437
  }
422
438
  return map;
423
439
  }
@@ -436,7 +452,7 @@ async function runBlockingHookCommands(options: {
436
452
  const result = await runHookCommand(options.payload, {
437
453
  command,
438
454
  cwd: options.cwd,
439
- env: process.env,
455
+ env: withResolvedClineBuildEnv(process.env),
440
456
  detached: false,
441
457
  timeoutMs: options.timeoutMs,
442
458
  });
@@ -474,7 +490,7 @@ function runAsyncHookCommands(options: {
474
490
  void runHookCommand(options.payload, {
475
491
  command,
476
492
  cwd: options.cwd,
477
- env: process.env,
493
+ env: withResolvedClineBuildEnv(process.env),
478
494
  detached: true,
479
495
  }).catch((error) => {
480
496
  logHookError(
@@ -845,12 +861,15 @@ export function mergeAgentHooks(
845
861
  }
846
862
 
847
863
  return {
864
+ onSessionStart: mergeHookFunction(activeLayers, "onSessionStart"),
848
865
  onRunStart: mergeHookFunction(activeLayers, "onRunStart"),
849
866
  onRunEnd: mergeHookFunction(activeLayers, "onRunEnd"),
850
867
  onIterationStart: mergeHookFunction(activeLayers, "onIterationStart"),
851
868
  onIterationEnd: mergeHookFunction(activeLayers, "onIterationEnd"),
852
869
  onTurnStart: mergeHookFunction(activeLayers, "onTurnStart"),
870
+ onBeforeAgentStart: mergeHookFunction(activeLayers, "onBeforeAgentStart"),
853
871
  onTurnEnd: mergeHookFunction(activeLayers, "onTurnEnd"),
872
+ onStopError: mergeHookFunction(activeLayers, "onStopError"),
854
873
  onToolCallStart: mergeHookFunction(activeLayers, "onToolCallStart"),
855
874
  onToolCallEnd: mergeHookFunction(activeLayers, "onToolCallEnd"),
856
875
  onSessionShutdown: mergeHookFunction(activeLayers, "onSessionShutdown"),
@@ -1,8 +1,3 @@
1
- export {
2
- type AvailableRuntimeCommand,
3
- listAvailableRuntimeCommandsFromWatcher,
4
- resolveRuntimeSlashCommandFromWatcher,
5
- } from "./commands";
6
1
  export {
7
2
  formatRulesForSystemPrompt,
8
3
  isRuleEnabled,
@@ -10,11 +5,6 @@ export {
10
5
  loadRulesForSystemPromptFromWatcher,
11
6
  } from "./rules";
12
7
  export { createTeamName, DefaultRuntimeBuilder } from "./runtime-builder";
13
- export {
14
- type SandboxCallOptions,
15
- SubprocessSandbox,
16
- type SubprocessSandboxOptions,
17
- } from "./sandbox/subprocess-sandbox";
18
8
  export type {
19
9
  BuiltRuntime,
20
10
  RuntimeBuilder,
@@ -22,16 +12,11 @@ export type {
22
12
  SessionRuntime,
23
13
  } from "./session-runtime";
24
14
  export {
25
- type AvailableSkill,
26
- listAvailableSkillsFromWatcher,
27
- resolveSkillsSlashCommandFromWatcher,
28
- } from "./skills";
15
+ type SandboxCallOptions,
16
+ SubprocessSandbox,
17
+ type SubprocessSandboxOptions,
18
+ } from "./subprocess-sandbox";
29
19
  export {
30
20
  type DesktopToolApprovalOptions,
31
21
  requestDesktopToolApproval,
32
22
  } from "./tool-approval";
33
- export {
34
- type AvailableWorkflow,
35
- listAvailableWorkflowsFromWatcher,
36
- resolveWorkflowSlashCommandFromWatcher,
37
- } from "./workflows";
@@ -1,4 +1,7 @@
1
- import type { RuleConfig, UserInstructionConfigWatcher } from "../agents";
1
+ import type {
2
+ RuleConfig,
3
+ UserInstructionConfigWatcher,
4
+ } from "../extensions/config";
2
5
 
3
6
  export function isRuleEnabled(rule: RuleConfig): boolean {
4
7
  return rule.disabled !== true;
@@ -35,7 +35,7 @@ class MockAgentTeamsRuntime {
35
35
  shutdownTeammate = vi.fn();
36
36
  }
37
37
 
38
- vi.mock("@clinebot/agents", () => ({
38
+ vi.mock("../team", () => ({
39
39
  AgentTeamsRuntime: MockAgentTeamsRuntime,
40
40
  bootstrapAgentTeams: bootstrapAgentTeamsMock,
41
41
  createDelegatedAgentConfigProvider: (config: Record<string, unknown>) => {
@@ -109,7 +109,7 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
109
109
  const { DefaultRuntimeBuilder } = await import("./runtime-builder");
110
110
  const onTeamRestored = vi.fn();
111
111
 
112
- new DefaultRuntimeBuilder().build({
112
+ await new DefaultRuntimeBuilder().build({
113
113
  config: {
114
114
  providerId: "anthropic",
115
115
  modelId: "claude-sonnet-4-6",
@@ -194,7 +194,7 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
194
194
  const { DefaultRuntimeBuilder } = await import("./runtime-builder");
195
195
  bootstrapAgentTeamsMock.mockClear();
196
196
 
197
- new DefaultRuntimeBuilder().build({
197
+ await new DefaultRuntimeBuilder().build({
198
198
  config: {
199
199
  providerId: "cline",
200
200
  modelId: "anthropic/claude-sonnet-4.6",
@@ -236,9 +236,6 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
236
236
  expect.objectContaining({
237
237
  providerId: "cline",
238
238
  cwd: "/repo/demo",
239
- clineWorkspaceMetadata: expect.stringContaining(
240
- "# Workspace Configuration",
241
- ),
242
239
  }),
243
240
  );
244
241
  });