@cline/core 0.0.76 → 0.0.78

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.
@@ -11,4 +11,13 @@ export interface HubCommandTransport {
11
11
  subscribe(clientId: string, listener: (event: HubEventEnvelope) => void, options?: {
12
12
  sessionId?: string;
13
13
  }): Promise<() => void> | (() => void);
14
+ /**
15
+ * Durable events with `sequence > sinceSequence` (scoped when a sessionId
16
+ * is given), oldest first, bounded by `limit`. Absent on transports
17
+ * without a durable event log; callers must treat replay as best-effort.
18
+ */
19
+ replayEventsAfter?(sinceSequence: number, options: {
20
+ sessionId?: string;
21
+ limit: number;
22
+ }): HubEventEnvelope[];
14
23
  }
@@ -1,9 +1,16 @@
1
- import type { HubCommandEnvelope, HubReplyEnvelope, ToolApprovalRequest } from "@cline/shared";
1
+ import type { HubCommandEnvelope, HubEventEnvelope, HubReplyEnvelope, ToolApprovalRequest } from "@cline/shared";
2
2
  import { type HubTransportContext } from "./context";
3
3
  export declare function requestToolApproval(ctx: HubTransportContext, request: ToolApprovalRequest): Promise<{
4
4
  approved: boolean;
5
5
  reason?: string;
6
6
  }>;
7
+ /**
8
+ * Pending `approval.requested` events, optionally scoped to one session.
9
+ * Re-issued to a (re)subscribing client so an approval raised while nobody
10
+ * was connected — or while this client was disconnected — is neither lost
11
+ * nor implicitly answered.
12
+ */
13
+ export declare function pendingApprovalEvents(ctx: HubTransportContext, sessionId?: string): HubEventEnvelope[];
7
14
  export declare function resolvePendingApproval(ctx: HubTransportContext, approvalId: string, result: {
8
15
  approved: boolean;
9
16
  reason?: string;
@@ -8,6 +8,12 @@ export type PendingApproval = {
8
8
  approved: boolean;
9
9
  reason?: string;
10
10
  }) => void;
11
+ /**
12
+ * The `approval.requested` event as originally published. Pending
13
+ * approvals survive client disconnects, so a (re)subscribing client is
14
+ * re-issued this event instead of being left with a silently parked turn.
15
+ */
16
+ requestedEvent?: HubEventEnvelope;
11
17
  };
