@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,669 @@
1
+ import {
2
+ type AgentHooks,
3
+ type HookSessionContext,
4
+ type HookSessionContextProvider,
5
+ resolveHookSessionContext,
6
+ type ToolCallRecord,
7
+ } from "@clinebot/shared";
8
+ import { z } from "zod";
9
+ import {
10
+ type RunSubprocessEventResult,
11
+ runSubprocessEvent,
12
+ } from "./subprocess-runner";
13
+
14
+ type AgentHookControl = NonNullable<
15
+ Awaited<ReturnType<NonNullable<AgentHooks["onToolCallStart"]>>>
16
+ >;
17
+ type AgentHookRunStartContext = Parameters<
18
+ NonNullable<AgentHooks["onRunStart"]>
19
+ >[0];
20
+ type AgentHookSessionShutdownContext = Parameters<
21
+ NonNullable<AgentHooks["onSessionShutdown"]>
22
+ >[0];
23
+ type AgentHookStopErrorContext = Parameters<
24
+ NonNullable<AgentHooks["onStopError"]>
25
+ >[0];
26
+ type AgentHookToolCallEndContext = Parameters<
27
+ NonNullable<AgentHooks["onToolCallEnd"]>
28
+ >[0];
29
+ type AgentHookToolCallStartContext = Parameters<
30
+ NonNullable<AgentHooks["onToolCallStart"]>
31
+ >[0];
32
+ type AgentHookTurnEndContext = Parameters<
33
+ NonNullable<AgentHooks["onTurnEnd"]>
34
+ >[0];
35
+
36
+ export const HookEventNameSchema = z.enum([
37
+ "agent_start",
38
+ "agent_resume",
39
+ "agent_abort",
40
+ "agent_end",
41
+ "agent_error",
42
+ "tool_call",
43
+ "tool_result",
44
+ "prompt_submit",
45
+ "pre_compact",
46
+ "session_shutdown",
47
+ ]);
48
+
49
+ export type HookEventName = z.infer<typeof HookEventNameSchema>;
50
+
51
+ const StringMapSchema = z.record(z.string(), z.string());
52
+
53
+ export interface HookOutput {
54
+ contextModification: string;
55
+ cancel: boolean;
56
+ review?: boolean;
57
+ errorMessage: string;
58
+ }
59
+
60
+ export const HookOutputSchema = z
61
+ .object({
62
+ contextModification: z.string().optional(),
63
+ cancel: z.boolean().optional(),
64
+ review: z.boolean().optional(),
65
+ errorMessage: z.string().optional(),
66
+ context: z.string().optional(),
67
+ overrideInput: z.unknown().optional(),
68
+ })
69
+ .passthrough();
70
+
71
+ export interface PreToolUseData {
72
+ toolName: string;
73
+ parameters: Record<string, string>;
74
+ }
75
+
76
+ export interface PostToolUseData {
77
+ toolName: string;
78
+ parameters: Record<string, string>;
79
+ result: string;
80
+ success: boolean;
81
+ executionTimeMs: number;
82
+ }
83
+
84
+ export interface UserPromptSubmitData {
85
+ prompt: string;
86
+ attachments: string[];
87
+ }
88
+
89
+ export interface TaskStartData {
90
+ taskMetadata: Record<string, string>;
91
+ }
92
+
93
+ export interface TaskResumeData {
94
+ taskMetadata: Record<string, string>;
95
+ previousState: Record<string, string>;
96
+ }
97
+
98
+ export interface TaskCancelData {
99
+ taskMetadata: Record<string, string>;
100
+ }
101
+
102
+ export interface TaskCompleteData {
103
+ taskMetadata: Record<string, string>;
104
+ }
105
+
106
+ export interface PreCompactData {
107
+ taskId: string;
108
+ ulid: string;
109
+ contextSize: number;
110
+ compactionStrategy: string;
111
+ previousApiReqIndex: number;
112
+ tokensIn: number;
113
+ tokensOut: number;
114
+ tokensInCache: number;
115
+ tokensOutCache: number;
116
+ deletedRangeStart: number;
117
+ deletedRangeEnd: number;
118
+ contextJsonPath: string;
119
+ contextRawPath: string;
120
+ }
121
+
122
+ const PreToolUseDataSchema = z.object({
123
+ toolName: z.string(),
124
+ parameters: StringMapSchema,
125
+ });
126
+
127
+ const PostToolUseDataSchema = z.object({
128
+ toolName: z.string(),
129
+ parameters: StringMapSchema,
130
+ result: z.string(),
131
+ success: z.boolean(),
132
+ executionTimeMs: z.number(),
133
+ });
134
+
135
+ const UserPromptSubmitDataSchema = z.object({
136
+ prompt: z.string(),
137
+ attachments: z.array(z.string()),
138
+ });
139
+
140
+ const TaskStartDataSchema = z.object({ taskMetadata: StringMapSchema });
141
+ const TaskResumeDataSchema = z.object({
142
+ taskMetadata: StringMapSchema,
143
+ previousState: StringMapSchema,
144
+ });
145
+ const TaskCancelDataSchema = z.object({ taskMetadata: StringMapSchema });
146
+ const TaskCompleteDataSchema = z.object({ taskMetadata: StringMapSchema });
147
+
148
+ const PreCompactDataSchema = z.object({
149
+ taskId: z.string(),
150
+ ulid: z.string(),
151
+ contextSize: z.number(),
152
+ compactionStrategy: z.string(),
153
+ previousApiReqIndex: z.number(),
154
+ tokensIn: z.number(),
155
+ tokensOut: z.number(),
156
+ tokensInCache: z.number(),
157
+ tokensOutCache: z.number(),
158
+ deletedRangeStart: z.number(),
159
+ deletedRangeEnd: z.number(),
160
+ contextJsonPath: z.string(),
161
+ contextRawPath: z.string(),
162
+ });
163
+
164
+ export interface HookEventPayloadBase {
165
+ clineVersion: string;
166
+ hookName: HookEventName;
167
+ timestamp: string;
168
+ taskId: string;
169
+ sessionContext?: HookSessionContext;
170
+ workspaceRoots: string[];
171
+ userId: string;
172
+ agent_id: string;
173
+ parent_agent_id: string | null;
174
+ preToolUse?: PreToolUseData | undefined;
175
+ postToolUse?: PostToolUseData | undefined;
176
+ userPromptSubmit?: UserPromptSubmitData | undefined;
177
+ taskStart?: TaskStartData | undefined;
178
+ taskResume?: TaskResumeData | undefined;
179
+ taskCancel?: TaskCancelData | undefined;
180
+ taskComplete?: TaskCompleteData | undefined;
181
+ preCompact?: PreCompactData | undefined;
182
+ }
183
+
184
+ export interface ToolCallHookPayload extends HookEventPayloadBase {
185
+ hookName: "tool_call";
186
+ iteration: number;
187
+ tool_call: {
188
+ id: string;
189
+ name: string;
190
+ input: unknown;
191
+ };
192
+ }
193
+
194
+ export interface ToolResultHookPayload extends HookEventPayloadBase {
195
+ hookName: "tool_result";
196
+ iteration: number;
197
+ tool_result: ToolCallRecord;
198
+ }
199
+
200
+ export interface AgentEndHookPayload extends HookEventPayloadBase {
201
+ hookName: "agent_end";
202
+ iteration: number;
203
+ turn: AgentHookTurnEndContext["turn"];
204
+ }
205
+
206
+ export interface AgentErrorHookPayload extends HookEventPayloadBase {
207
+ hookName: "agent_error";
208
+ iteration: number;
209
+ error: {
210
+ name: string;
211
+ message: string;
212
+ stack?: string;
213
+ };
214
+ }
215
+
216
+ export interface AgentStartHookPayload extends HookEventPayloadBase {
217
+ hookName: "agent_start";
218
+ }
219
+
220
+ export interface AgentResumeHookPayload extends HookEventPayloadBase {
221
+ hookName: "agent_resume";
222
+ }
223
+
224
+ export interface AgentAbortHookPayload extends HookEventPayloadBase {
225
+ hookName: "agent_abort";
226
+ reason?: string;
227
+ }
228
+
229
+ export interface PromptSubmitHookPayload extends HookEventPayloadBase {
230
+ hookName: "prompt_submit";
231
+ }
232
+
233
+ export interface PreCompactHookPayload extends HookEventPayloadBase {
234
+ hookName: "pre_compact";
235
+ preCompact: PreCompactData;
236
+ }
237
+
238
+ export interface SessionShutdownHookPayload extends HookEventPayloadBase {
239
+ hookName: "session_shutdown";
240
+ reason?: string;
241
+ }
242
+
243
+ export type HookEventPayload =
244
+ | ToolCallHookPayload
245
+ | ToolResultHookPayload
246
+ | AgentStartHookPayload
247
+ | AgentResumeHookPayload
248
+ | AgentAbortHookPayload
249
+ | PromptSubmitHookPayload
250
+ | PreCompactHookPayload
251
+ | AgentEndHookPayload
252
+ | AgentErrorHookPayload
253
+ | SessionShutdownHookPayload;
254
+
255
+ export const HookEventPayloadSchema: z.ZodType<any> = z
256
+ .object({
257
+ clineVersion: z.string(),
258
+ hookName: HookEventNameSchema,
259
+ timestamp: z.string(),
260
+ taskId: z.string(),
261
+ sessionContext: z
262
+ .object({
263
+ rootSessionId: z.string().optional(),
264
+ hookLogPath: z.string().optional(),
265
+ })
266
+ .optional(),
267
+ workspaceRoots: z.array(z.string()),
268
+ userId: z.string(),
269
+ agent_id: z.string(),
270
+ parent_agent_id: z.string().nullable(),
271
+ iteration: z.number().optional(),
272
+ reason: z.string().optional(),
273
+ tool_call: z
274
+ .object({
275
+ id: z.string(),
276
+ name: z.string(),
277
+ input: z.unknown(),
278
+ })
279
+ .optional(),
280
+ tool_result: z.custom<ToolCallRecord>().optional(),
281
+ turn: z.custom<AgentHookTurnEndContext["turn"]>().optional(),
282
+ error: z
283
+ .object({
284
+ name: z.string(),
285
+ message: z.string(),
286
+ stack: z.string().optional(),
287
+ })
288
+ .optional(),
289
+ preToolUse: PreToolUseDataSchema.optional(),
290
+ postToolUse: PostToolUseDataSchema.optional(),
291
+ userPromptSubmit: UserPromptSubmitDataSchema.optional(),
292
+ taskStart: TaskStartDataSchema.optional(),
293
+ taskResume: TaskResumeDataSchema.optional(),
294
+ taskCancel: TaskCancelDataSchema.optional(),
295
+ taskComplete: TaskCompleteDataSchema.optional(),
296
+ preCompact: PreCompactDataSchema.optional(),
297
+ })
298
+ .passthrough();
299
+
300
+ export function parseHookEventPayload(
301
+ value: unknown,
302
+ ): HookEventPayload | undefined {
303
+ const parsed = HookEventPayloadSchema.safeParse(value);
304
+ if (!parsed.success) {
305
+ return undefined;
306
+ }
307
+ return parsed.data as HookEventPayload;
308
+ }
309
+
310
+ export interface RunHookOptions {
311
+ command?: string[];
312
+ cwd?: string;
313
+ env?: NodeJS.ProcessEnv;
314
+ detached?: boolean;
315
+ timeoutMs?: number;
316
+ onSpawn?: (event: {
317
+ command: string[];
318
+ pid?: number;
319
+ detached: boolean;
320
+ }) => void;
321
+ }
322
+
323
+ export type RunHookResult = RunSubprocessEventResult;
324
+
325
+ const DEFAULT_HOOK_COMMAND = ["agent", "hook"];
326
+
327
+ export async function runHook(
328
+ payload: HookEventPayload,
329
+ options: RunHookOptions = {},
330
+ ): Promise<RunHookResult | undefined> {
331
+ const command = options.command ?? DEFAULT_HOOK_COMMAND;
332
+ return await runSubprocessEvent(payload, {
333
+ command,
334
+ cwd: options.cwd,
335
+ env: options.env,
336
+ detached: options.detached,
337
+ timeoutMs: options.timeoutMs,
338
+ onSpawn: options.onSpawn,
339
+ });
340
+ }
341
+
342
+ export interface SubprocessHooksOptions {
343
+ command?: string[];
344
+ cwd?: string;
345
+ env?: NodeJS.ProcessEnv;
346
+ timeoutMs?: number;
347
+ onDispatchError?: (error: Error, payload: HookEventPayload) => void;
348
+ onDispatch?: (event: {
349
+ payload: HookEventPayload;
350
+ result?: RunHookResult;
351
+ detached: boolean;
352
+ }) => void;
353
+ onSpawn?: (event: {
354
+ command: string[];
355
+ pid?: number;
356
+ detached: boolean;
357
+ }) => void;
358
+ sessionContext?: HookSessionContextProvider;
359
+ }
360
+
361
+ export interface SubprocessHookControl {
362
+ hooks: AgentHooks;
363
+ shutdown: (ctx: {
364
+ agentId: string;
365
+ conversationId: string;
366
+ parentAgentId: string | null;
367
+ reason?: string;
368
+ }) => Promise<void>;
369
+ }
370
+
371
+ function toError(error: unknown): Error {
372
+ return error instanceof Error ? error : new Error(String(error));
373
+ }
374
+
375
+ function toHookControl(value: unknown): AgentHookControl | undefined {
376
+ if (!value || typeof value !== "object") {
377
+ return undefined;
378
+ }
379
+ const parsed = HookOutputSchema.safeParse(value);
380
+ if (!parsed.success) {
381
+ return undefined;
382
+ }
383
+ const maybe = parsed.data;
384
+ const hasControlKey =
385
+ "cancel" in maybe ||
386
+ "review" in maybe ||
387
+ "context" in maybe ||
388
+ "contextModification" in maybe ||
389
+ "overrideInput" in maybe ||
390
+ "errorMessage" in maybe;
391
+ if (!hasControlKey) {
392
+ return undefined;
393
+ }
394
+ const contextFromHook =
395
+ typeof maybe.context === "string"
396
+ ? maybe.context
397
+ : typeof maybe.contextModification === "string"
398
+ ? maybe.contextModification
399
+ : typeof maybe.errorMessage === "string" &&
400
+ maybe.errorMessage.length > 0
401
+ ? maybe.errorMessage
402
+ : undefined;
403
+ return {
404
+ cancel: typeof maybe.cancel === "boolean" ? maybe.cancel : undefined,
405
+ review: typeof maybe.review === "boolean" ? maybe.review : undefined,
406
+ context: contextFromHook,
407
+ overrideInput: Object.hasOwn(maybe, "overrideInput")
408
+ ? maybe.overrideInput
409
+ : undefined,
410
+ };
411
+ }
412
+
413
+ function mapParams(input: unknown): Record<string, string> {
414
+ if (!input || typeof input !== "object") {
415
+ return {};
416
+ }
417
+ const output: Record<string, string> = {};
418
+ for (const [key, value] of Object.entries(input as Record<string, unknown>)) {
419
+ if (typeof value === "string") {
420
+ output[key] = value;
421
+ } else {
422
+ output[key] = JSON.stringify(value);
423
+ }
424
+ }
425
+ return output;
426
+ }
427
+
428
+ function basePayload(
429
+ hookName: HookEventName,
430
+ ctx: {
431
+ agentId: string;
432
+ conversationId: string;
433
+ parentAgentId: string | null;
434
+ },
435
+ options: SubprocessHooksOptions,
436
+ ): HookEventPayloadBase {
437
+ const env = options.env ?? process.env;
438
+ const userId = env.CLINE_USER_ID?.trim() || env.USER?.trim() || "unknown";
439
+ const workspaceRoot = options.cwd || process.cwd();
440
+ return {
441
+ clineVersion: env.CLINE_VERSION?.trim() || "",
442
+ hookName,
443
+ timestamp: new Date().toISOString(),
444
+ taskId: ctx.conversationId,
445
+ sessionContext: resolveHookSessionContext(options.sessionContext, {
446
+ hookName,
447
+ conversationId: ctx.conversationId,
448
+ agentId: ctx.agentId,
449
+ parentAgentId: ctx.parentAgentId,
450
+ }),
451
+ workspaceRoots: workspaceRoot ? [workspaceRoot] : [],
452
+ userId,
453
+ agent_id: ctx.agentId,
454
+ parent_agent_id: ctx.parentAgentId,
455
+ };
456
+ }
457
+
458
+ function serializeHookError(error: Error): AgentErrorHookPayload["error"] {
459
+ return {
460
+ name: error.name,
461
+ message: error.message,
462
+ stack: error.stack,
463
+ };
464
+ }
465
+
466
+ function isAbortReason(reason?: string): boolean {
467
+ const value = String(reason ?? "").toLowerCase();
468
+ return (
469
+ value.includes("cancel") ||
470
+ value.includes("abort") ||
471
+ value.includes("interrupt")
472
+ );
473
+ }
474
+
475
+ async function dispatchDetached(
476
+ payload: HookEventPayload,
477
+ options: SubprocessHooksOptions,
478
+ ): Promise<void> {
479
+ try {
480
+ const result = await runHook(payload, {
481
+ command: options.command,
482
+ cwd: options.cwd,
483
+ env: options.env,
484
+ detached: true,
485
+ onSpawn: options.onSpawn,
486
+ });
487
+ options.onDispatch?.({ payload, result, detached: true });
488
+ } catch (error) {
489
+ options.onDispatchError?.(toError(error), payload);
490
+ }
491
+ }
492
+
493
+ export function createSubprocessHooks(
494
+ options: SubprocessHooksOptions = {},
495
+ ): SubprocessHookControl {
496
+ const onRunStart = async (
497
+ ctx: AgentHookRunStartContext,
498
+ ): Promise<AgentHookControl | undefined> => {
499
+ const isResume =
500
+ (options.env ?? process.env).CLINE_HOOK_AGENT_RESUME === "1";
501
+ if (isResume) {
502
+ const resumePayload: AgentResumeHookPayload = {
503
+ ...basePayload("agent_resume", ctx, options),
504
+ hookName: "agent_resume",
505
+ taskResume: {
506
+ taskMetadata: {},
507
+ previousState: {},
508
+ },
509
+ };
510
+ await dispatchDetached(resumePayload, options);
511
+ } else {
512
+ const startPayload: AgentStartHookPayload = {
513
+ ...basePayload("agent_start", ctx, options),
514
+ hookName: "agent_start",
515
+ taskStart: { taskMetadata: {} },
516
+ };
517
+ await dispatchDetached(startPayload, options);
518
+ }
519
+
520
+ const promptPayload: PromptSubmitHookPayload = {
521
+ ...basePayload("prompt_submit", ctx, options),
522
+ hookName: "prompt_submit",
523
+ userPromptSubmit: {
524
+ prompt: ctx.userMessage,
525
+ attachments: [],
526
+ },
527
+ };
528
+ await dispatchDetached(promptPayload, options);
529
+ return undefined;
530
+ };
531
+
532
+ const onToolCallStart = async (
533
+ ctx: AgentHookToolCallStartContext,
534
+ ): Promise<AgentHookControl | undefined> => {
535
+ const payload: ToolCallHookPayload = {
536
+ ...basePayload("tool_call", ctx, options),
537
+ hookName: "tool_call",
538
+ iteration: ctx.iteration,
539
+ tool_call: {
540
+ id: ctx.call.id,
541
+ name: ctx.call.name,
542
+ input: ctx.call.input,
543
+ },
544
+ preToolUse: {
545
+ toolName: ctx.call.name,
546
+ parameters: mapParams(ctx.call.input),
547
+ },
548
+ };
549
+
550
+ try {
551
+ const result = await runHook(payload, {
552
+ command: options.command,
553
+ cwd: options.cwd,
554
+ env: options.env,
555
+ detached: false,
556
+ timeoutMs: options.timeoutMs,
557
+ onSpawn: options.onSpawn,
558
+ });
559
+ options.onDispatch?.({ payload, result, detached: false });
560
+ if (result?.timedOut) {
561
+ throw new Error("tool_call hook command timed out");
562
+ }
563
+ if (result?.parseError) {
564
+ throw new Error(
565
+ `tool_call hook produced invalid control JSON: ${result.parseError}`,
566
+ );
567
+ }
568
+ return toHookControl(result?.parsedJson);
569
+ } catch (error) {
570
+ options.onDispatchError?.(toError(error), payload);
571
+ return;
572
+ }
573
+ };
574
+
575
+ const onToolCallEnd = async (
576
+ ctx: AgentHookToolCallEndContext,
577
+ ): Promise<AgentHookControl | undefined> => {
578
+ const payload: ToolResultHookPayload = {
579
+ ...basePayload("tool_result", ctx, options),
580
+ hookName: "tool_result",
581
+ iteration: ctx.iteration,
582
+ tool_result: ctx.record,
583
+ postToolUse: {
584
+ toolName: ctx.record.name,
585
+ parameters: mapParams(ctx.record.input),
586
+ result:
587
+ typeof ctx.record.output === "string"
588
+ ? ctx.record.output
589
+ : JSON.stringify(ctx.record.output),
590
+ success: !ctx.record.error,
591
+ executionTimeMs: ctx.record.durationMs,
592
+ },
593
+ };
594
+ await dispatchDetached(payload, options);
595
+ return undefined;
596
+ };
597
+
598
+ const onTurnEnd = async (
599
+ ctx: AgentHookTurnEndContext,
600
+ ): Promise<AgentHookControl | undefined> => {
601
+ const payload: AgentEndHookPayload = {
602
+ ...basePayload("agent_end", ctx, options),
603
+ hookName: "agent_end",
604
+ iteration: ctx.iteration,
605
+ turn: ctx.turn,
606
+ taskComplete: { taskMetadata: {} },
607
+ };
608
+ await dispatchDetached(payload, options);
609
+ return undefined;
610
+ };
611
+
612
+ const onStopError = async (
613
+ ctx: AgentHookStopErrorContext,
614
+ ): Promise<AgentHookControl | undefined> => {
615
+ const hookName: HookEventName = isAbortReason(ctx.error.message)
616
+ ? "agent_abort"
617
+ : "agent_error";
618
+ const payload: AgentErrorHookPayload | AgentAbortHookPayload =
619
+ hookName === "agent_error"
620
+ ? {
621
+ ...basePayload(hookName, ctx, options),
622
+ hookName,
623
+ iteration: ctx.iteration,
624
+ error: serializeHookError(ctx.error),
625
+ taskCancel: { taskMetadata: {} },
626
+ }
627
+ : {
628
+ ...basePayload(hookName, ctx, options),
629
+ hookName,
630
+ reason: ctx.error.message,
631
+ taskCancel: { taskMetadata: {} },
632
+ };
633
+ await dispatchDetached(payload, options);
634
+ return undefined;
635
+ };
636
+
637
+ const shutdown = async ({
638
+ agentId,
639
+ conversationId,
640
+ parentAgentId,
641
+ reason,
642
+ }: AgentHookSessionShutdownContext): Promise<void> => {
643
+ const payload: SessionShutdownHookPayload = {
644
+ ...basePayload(
645
+ "session_shutdown",
646
+ {
647
+ agentId,
648
+ conversationId,
649
+ parentAgentId,
650
+ },
651
+ options,
652
+ ),
653
+ hookName: "session_shutdown",
654
+ reason,
655
+ };
656
+ await dispatchDetached(payload, options);
657
+ };
658
+
659
+ return {
660
+ hooks: {
661
+ onRunStart,
662
+ onToolCallStart,
663
+ onToolCallEnd,
664
+ onTurnEnd,
665
+ onStopError,
666
+ },
667
+ shutdown,
668
+ };
669
+ }