@clinebot/core 0.0.36 → 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 (228) hide show
  1. package/dist/ClineCore.d.ts +312 -3
  2. package/dist/ClineCore.d.ts.map +1 -1
  3. package/dist/account/cline-account-service.d.ts.map +1 -1
  4. package/dist/cron/cron-event-ingress.d.ts +38 -0
  5. package/dist/cron/cron-event-ingress.d.ts.map +1 -0
  6. package/dist/cron/cron-materializer.d.ts +36 -0
  7. package/dist/cron/cron-materializer.d.ts.map +1 -0
  8. package/dist/cron/cron-reconciler.d.ts +62 -0
  9. package/dist/cron/cron-reconciler.d.ts.map +1 -0
  10. package/dist/cron/cron-report-writer.d.ts +41 -0
  11. package/dist/cron/cron-report-writer.d.ts.map +1 -0
  12. package/dist/cron/cron-runner.d.ts +43 -0
  13. package/dist/cron/cron-runner.d.ts.map +1 -0
  14. package/dist/cron/cron-schema.d.ts +3 -0
  15. package/dist/cron/cron-schema.d.ts.map +1 -0
  16. package/dist/cron/cron-service.d.ts +57 -0
  17. package/dist/cron/cron-service.d.ts.map +1 -0
  18. package/dist/cron/cron-spec-parser.d.ts +27 -0
  19. package/dist/cron/cron-spec-parser.d.ts.map +1 -0
  20. package/dist/cron/cron-watcher.d.ts +23 -0
  21. package/dist/cron/cron-watcher.d.ts.map +1 -0
  22. package/dist/cron/scheduler.d.ts +3 -1
  23. package/dist/cron/scheduler.d.ts.map +1 -1
  24. package/dist/cron/sqlite-cron-store.d.ts +230 -0
  25. package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
  26. package/dist/extensions/plugin/plugin-config-loader.d.ts +7 -1
  27. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  28. package/dist/extensions/plugin/plugin-loader.d.ts +10 -6
  29. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  30. package/dist/extensions/plugin/plugin-sandbox.d.ts +7 -1
  31. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  32. package/dist/extensions/plugin-sandbox-bootstrap.js +236 -275
  33. package/dist/extensions/tools/constants.d.ts +1 -0
  34. package/dist/extensions/tools/constants.d.ts.map +1 -1
  35. package/dist/extensions/tools/definitions.d.ts +2 -3
  36. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  37. package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
  38. package/dist/extensions/tools/helpers.d.ts +1 -0
  39. package/dist/extensions/tools/helpers.d.ts.map +1 -1
  40. package/dist/extensions/tools/index.d.ts +1 -2
  41. package/dist/extensions/tools/index.d.ts.map +1 -1
  42. package/dist/extensions/tools/presets.d.ts +1 -1
  43. package/dist/extensions/tools/schemas.d.ts +25 -3
  44. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  45. package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
  46. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
  47. package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
  48. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
  49. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  50. package/dist/extensions/tools/types.d.ts +0 -5
  51. package/dist/extensions/tools/types.d.ts.map +1 -1
  52. package/dist/hooks/hook-bridge.d.ts +118 -0
  53. package/dist/hooks/hook-bridge.d.ts.map +1 -0
  54. package/dist/hooks/hook-file-hooks.d.ts +2 -1
  55. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  56. package/dist/hooks/hook-registry.d.ts +16 -0
  57. package/dist/hooks/hook-registry.d.ts.map +1 -0
  58. package/dist/hub/browser-websocket.d.ts.map +1 -1
  59. package/dist/hub/client.d.ts +7 -1
  60. package/dist/hub/client.d.ts.map +1 -1
  61. package/dist/hub/daemon-entry.js +721 -461
  62. package/dist/hub/daemon.d.ts.map +1 -1
  63. package/dist/hub/defaults.d.ts +8 -4
  64. package/dist/hub/defaults.d.ts.map +1 -1
  65. package/dist/hub/index.js +665 -415
  66. package/dist/hub/runtime-handlers.d.ts.map +1 -1
  67. package/dist/hub/server.d.ts +18 -0
  68. package/dist/hub/server.d.ts.map +1 -1
  69. package/dist/hub/session-client.d.ts +3 -0
  70. package/dist/hub/session-client.d.ts.map +1 -1
  71. package/dist/hub/start-shared-server.d.ts.map +1 -1
  72. package/dist/hub/ui-client.d.ts +1 -0
  73. package/dist/hub/ui-client.d.ts.map +1 -1
  74. package/dist/index.d.ts +9 -7
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +756 -467
  77. package/dist/llms/cline-recommended-models.d.ts +20 -0
  78. package/dist/llms/cline-recommended-models.d.ts.map +1 -0
  79. package/dist/llms/handler-factory.d.ts +16 -0
  80. package/dist/llms/handler-factory.d.ts.map +1 -0
  81. package/dist/llms/provider-defaults.d.ts.map +1 -1
  82. package/dist/llms/provider-settings.d.ts +45 -2
  83. package/dist/llms/provider-settings.d.ts.map +1 -1
  84. package/dist/llms/runtime-registry.d.ts.map +1 -1
  85. package/dist/runtime/agent-config-adapter.d.ts +148 -0
  86. package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
  87. package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
  88. package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
  89. package/dist/runtime/history.d.ts +6 -0
  90. package/dist/runtime/history.d.ts.map +1 -1
  91. package/dist/runtime/host.d.ts.map +1 -1
  92. package/dist/runtime/loop-detection.d.ts +59 -0
  93. package/dist/runtime/loop-detection.d.ts.map +1 -0
  94. package/dist/runtime/mistake-tracker.d.ts +69 -0
  95. package/dist/runtime/mistake-tracker.d.ts.map +1 -0
  96. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  97. package/dist/runtime/runtime-event-adapter.d.ts +102 -0
  98. package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
  99. package/dist/runtime/runtime-host.d.ts +28 -3
  100. package/dist/runtime/runtime-host.d.ts.map +1 -1
  101. package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
  102. package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
  103. package/dist/runtime/session-runtime.d.ts +16 -3
  104. package/dist/runtime/session-runtime.d.ts.map +1 -1
  105. package/dist/runtime/user-input-builder.d.ts +24 -0
  106. package/dist/runtime/user-input-builder.d.ts.map +1 -0
  107. package/dist/services/index.js +28 -0
  108. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  109. package/dist/services/plugin-tools.d.ts.map +1 -1
  110. package/dist/services/providers/local-provider-registry.d.ts +197 -21
  111. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  112. package/dist/services/providers/local-provider-service.d.ts +3 -1
  113. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  114. package/dist/services/session-data.d.ts.map +1 -1
  115. package/dist/services/session-telemetry.d.ts +7 -2
  116. package/dist/services/session-telemetry.d.ts.map +1 -1
  117. package/dist/services/storage/file-team-store.d.ts.map +1 -1
  118. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  119. package/dist/services/storage/provider-settings-manager.d.ts +1 -0
  120. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
  121. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
  122. package/dist/session/conversation-store.d.ts +30 -0
  123. package/dist/session/conversation-store.d.ts.map +1 -0
  124. package/dist/session/message-builder.d.ts +65 -0
  125. package/dist/session/message-builder.d.ts.map +1 -0
  126. package/dist/session/session-manifest.d.ts +1 -1
  127. package/dist/transports/hub.d.ts +14 -3
  128. package/dist/transports/hub.d.ts.map +1 -1
  129. package/dist/transports/local.d.ts +14 -4
  130. package/dist/transports/local.d.ts.map +1 -1
  131. package/dist/transports/remote.d.ts.map +1 -1
  132. package/dist/types/chat-schema.d.ts +5 -5
  133. package/dist/types/config.d.ts +9 -0
  134. package/dist/types/config.d.ts.map +1 -1
  135. package/dist/types/events.d.ts +7 -6
  136. package/dist/types/events.d.ts.map +1 -1
  137. package/dist/types/provider-settings.d.ts +2 -2
  138. package/dist/types/provider-settings.d.ts.map +1 -1
  139. package/dist/types/session.d.ts +5 -2
  140. package/dist/types/session.d.ts.map +1 -1
  141. package/dist/types.d.ts +4 -4
  142. package/dist/types.d.ts.map +1 -1
  143. package/package.json +4 -4
  144. package/src/ClineCore.ts +691 -6
  145. package/src/account/cline-account-service.ts +44 -6
  146. package/src/cron/cron-event-ingress.ts +357 -0
  147. package/src/cron/cron-materializer.ts +97 -0
  148. package/src/cron/cron-reconciler.ts +241 -0
  149. package/src/cron/cron-report-writer.ts +153 -0
  150. package/src/cron/cron-runner.ts +495 -0
  151. package/src/cron/cron-schema.ts +127 -0
  152. package/src/cron/cron-service.ts +163 -0
  153. package/src/cron/cron-spec-parser.ts +489 -0
  154. package/src/cron/cron-watcher.ts +102 -0
  155. package/src/cron/index.ts +10 -0
  156. package/src/cron/scheduler.ts +141 -6
  157. package/src/cron/sqlite-cron-store.ts +1286 -0
  158. package/src/extensions/plugin/plugin-config-loader.ts +21 -1
  159. package/src/extensions/plugin/plugin-loader.ts +25 -9
  160. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +151 -1
  161. package/src/extensions/plugin/plugin-sandbox.ts +131 -7
  162. package/src/extensions/tools/constants.ts +2 -0
  163. package/src/extensions/tools/definitions.ts +31 -22
  164. package/src/extensions/tools/executors/editor.ts +4 -3
  165. package/src/extensions/tools/helpers.ts +24 -0
  166. package/src/extensions/tools/index.ts +1 -2
  167. package/src/extensions/tools/presets.ts +1 -1
  168. package/src/extensions/tools/schemas.ts +13 -18
  169. package/src/extensions/tools/team/delegated-agent.ts +8 -3
  170. package/src/extensions/tools/team/multi-agent.ts +135 -19
  171. package/src/extensions/tools/team/team-tools.ts +151 -91
  172. package/src/extensions/tools/types.ts +0 -6
  173. package/src/hooks/hook-bridge.ts +489 -0
  174. package/src/hooks/hook-file-hooks.ts +58 -3
  175. package/src/hooks/hook-registry.ts +257 -0
  176. package/src/hub/browser-websocket.ts +26 -4
  177. package/src/hub/client.ts +72 -13
  178. package/src/hub/daemon-entry.ts +35 -0
  179. package/src/hub/daemon.ts +117 -14
  180. package/src/hub/defaults.ts +39 -12
  181. package/src/hub/runtime-handlers.ts +4 -3
  182. package/src/hub/server.ts +506 -77
  183. package/src/hub/session-client.ts +43 -1
  184. package/src/hub/start-shared-server.ts +3 -0
  185. package/src/hub/ui-client.ts +4 -0
  186. package/src/index.ts +46 -1
  187. package/src/llms/cline-recommended-models.ts +167 -0
  188. package/src/llms/handler-factory.ts +56 -0
  189. package/src/llms/provider-defaults.ts +17 -1
  190. package/src/llms/provider-settings.ts +48 -1
  191. package/src/llms/runtime-registry.ts +1 -0
  192. package/src/runtime/agent-config-adapter.ts +636 -0
  193. package/src/runtime/agent-runtime-config-builder.ts +205 -0
  194. package/src/runtime/error-feedback.ts +142 -0
  195. package/src/runtime/history.ts +137 -0
  196. package/src/runtime/host.ts +22 -0
  197. package/src/runtime/loop-detection.ts +162 -0
  198. package/src/runtime/mistake-tracker.ts +221 -0
  199. package/src/runtime/runtime-builder.ts +61 -5
  200. package/src/runtime/runtime-event-adapter.ts +412 -0
  201. package/src/runtime/runtime-host.ts +45 -1
  202. package/src/runtime/session-runtime-orchestrator.ts +1253 -0
  203. package/src/runtime/session-runtime.ts +16 -2
  204. package/src/runtime/user-input-builder.ts +167 -0
  205. package/src/services/local-runtime-bootstrap.ts +128 -22
  206. package/src/services/plugin-tools.ts +1 -0
  207. package/src/services/providers/local-provider-registry.ts +273 -57
  208. package/src/services/providers/local-provider-service.ts +67 -7
  209. package/src/services/session-data.ts +16 -14
  210. package/src/services/session-telemetry.ts +6 -15
  211. package/src/services/storage/file-team-store.ts +1 -5
  212. package/src/services/storage/provider-settings-legacy-migration.ts +8 -47
  213. package/src/services/storage/provider-settings-manager.ts +16 -1
  214. package/src/services/storage/sqlite-team-store.ts +1 -5
  215. package/src/session/conversation-store.ts +77 -0
  216. package/src/session/message-builder.ts +941 -0
  217. package/src/transports/hub.ts +458 -33
  218. package/src/transports/local.ts +296 -65
  219. package/src/transports/remote.ts +1 -0
  220. package/src/types/config.ts +9 -0
  221. package/src/types/events.ts +8 -6
  222. package/src/types/index.ts +3 -0
  223. package/src/types/provider-settings.ts +8 -1
  224. package/src/types/session.ts +5 -2
  225. package/src/types.ts +15 -1
  226. package/dist/cron/index.d.ts +0 -6
  227. package/dist/cron/index.d.ts.map +0 -1
  228. package/dist/services/telemetry/index.js +0 -28