12
18
  export type PendingCapabilityRequest = {
13
19
  sessionId: string;
@@ -46,6 +52,13 @@ export interface HubTransportContext {
46
52
  /** Hub-owned extensions injected into every local session runtime. */
47
53
  readonly sessionExtensions?: readonly AgentExtension[];
48
54
  readonly sessionHost: RuntimeHost & Partial<CommandExecutionRuntimeService & PendingPromptsRuntimeService & SessionUsageRuntimeService & SessionConnectionRuntimeService>;
55
+ /**
56
+ * While draining, new mutating work (session.create, run.*) is refused
57
+ * with the retryable `hub_draining` error so the Hub can be replaced at a
58
+ * boundary an operator chose instead of being ambushed mid-turn.
59
+ * Optional: absent contexts (test fixtures) are never draining.
60
+ */
61
+ isDraining?(): boolean;
49
62
  publish(event: HubEventEnvelope): void;
50
63
  buildEvent(event: HubEventEnvelope["event"], payload?: Record<string, unknown>, sessionId?: string): HubEventEnvelope;
51
64
  requestCapability(sessionId: string, capabilityName: string, payload: Record<string, unknown>, targetClientId: string, onProgress?: (payload: Record<string, unknown>) => void): Promise<Record<string, unknown> | undefined>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Queue-backed run admission (`run.enqueue`), queue introspection
3
+ * (`run.list`), and drain lifecycle (`hub.drain`, `hub.status`).
4
+ *
5
+ * `run.start` keeps its historical synchronous-reply contract untouched;
6
+ * `run.enqueue` is the additive path with app-server semantics: durable FIFO
7
+ * admission, an immediate `{runId, acceptedAt, queuePosition}` ack, and
8
+ * execution that never depends on the requesting socket staying alive.
9
+ */
10
+ import type { HubCommandEnvelope, HubReplyEnvelope } from "@cline/shared";
11
+ import { type HubRunQueue } from "../hub-run-queue";
12
+ import { type HubTransportContext } from "./context";
13
+ export declare const HUB_DRAINING_ERROR_CODE = "hub_draining";
14
+ export declare function isDrainRefusedCommand(command: string): boolean;
15
+ export declare function drainingReply(envelope: HubCommandEnvelope): HubReplyEnvelope;
16
+ /**
17
+ * Serial per-session executor over the durable queue. Admission and
18
+ * execution are decoupled: `enqueue` acks immediately, `pump` runs turns one
19
+ * at a time per session through the same `handleSessionInput` path (and thus
20
+ * the same event projection) as `run.start`.
21
+ */
22
+ export declare class HubRunExecutor {
23
+ private readonly ctx;
24
+ private readonly queue;
25
+ private readonly activeSessions;
26
+ constructor(ctx: HubTransportContext, queue: HubRunQueue);
27
+ /** Start (or continue) draining the session's queue in the background. */
28
+ pump(sessionId: string): void;
29
+ private drainSession;
30
+ private execute;
31
+ }
32
+ export declare function handleRunEnqueue(ctx: HubTransportContext, envelope: HubCommandEnvelope, queue: HubRunQueue, executor: HubRunExecutor): HubReplyEnvelope;
33
+ export declare function handleRunList(envelope: HubCommandEnvelope, queue: HubRunQueue): HubReplyEnvelope;
@@ -3,7 +3,7 @@ import type { SessionConnectionUpdate } from "../../../runtime/host/runtime-host
3
3
  import { type HubTransportContext } from "./context";
4
4
  export declare function selectSessionTools<T extends {
5
5
  name: string;
6
- }>(tools: readonly T[], mode: string): T[];
6
+ }>(tools: readonly T[], mode: string, source?: string): T[];
7
7
  export declare function readSessionConnectionUpdate(value: unknown): SessionConnectionUpdate;
8
8
  export declare function resolveSessionAutoApproveTools(toolPolicies: unknown, runtimeOptions: Record<string, unknown>): boolean;
9
9
  export declare function handleSessionCreate(ctx: HubTransportContext, envelope: HubCommandEnvelope, requestToolApproval: (request: ToolApprovalRequest) => Promise<{
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Durable, cursor-addressed Hub event log.
3
+ *
4
+ * Every event the Hub publishes is appended here with a monotonically
5
+ * increasing global sequence before it is fanned out to live sockets. A
6
+ * client that reconnects can resume exactly where it left off by passing
7
+ * `sinceSequence` on `stream.subscribe`: the adapter replays pages from this
8
+ * log, then live-tails. Nothing about delivery depends on who was watching
9
+ * when the event happened — disconnect never implies data loss.
10
+ *
11
+ * The log is a projection aid, not the source of truth for conversation
12
+ * history (session messages remain canonical on disk); it is bounded by a
13
+ * retention sweep so it can run forever.
14
+ */
15
+ import type { HubEventEnvelope } from "@cline/shared";
16
+ export interface HubEventLogOptions {
17
+ /** Database file. Defaults to an owner-scoped `<data>/db/hub-events-*.db`; use ":memory:" in tests. */
18
+ dbPath?: string;
19
+ /** Scopes the default `dbPath`; ignored when `dbPath` is given. */
20
+ ownerId?: string;
21
+ /** Events older than this are pruned. Defaults to 7 days. */
22
+ retentionMs?: number;
23
+ /** Hard cap on rows kept, oldest pruned first. Defaults to 200k. */
24
+ maxRows?: number;
25
+ }
26
+ export interface HubEventLogScope {
27
+ sessionId?: string;
28
+ }
29
+ /**
30
+ * Default log location, scoped per hub owner context so coexisting hubs
31
+ * (production and a dev shared hub) never interleave one log's sequences.
32
+ */
33
+ export declare function resolveHubEventLogPath(ownerId?: string): string;
34
+ export declare class HubEventLogStore {
35
+ private readonly db;
36
+ private readonly retentionMs;
37
+ private readonly maxRows;
38
+ private closed;
39
+ constructor(options?: HubEventLogOptions);
40
+ /**
41
+ * Append a durable event and return it stamped with its global sequence.
42
+ * The returned envelope (not the input) is what must be fanned out so
43
+ * live listeners and replaying clients observe identical frames.
44
+ */
45
+ append(envelope: HubEventEnvelope): HubEventEnvelope;
46
+ /** Events after `sequence`, oldest first, optionally scoped to a session. */
47
+ listAfter(sequence: number, scope: HubEventLogScope, limit: number): HubEventEnvelope[];
48
+ lastSequence(): number;
49
+ /** Bound the log: drop rows past retention, then enforce the row cap. */
50
+ prune(now?: number): void;
51
+ close(): void;
52
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Durable FIFO run queue with immediate acknowledgement.
3
+ *
4
+ * `run.enqueue` admits a prompt into this queue and acks immediately with
5
+ * `{runId, acceptedAt, queuePosition}` — acceptance is decoupled from
6
+ * execution, so the reply never blocks on the turn and never dies with the
7
+ * socket. One run executes at a time per session, in admission order.
8
+ *
9
+ * Runs are durable: a daemon crash leaves `queued` rows to re-admit in FIFO
10
+ * order at the next startup, and `running` rows are marked `interrupted` —
11
+ * never silently resumed, never left dangling as ghost "running" state.
12
+ *
13
+ * Admission applies backpressure: a full per-session queue rejects with a
14
+ * retryable `run_admission_rejected` instead of accepting unbounded work.
15
+ */
16
+ export type HubRunState = "queued" | "running" | "completed" | "failed" | "aborted" | "interrupted";
17
+ export interface HubRunRecord {
18
+ runId: string;
19
+ sessionId: string;
20
+ state: HubRunState;
21
+ /** The `run.start`-shaped payload to execute (prompt, mode, attachments, ...). */
22
+ input: Record<string, unknown>;
23
+ clientId?: string;
24
+ acceptedAt: number;
25
+ startedAt?: number;
26
+ endedAt?: number;
27
+ error?: string;
28
+ }
29
+ export interface HubRunAccepted {
30
+ runId: string;
31
+ acceptedAt: number;
32
+ queuePosition: number;
33
+ }
34
+ export declare class HubRunAdmissionRejectedError extends Error {
35
+ readonly retryable = true;
36
+ constructor(sessionId: string, pending: number, limit: number);
37
+ }
38
+ export interface HubRunQueueOptions {
39
+ /** Database file. Defaults to an owner-scoped `<data>/db/hub-runs-*.db`; use ":memory:" in tests. */
40
+ dbPath?: string;
41
+ /** Scopes the default `dbPath`; ignored when `dbPath` is given. */
42
+ ownerId?: string;
43
+ maxPendingPerSession?: number;
44
+ }
45
+ /**
46
+ * Default queue location, scoped per hub owner context: startup recovery
47
+ * marks orphaned `running` rows interrupted, and a coexisting hub (dev
48
+ * shared next to production) must never reap another hub's live runs.
49
+ */
50
+ export declare function resolveHubRunQueuePath(ownerId?: string): string;
51
+ export declare class HubRunQueue {
52
+ private readonly db;
53
+ private readonly maxPendingPerSession;
54
+ private closed;
55
+ constructor(options?: HubRunQueueOptions);
56
+ /** Durable FIFO admission + immediate acknowledgement. */
57
+ admit(sessionId: string, input: Record<string, unknown>, clientId?: string): HubRunAccepted;
58
+ get(runId: string): HubRunRecord | undefined;
59
+ /** Oldest queued run for the session, if any. */
60
+ nextQueued(sessionId: string): HubRunRecord | undefined;
61
+ /** Whether a run is currently marked running for the session. */
62
+ hasRunning(sessionId: string): boolean;
63
+ countPendingBySession(sessionId: string): number;
64
+ countPending(): number;
65
+ markRunning(runId: string): void;
66
+ markTerminal(runId: string, state: Extract<HubRunState, "completed" | "failed" | "aborted" | "interrupted">, error?: string): void;
67
+ list(options?: {
68
+ sessionId?: string;
69
+ limit?: number;
70
+ }): HubRunRecord[];
71
+ /**
72
+ * Crash recovery, run once at daemon startup, before any new admission:
73
+ * runs left `running` by a dead daemon are marked `interrupted` (never
74
+ * auto-resumed — a resumed half-turn is worse than an honest interrupt),
75
+ * and committed `queued` runs are returned for FIFO re-admission.
76
+ */
77
+ recoverOnStartup(): {
78
+ interrupted: HubRunRecord[];
79
+ requeued: HubRunRecord[];
80
+ };
81
+ close(): void;
82
+ }
@@ -5,6 +5,8 @@ import type { CommandExecutionRuntimeService, PendingPromptsRuntimeService, Runt
5
5
  import type { CoreSettingsService } from "../../settings";
6
6
  import type { AgendaTaskManagerOptions } from "../../tasks";
7
7
  import type { HubOwnerContext } from "../discovery";
8
+ import type { HubEventLogOptions } from "./hub-event-log";
9
+ import type { HubRunQueueOptions } from "./hub-run-queue";
8
10
  export interface HubWebSocketServerOptions {
9
11
  /** Workspace authority assigned by the Hub to authenticated clients. */
10
12
  workspaceRoot?: string;
@@ -52,6 +54,14 @@ export interface HubWebSocketServerOptions {
52
54
  * signals, and fatal errors through one shutdown coordinator.
53
55
  */
54
56
  onShutdownRequested?: () => void | Promise<void>;
57
+ /**
58
+ * Durable event log configuration. Pass `false` to disable persistence
59
+ * (events become fire-and-forget, the pre-log behavior; `stream.subscribe`
60
+ * replay cursors are then best-effort no-ops).
61
+ */
62
+ eventLog?: HubEventLogOptions | false;
63
+ /** Durable run queue configuration (`run.enqueue`). */
64
+ runQueue?: HubRunQueueOptions | false;
55
65
  }
56
66
  export interface HubWebSocketServer {
57
67
  host: string;
@@ -24,12 +24,21 @@ export declare class HubServerTransport implements NativeHubTransport {
24
24
  private readonly sessionHost;
25
25
  private readonly hubId;
26
26
  private readonly ctx;
27
+ /** Durable event log; created on start(), absent in never-started tests. */
28
+ private eventLog?;
29
+ private eventLogPruneTimer?;
30
+ /** Durable run queue + serial per-session executor (run.enqueue). */
31
+ private runQueue?;
32
+ private runExecutor?;
33
+ private draining;
27
34
  constructor(options: HubWebSocketServerOptions);
28
35
  private startAgendaTaskSession;
29
36
  private runAgendaTaskSession;
30
37
  getCronService(): CronService | undefined;
31
38
  getHubId(): string;
32
39
  start(): Promise<void>;
40
+ private startEventLog;
41
+ private startRunQueue;
33
42
  stop(): Promise<void>;
34
43
  handleCommand(envelope: HubCommandEnvelope, authority?: HubConnectionAuthority | null): Promise<HubReplyEnvelope>;
35
44
  private dispatchCommand;
@@ -37,6 +46,22 @@ export declare class HubServerTransport implements NativeHubTransport {
37
46
  private commandTelemetryContext;
38
47
  private handleSettingsList;
39
48
  private handleSettingsToggle;
49
+ /**
50
+ * Explicit drain: refuse new mutating work while accepted runs finish.
51
+ * This is the graceful half of an upgrade — replacement happens at a
52
+ * boundary an operator chose, never as an ambush under a live turn.
53
+ */
54
+ private handleHubDrain;
55
+ private handleHubStatus;
56
+ private describeStatus;
57
+ /** Whether the hub is currently draining (exposed for the HTTP status). */
58
+ isDraining(): boolean;
59
+ /** Durable events after a cursor — the adapter's replay source. */
60
+ replayEventsAfter(sinceSequence: number, options: {
61
+ sessionId?: string;
62
+ limit: number;
63
+ }): HubEventEnvelope[];
64
+ lastEventSequence(): number;
40
65
  subscribe(clientId: string, listener: (event: HubEventEnvelope) => void, options?: {
41
66
  sessionId?: string;
42
67
  }): () => void;
@@ -5,6 +5,11 @@ export interface NativeHubTransport {
5
5
  subscribe(clientId: string, listener: (event: HubEventEnvelope) => void, options?: {
6
6
  sessionId?: string;
7
7
  }): () => void;
8
+ /** See {@link HubCommandTransport.replayEventsAfter}. */
9
+ replayEventsAfter?(sinceSequence: number, options: {
10
+ sessionId?: string;
11
+ limit: number;
12
+ }): HubEventEnvelope[];
8
13
  }
9
14
  export declare class NativeHubTransportAdapter implements HubCommandTransport {
10
15
  private readonly transport;
@@ -13,4 +18,8 @@ export declare class NativeHubTransportAdapter implements HubCommandTransport {
13
18
  subscribe(clientId: string, listener: (event: HubEventEnvelope) => void, options?: {
14
19
  sessionId?: string;
15
20
  }): () => void;
21
+ replayEventsAfter(sinceSequence: number, options: {
22
+ sessionId?: string;
23
+ limit: number;
24
+ }): HubEventEnvelope[];
16
25
  }
package/dist/index.d.ts CHANGED
@@ -113,7 +113,7 @@ export { CORE_BUILD_VERSION } from "./version";
113
113
  export declare function loadOpenTelemetryAdapter(): Promise<typeof import("./services/telemetry")>;
114
114
  export { Agent, createAgentRuntime } from "@cline/agents";
115
115
  export { createCompactionStateAwarePrepareTurn, createContextCompactionPrepareTurn, } from "./extensions/context/compaction";
116
- export { ALL_DEFAULT_TOOL_NAMES, type ApplyPatchExecutor, type ApplyPatchInput, type AskQuestionExecutor, type BuiltinToolAvailabilityContext, CommandExitError, type CreateBuiltinToolsOptions, type CreateDefaultToolsOptions, computePatchChanges, createApplyPatchExecutor, createBuiltinTools, createDefaultExecutors, createDefaultShellExecutor, createDefaultTools, createDefaultToolsWithPreset, createEditorExecutor, createShellExecutor, createShellTool, createToolPoliciesWithPreset, type DefaultExecutorsOptions, type DefaultToolName, DefaultToolNames, type DefaultToolsConfig, type EditFileInput, type EditorExecutor, type EditorExecutorOptions, getCoreAcpToolNames, getCoreBuiltinToolCatalog, getCoreDefaultEnabledToolIds, getCoreHeadlessToolNames, isSkillsToolAvailable, MAX_COMMAND_OUTPUT_CHARS, PATCH_MARKERS, PatchActionType, type PatchFileChange, resolveCoreSelectedToolIds, type ShellExecutor, type ShellExecutorOptions, type StructuredCommandInput, StructuredCommandInputSchema, TEAM_TOOL_NAMES, type ToolCatalogEntry, type ToolExecutors, type ToolPolicyPresetName, type ToolPresetName, ToolPresets, truncateCommandOutput, } from "./extensions/tools";
116
+ export { ALL_DEFAULT_TOOL_NAMES, type ApplyPatchExecutor, type ApplyPatchInput, type AskQuestionExecutor, type BuiltinToolAvailabilityContext, CommandExitError, type CreateBuiltinToolsOptions, type CreateDefaultToolsOptions, computePatchChanges, createApplyPatchExecutor, createBuiltinTools, createDefaultExecutors, createDefaultShellExecutor, createDefaultTools, createDefaultToolsWithPreset, createEditorExecutor, createShellExecutor, createShellTool, createToolPoliciesWithPreset, type DefaultExecutorsOptions, type DefaultToolName, DefaultToolNames, type DefaultToolsConfig, type EditFileInput, type EditorExecutor, type EditorExecutorOptions, getCoreAcpToolNames, getCoreBuiltinToolCatalog, getCoreDefaultEnabledToolIds, getCoreHeadlessToolNames, isCoreBuiltinToolAvailable, isSkillsToolAvailable, MAX_COMMAND_OUTPUT_CHARS, PATCH_MARKERS, PatchActionType, type PatchFileChange, resolveCoreSelectedToolIds, resolveToolClientType, type ShellExecutor, type ShellExecutorOptions, type StructuredCommandInput, StructuredCommandInputSchema, TEAM_TOOL_NAMES, type ToolCatalogEntry, type ToolClientType, type ToolExecutors, type ToolPolicyPresetName, type ToolPresetName, ToolPresets, truncateCommandOutput, } from "./extensions/tools";
117
117
  export { applyClineFeaturedModels, type ClineRecommendedModel, type ClineRecommendedModelsData, FALLBACK_CLINE_RECOMMENDED_MODELS, type FetchClineRecommendedModelsOptions, fetchClineRecommendedModels, getCachedClineRecommendedModels, peekClineRecommendedModels, resetClineRecommendedModelsCacheForTests, } from "./services/llms/cline-recommended-models";
118
118
  export { clearLiveModelsCatalogCache, clearPrivateModelsCatalogCache, DEFAULT_MODELS_CATALOG_URL, getLiveModelsCatalog, getProviderConfig, isPrivateModelCatalogProvider, OPENAI_COMPATIBLE_PROVIDERS, resolveProviderConfig, } from "./services/llms/provider-defaults";
119
119
  export type { AuthSettings, AwsSettings, AzureSettings, BuiltInProviderId, GcpSettings, ModelCatalogConfig, ModelCatalogSettings, OcaSettings, ProviderCapability, ProviderClient, ProviderConfig, ProviderDefaultsConfig, ProviderId, ProviderProtocol, ProviderSettings, ReasoningSettings, SapSettings, ToProviderConfigOptions, } from "./services/llms/provider-settings";