@@ -1,16 +1,25 @@
1
- import { readFileSync } from "node:fs";
2
- import { basename } from "node:path";
3
1
  import type {
2
+ AgentEvent,
3
+ AgentFinishReason,
4
4
  AgentResult,
5
+ AgentUsage,
6
+ HubEventEnvelope,
5
7
  SessionRecord as HubSessionRecord,
6
8
  HubToolExecutorName,
7
9
  JsonValue,
10
+ ToolApprovalRequest,
11
+ ToolApprovalResult,
8
12
  ToolContext,
9
13
  } from "@clinebot/shared";
10
14
  import type { ToolExecutors } from "../extensions/tools";
11
15
  import type { HookEventPayload } from "../hooks";
12
16
  import { NodeHubClient } from "../hub/client";
13
17
  import type {
18
+ PendingPromptMutationResult,
19
+ PendingPromptsAction,
20
+ PendingPromptsDeleteInput,
21
+ PendingPromptsListInput,
22
+ PendingPromptsUpdateInput,
14
23
  RuntimeHost,
15
24
  RuntimeHostSubscribeOptions,
16
25
  SendSessionInput,
@@ -23,12 +32,9 @@ import {
23
32
  SessionManifestSchema,
24
33
  } from "../session/session-manifest";
25
34
  import { SessionSource, type SessionStatus } from "../types/common";
26
- import type { CoreSessionEvent } from "../types/events";
35
+ import type { CoreSessionEvent, SessionPendingPrompt } from "../types/events";
27
36
  import type { SessionRecord } from "../types/sessions";
28
- import {
29
- RuntimeHostEventBus,
30
- readPersistedMessagesFile,
31
- } from "./runtime-host-support";
37
+ import { RuntimeHostEventBus } from "./runtime-host-support";
32
38
 
33
39
  function toJsonRecord(
34
40
  value: Record<string, unknown> | undefined,
@@ -75,11 +81,102 @@ function parseToolContext(value: unknown): ToolContext {
75
81
  };
76
82
  }
77
83
 
84
+ function parseApprovalInput(value: unknown): unknown {
85
+ if (typeof value !== "string") {
86
+ return value;
87
+ }
88
+ try {
89
+ return JSON.parse(value);
90
+ } catch {
91
+ return value;
92
+ }
93
+ }
94
+
95
+ function isAgentFinishReason(value: unknown): value is AgentFinishReason {
96
+ return (
97
+ value === "completed" ||
98
+ value === "max_iterations" ||
99
+ value === "aborted" ||
100
+ value === "mistake_limit" ||
101
+ value === "error"
102
+ );
103
+ }
104
+
105
+ function parseDoneUsage(value: unknown): AgentUsage | undefined {
106
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
107
+ return undefined;
108
+ }
109
+ const payload = value as Record<string, unknown>;
110
+ const inputTokens =
111
+ typeof payload.inputTokens === "number" ? payload.inputTokens : undefined;
112
+ const outputTokens =
113
+ typeof payload.outputTokens === "number" ? payload.outputTokens : undefined;
114
+ if (inputTokens === undefined || outputTokens === undefined) {
115
+ return undefined;
116
+ }
117
+ return {
118
+ inputTokens,
119
+ outputTokens,
120
+ cacheReadTokens:
121
+ typeof payload.cacheReadTokens === "number" ? payload.cacheReadTokens : 0,
122
+ cacheWriteTokens:
123
+ typeof payload.cacheWriteTokens === "number"
124
+ ? payload.cacheWriteTokens
125
+ : 0,
126
+ totalCost: typeof payload.totalCost === "number" ? payload.totalCost : 0,
127
+ };
128
+ }
129
+
130
+ function doneEventFromPayload(
131
+ payload: Record<string, unknown> | undefined,
132
+ ): AgentEvent {
133
+ const result =
134
+ payload?.result &&
135
+ typeof payload.result === "object" &&
136
+ !Array.isArray(payload.result)
137
+ ? (payload.result as Record<string, unknown>)
138
+ : undefined;
139
+ const reasonCandidate = payload?.reason ?? result?.finishReason;
140
+ const reason = isAgentFinishReason(reasonCandidate)
141
+ ? reasonCandidate
142
+ : reasonCandidate === "failed"
143
+ ? "error"
144
+ : "completed";
145
+ const usage = parseDoneUsage(payload?.usage ?? result?.usage);
146
+ return {
147
+ type: "done",
148
+ reason,
149
+ text:
150
+ typeof payload?.text === "string"
151
+ ? payload.text
152
+ : typeof result?.text === "string"
153
+ ? result.text
154
+ : "",
155
+ iterations:
156
+ typeof payload?.iterations === "number"
157
+ ? payload.iterations
158
+ : typeof result?.iterations === "number"
159
+ ? result.iterations
160
+ : 0,
161
+ usage,
162
+ };
163
+ }
164
+
165
+ function hubReplyErrorMessage(
166
+ reply: { error?: { message?: string } },
167
+ command: string,
168
+ ): string {
169
+ return reply.error?.message ?? `hub command failed: ${command}`;
170
+ }
171
+
78
172
  export interface HubRuntimeHostOptions {
79
173
  url: string;
80
174
  authToken?: string;
81
175
  clientType?: string;
82
176
  displayName?: string;
177
+ requestToolApproval?: (
178
+ request: ToolApprovalRequest,
179
+ ) => Promise<ToolApprovalResult> | ToolApprovalResult;
83
180
  }
84
181
 
85
182
  function mapStatus(
@@ -207,11 +304,16 @@ export class HubRuntimeHost implements RuntimeHost {
207
304
  Partial<ToolExecutors>
208
305
  >();
209
306
  private readonly sessionSubscriptions = new Map<string, () => void>();
307
+ private readonly pendingApprovalToolCallIds = new Set<string>();
308
+ private readonly requestToolApproval:
309
+ | HubRuntimeHostOptions["requestToolApproval"]
310
+ | undefined;
210
311
 
211
312
  constructor(
212
313
  options: HubRuntimeHostOptions,
213
314
  clientContext?: { workspaceRoot?: string; cwd?: string },
214
315
  ) {
316
+ this.requestToolApproval = options.requestToolApproval;
215
317
  this.runtimeAddress = options.url;
216
318
  this.client = new NodeHubClient({
217
319
  url: options.url,
@@ -293,20 +395,104 @@ export class HubRuntimeHost implements RuntimeHost {
293
395
  : {}),
294
396
  ...(input.userFiles?.length
295
397
  ? {
296
- userFiles: input.userFiles.map((filePath) => ({
297
- name: basename(filePath),
298
- content: readFileSync(filePath, "utf8"),
299
- })),
398
+ userFiles: input.userFiles,
300
399
  }
301
400
  : {}),
302
401
  }
303
402
  : undefined,
403
+ delivery: input.delivery,
304
404
  },
305
405
  input.sessionId,
406
+ { timeoutMs: null },
306
407
  );
307
408
  return reply.payload?.result as AgentResult | undefined;
308
409
  }
309
410
 
411
+ async pendingPrompts(
412
+ action: "list",
413
+ input: PendingPromptsListInput,
414
+ ): Promise<SessionPendingPrompt[]>;
415
+ async pendingPrompts(
416
+ action: "update",
417
+ input: PendingPromptsUpdateInput,
418
+ ): Promise<PendingPromptMutationResult>;
419
+ async pendingPrompts(
420
+ action: "delete",
421
+ input: PendingPromptsDeleteInput,
422
+ ): Promise<PendingPromptMutationResult>;
423
+ async pendingPrompts(
424
+ action: PendingPromptsAction,
425
+ input:
426
+ | PendingPromptsListInput
427
+ | PendingPromptsUpdateInput
428
+ | PendingPromptsDeleteInput,
429
+ ): Promise<SessionPendingPrompt[] | PendingPromptMutationResult> {
430
+ switch (action) {
431
+ case "list":
432
+ return await this.listPendingPromptEntries(input);
433
+ case "update":
434
+ return await this.editPendingPromptEntry(
435
+ input as PendingPromptsUpdateInput,
436
+ );
437
+ case "delete":
438
+ return await this.deletePendingPromptEntry(
439
+ input as PendingPromptsDeleteInput,
440
+ );
441
+ }
442
+ }
443
+
444
+ private async listPendingPromptEntries(
445
+ input: PendingPromptsListInput,
446
+ ): Promise<SessionPendingPrompt[]> {
447
+ this.ensureSessionSubscription(input.sessionId);
448
+ const reply = await this.client.command(
449
+ "session.pending_prompts",
450
+ { sessionId: input.sessionId },
451
+ input.sessionId,
452
+ );
453
+ return Array.isArray(reply.payload?.prompts)
454
+ ? (reply.payload.prompts as SessionPendingPrompt[])
455
+ : [];
456
+ }
457
+
458
+ private async editPendingPromptEntry(
459
+ input: PendingPromptsUpdateInput,
460
+ ): Promise<PendingPromptMutationResult> {
461
+ this.ensureSessionSubscription(input.sessionId);
462
+ const reply = await this.client.command(
463
+ "session.update_pending_prompt",
464
+ { ...input },
465
+ input.sessionId,
466
+ );
467
+ return {
468
+ sessionId: input.sessionId,
469
+ prompts: Array.isArray(reply.payload?.prompts)
470
+ ? (reply.payload.prompts as SessionPendingPrompt[])
471
+ : [],
472
+ prompt: reply.payload?.prompt as SessionPendingPrompt | undefined,
473
+ updated: reply.payload?.updated === true,
474
+ };
475
+ }
476
+
477
+ private async deletePendingPromptEntry(
478
+ input: PendingPromptsDeleteInput,
479
+ ): Promise<PendingPromptMutationResult> {
480
+ this.ensureSessionSubscription(input.sessionId);
481
+ const reply = await this.client.command(
482
+ "session.remove_pending_prompt",
483
+ { ...input },
484
+ input.sessionId,
485
+ );
486
+ return {
487
+ sessionId: input.sessionId,
488
+ prompts: Array.isArray(reply.payload?.prompts)
489
+ ? (reply.payload.prompts as SessionPendingPrompt[])
490
+ : [],
491
+ prompt: reply.payload?.prompt as SessionPendingPrompt | undefined,
492
+ removed: reply.payload?.removed === true,
493
+ };
494
+ }
495
+
310
496
  async getAccumulatedUsage(
311
497
  sessionId: string,
312
498
  ): Promise<SessionAccumulatedUsage | undefined> {
@@ -346,7 +532,7 @@ export class HubRuntimeHost implements RuntimeHost {
346
532
  }
347
533
  this.sessionSubscriptions.clear();
348
534
  this.sessionToolExecutors.clear();
349
- this.client.close();
535
+ await this.client.dispose();
350
536
  }
351
537
 
352
538
  async get(sessionId: string): Promise<SessionRecord | undefined> {
@@ -400,8 +586,22 @@ export class HubRuntimeHost implements RuntimeHost {
400
586
  async readMessages(
401
587
  sessionId: string,
402
588
  ): Promise<import("@clinebot/llms").Message[]> {
403
- const session = await this.get(sessionId);
404
- return readPersistedMessagesFile(session?.messagesPath);
589
+ const target = sessionId.trim();
590
+ if (!target) {
591
+ return [];
592
+ }
593
+ const reply = await this.client.command(
594
+ "session.messages",
595
+ { sessionId: target },
596
+ target,
597
+ );
598
+ if (!reply.ok) {
599
+ throw new Error(hubReplyErrorMessage(reply, "session.messages"));
600
+ }
601
+ const messages = reply.payload?.messages;
602
+ return Array.isArray(messages)
603
+ ? (messages as import("@clinebot/llms").Message[])
604
+ : [];
405
605
  }
406
606
 
407
607
  async handleHookEvent(_payload: HookEventPayload): Promise<void> {
@@ -441,19 +641,79 @@ export class HubRuntimeHost implements RuntimeHost {
441
641
  this.sessionSubscriptions.delete(target);
442
642
  }
443
643
 
444
- private handleHubEvent(
445
- event: import("@clinebot/shared").HubEventEnvelope,
446
- ): void {
644
+ private emitToolCallContentStart(input: {
645
+ sessionId: string;
646
+ toolCallId?: string;
647
+ toolName?: string;
648
+ toolInput?: unknown;
649
+ }): void {
650
+ this.events.emit({
651
+ type: "agent_event",
652
+ payload: {
653
+ sessionId: input.sessionId,
654
+ event: {
655
+ type: "content_start",
656
+ contentType: "tool",
657
+ toolCallId: input.toolCallId,
658
+ toolName: input.toolName,
659
+ input: input.toolInput,
660
+ },
661
+ },
662
+ });
663
+ }
664
+
665
+ private handleHubEvent(event: HubEventEnvelope): void {
447
666
  const sessionId = event.sessionId?.trim();
448
667
  if (event.event === "capability.requested") {
449
668
  void this.handleCapabilityRequest(event);
450
669
  return;
451
670
  }
671
+ if (event.event === "approval.requested") {
672
+ void this.handleApprovalRequested(event);
673
+ return;
674
+ }
452
675
  if (!sessionId) {
453
676
  return;
454
677
  }
455
678
 
456
679
  switch (event.event) {
680
+ case "iteration.started": {
681
+ this.events.emit({
682
+ type: "agent_event",
683
+ payload: {
684
+ sessionId,
685
+ event: {
686
+ type: "iteration_start",
687
+ iteration:
688
+ typeof event.payload?.iteration === "number"
689
+ ? event.payload.iteration
690
+ : 0,
691
+ },
692
+ },
693
+ });
694
+ return;
695
+ }
696
+ case "iteration.finished": {
697
+ this.events.emit({
698
+ type: "agent_event",
699
+ payload: {
700
+ sessionId,
701
+ event: {
702
+ type: "iteration_end",
703
+ iteration:
704
+ typeof event.payload?.iteration === "number"
705
+ ? event.payload.iteration
706
+ : 0,
707
+ hadToolCalls: event.payload?.hadToolCalls === true,
708
+ toolCallCount:
709
+ typeof event.payload?.toolCallCount === "number"
710
+ ? event.payload.toolCallCount
711
+ : 0,
712
+ },
713
+ },
714
+ });
715
+ return;
716
+ }
457
717
  case "assistant.delta": {
458
718
  const text =
459
719
  typeof event.payload?.text === "string" ? event.payload.text : "";
@@ -473,6 +733,23 @@ export class HubRuntimeHost implements RuntimeHost {
473
733
  });
474
734
  return;
475
735
  }
736
+ case "assistant.finished": {
737
+ this.events.emit({
738
+ type: "agent_event",
739
+ payload: {
740
+ sessionId,
741
+ event: {
742
+ type: "content_end",
743
+ contentType: "text",
744
+ text:
745
+ typeof event.payload?.text === "string"
746
+ ? event.payload.text
747
+ : undefined,
748
+ },
749
+ },
750
+ });
751
+ return;
752
+ }
476
753
  case "reasoning.delta": {
477
754
  const text =
478
755
  typeof event.payload?.text === "string" ? event.payload.text : "";
@@ -494,29 +771,60 @@ export class HubRuntimeHost implements RuntimeHost {
494
771
  });
495
772
  return;
496
773
  }
497
- case "tool.started": {
774
+ case "reasoning.finished": {
498
775
  this.events.emit({
499
776
  type: "agent_event",
500
777
  payload: {
501
778
  sessionId,
502
779
  event: {
503
- type: "content_start",
504
- contentType: "tool",
505
- toolCallId:
506
- typeof event.payload?.toolCallId === "string"
507
- ? event.payload.toolCallId
508
- : undefined,
509
- toolName:
510
- typeof event.payload?.toolName === "string"
511
- ? event.payload.toolName
780
+ type: "content_end",
781
+ contentType: "reasoning",
782
+ reasoning:
783
+ typeof event.payload?.reasoning === "string"
784
+ ? event.payload.reasoning
512
785
  : undefined,
513
- input: event.payload?.input,
514
786
  },
515
787
  },
516
788
  });
517
789
  return;
518
790
  }
791
+ case "agent.done": {
792
+ this.events.emit({
793
+ type: "agent_event",
794
+ payload: {
795
+ sessionId,
796
+ event: doneEventFromPayload(event.payload),
797
+ },
798
+ });
799
+ return;
800
+ }
801
+ case "tool.started": {
802
+ const toolCallId =
803
+ typeof event.payload?.toolCallId === "string"
804
+ ? event.payload.toolCallId
805
+ : undefined;
806
+ if (toolCallId && this.pendingApprovalToolCallIds.delete(toolCallId)) {
807
+ return;
808
+ }
809
+ this.emitToolCallContentStart({
810
+ sessionId,
811
+ toolCallId,
812
+ toolName:
813
+ typeof event.payload?.toolName === "string"
814
+ ? event.payload.toolName
815
+ : undefined,
816
+ toolInput: event.payload?.input,
817
+ });
818
+ return;
819
+ }
519
820
  case "tool.finished": {
821
+ const toolCallId =
822
+ typeof event.payload?.toolCallId === "string"
823
+ ? event.payload.toolCallId
824
+ : undefined;
825
+ if (toolCallId) {
826
+ this.pendingApprovalToolCallIds.delete(toolCallId);
827
+ }
520
828
  this.events.emit({
521
829
  type: "agent_event",
522
830
  payload: {
@@ -524,10 +832,7 @@ export class HubRuntimeHost implements RuntimeHost {
524
832
  event: {
525
833
  type: "content_end",
526
834
  contentType: "tool",
527
- toolCallId:
528
- typeof event.payload?.toolCallId === "string"
529
- ? event.payload.toolCallId
530
- : undefined,
835
+ toolCallId,
531
836
  toolName:
532
837
  typeof event.payload?.toolName === "string"
533
838
  ? event.payload.toolName
@@ -557,9 +862,55 @@ export class HubRuntimeHost implements RuntimeHost {
557
862
  });
558
863
  return;
559
864
  }
865
+ case "session.pending_prompts": {
866
+ this.events.emit({
867
+ type: "pending_prompts",
868
+ payload: {
869
+ sessionId,
870
+ prompts: Array.isArray(event.payload?.prompts)
871
+ ? (event.payload.prompts as SessionPendingPrompt[])
872
+ : [],
873
+ },
874
+ });
875
+ return;
876
+ }
877
+ case "session.pending_prompt_submitted": {
878
+ const prompt = event.payload?.prompt as
879
+ | SessionPendingPrompt
880
+ | undefined;
881
+ if (!prompt) {
882
+ return;
883
+ }
884
+ this.events.emit({
885
+ type: "pending_prompt_submitted",
886
+ payload: {
887
+ sessionId,
888
+ id: prompt.id,
889
+ prompt: prompt.prompt,
890
+ delivery: prompt.delivery,
891
+ attachmentCount: prompt.attachmentCount,
892
+ },
893
+ });
894
+ return;
895
+ }
560
896
  case "run.completed":
561
897
  case "run.aborted": {
562
898
  this.sessionToolExecutors.delete(sessionId);
899
+ this.events.emit({
900
+ type: "agent_event",
901
+ payload: {
902
+ sessionId,
903
+ event: doneEventFromPayload({
904
+ ...event.payload,
905
+ reason:
906
+ typeof event.payload?.reason === "string"
907
+ ? event.payload.reason
908
+ : event.event === "run.aborted"
909
+ ? "aborted"
910
+ : "completed",
911
+ }),
912
+ },
913
+ });
563
914
  this.events.emit({
564
915
  type: "ended",
565
916
  payload: {
@@ -581,7 +932,7 @@ export class HubRuntimeHost implements RuntimeHost {
581
932
  }
582
933
 
583
934
  private async handleCapabilityRequest(
584
- event: import("@clinebot/shared").HubEventEnvelope,
935
+ event: HubEventEnvelope,
585
936
  ): Promise<void> {
586
937
  const sessionId = event.sessionId?.trim();
587
938
  if (!sessionId) {
@@ -653,4 +1004,78 @@ export class HubRuntimeHost implements RuntimeHost {
653
1004
  );
654
1005
  }
655
1006
  }
1007
+
1008
+ private async handleApprovalRequested(
1009
+ event: HubEventEnvelope,
1010
+ ): Promise<void> {
1011
+ const sessionId = event.sessionId?.trim();
1012
+ if (!sessionId || !this.requestToolApproval) {
1013
+ return;
1014
+ }
1015
+ const approvalId =
1016
+ typeof event.payload?.approvalId === "string"
1017
+ ? event.payload.approvalId.trim()
1018
+ : "";
1019
+ const toolCallId =
1020
+ typeof event.payload?.toolCallId === "string"
1021
+ ? event.payload.toolCallId
1022
+ : "";
1023
+ const toolName =
1024
+ typeof event.payload?.toolName === "string" ? event.payload.toolName : "";
1025
+ if (!approvalId || !toolCallId || !toolName) {
1026
+ return;
1027
+ }
1028
+ const policy =
1029
+ event.payload?.policy &&
1030
+ typeof event.payload.policy === "object" &&
1031
+ !Array.isArray(event.payload.policy)
1032
+ ? (event.payload.policy as ToolApprovalRequest["policy"])
1033
+ : { autoApprove: false };
1034
+ const input = parseApprovalInput(event.payload?.inputJson);
1035
+ this.pendingApprovalToolCallIds.add(toolCallId);
1036
+ this.emitToolCallContentStart({
1037
+ sessionId,
1038
+ toolCallId,
1039
+ toolName,
1040
+ toolInput: input,
1041
+ });
1042
+ const result = await Promise.resolve(
1043
+ this.requestToolApproval({
1044
+ sessionId,
1045
+ agentId:
1046
+ typeof event.payload?.agentId === "string"
1047
+ ? event.payload.agentId
1048
+ : "",
1049
+ conversationId:
1050
+ typeof event.payload?.conversationId === "string"
1051
+ ? event.payload.conversationId
1052
+ : sessionId,
1053
+ iteration:
1054
+ typeof event.payload?.iteration === "number"
1055
+ ? event.payload.iteration
1056
+ : 0,
1057
+ toolCallId,
1058
+ toolName,
1059
+ input,
1060
+ policy,
1061
+ }),
1062
+ ).catch((error) => ({
1063
+ approved: false,
1064
+ reason:
1065
+ error instanceof Error
1066
+ ? error.message
1067
+ : `Tool approval request failed: ${String(error)}`,
1068
+ }));
1069
+ await this.client
1070
+ .command(
1071
+ "approval.respond",
1072
+ {
1073
+ approvalId,
1074
+ approved: result.approved,
1075
+ reason: result.reason,
1076
+ },
1077
+ sessionId,
1078
+ )
1079
+ .catch(() => {});
1080
+ }
656
1081
  }