@otto-code/client 0.7.5 → 0.8.0

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.
@@ -1,10 +1,12 @@
1
+ import type { AgentAttentionNotificationPayload } from "@otto-code/protocol/agent-attention-notification";
1
2
  import type { z } from "zod";
3
+ import type { ProjectGithubCloneProtocol } from "@otto-code/protocol/messages";
2
4
  import { type ClientCapability } from "@otto-code/protocol/client-capabilities";
3
5
  import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, type ServerInfoStatusPayload } from "@otto-code/protocol/messages";
4
- import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreateOttoWorktreeRequest, CodeListFilesResponse, CodeSymbolLocation, CodeDefinitionLocation, CodeDefinitionStatus, CodeRenameApplyStatus, CodeRenameFileOutcome, CodeRenameUndoFile, CodeRenameUndoStatus, CodeHoverRange, CodeRenameEdit, CodeRenameFilePlan, LspLanguageState, LspRunningServer, CodeSolutionGetTreeResponse, CodeSolutionLoadProjectResponse, SolutionFormat, SolutionRef, SolutionTreeFolder, SolutionTreeProject, SolutionProjectNode, SolutionProjectStatus, SolutionPackageReference, FileCreateResult, FileDeleteResult, FileDownloadTokenResponse, FileEntryKind, FileEol, FileRenameResult, FileReplaceFileResult, FileReplaceRequest, FileReplaceResponse, FileSearchResultPayload, FileSearchSummary, FileUploadResponse, FileExplorerResponse, FileWatchEventPayload, FileWriteResult, FileRefineResult, FileRefineDocument, FileRefineReference, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommitResponse, CheckoutGitCommitResponse, CheckoutGitCommitAgentResponse, CheckoutGitRollbackResponse, CheckoutGitFileHistoryResponse, CheckoutGitFileCommitDiffResponse, CheckoutGitFileBlameResponse, CheckoutGitFileOriginResponse, CheckoutGitGetOperationLogResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutGithubSetAutoMergeResponse, CheckoutGithubGetCheckDetailsResponse, PreviewListConfigResponse, PreviewStartResponse, PreviewBindTabResponse, PreviewStopResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, GitHubSearchResponse, GitHubSearchRequest, GitHostingProviderId, HostingSearchRequest, HostingSearchResponse, HostingAuthStatusResponse, DirectorySuggestionsResponse, OttoWorktreeListResponse, OttoWorktreeArchiveResponse, ProjectIconResponse, ContextCategory, ContextPromptPreviewGetResponseMessage, ContextReportGetResponseMessage, ContextEdgeConvertResponseMessage, ContextFindingsFixResponseMessage, PersonalityMemoryListResponseMessage, PersonalityMemoryUpdateResponseMessage, PersonalityMemoryTransferResponseMessage, PersonalityMemoryStatsResponseMessage, ProjectAddResponse, ProjectScaffoldGit, ProjectScaffoldProgress, ProjectScaffoldResponse, HostingListRepositoriesResponse, HostingListOwnersResponse, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceArchivePreflightResponse, WorktreeBaseRefSetResponse, WorktreeReattachListResponse, WorktreeReattachResponse, WorktreeReattachTarget, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, StatsActivityGetResponseMessage, StatsActivityResetResponseMessage, UsageLogGetResponseMessage, AgentContextGetUsageResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, AttachmentsImagesClearResponse, AttachmentsImagesStatsResponse, HistoryAgentsClearArchivedResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, AgentPromptDelivery, TasksSuggestedStartMode, OttoConfigRaw, OttoConfigRevision, WorkspaceCreateRequest } from "@otto-code/protocol/messages";
6
+ import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreateOttoWorktreeRequest, CodeListFilesResponse, CodeSymbolLocation, CodeDefinitionLocation, CodeDefinitionStatus, CodeRenameApplyStatus, CodeRenameFileOutcome, CodeRenameUndoFile, CodeRenameUndoStatus, CodeHoverRange, CodeRenameEdit, CodeRenameFilePlan, LspLanguageState, LspRunningServer, CodeSolutionGetTreeResponse, CodeSolutionLoadProjectResponse, SolutionFormat, SolutionRef, SolutionTreeFolder, SolutionTreeProject, SolutionProjectNode, SolutionProjectStatus, SolutionPackageReference, FileCreateResult, FileDeleteResult, FileDownloadTokenResponse, FileEntryKind, FileEol, FileRenameResult, FileReplaceFileResult, FileReplaceRequest, FileReplaceResponse, FileSearchResultPayload, FileSearchSummary, FileUploadResponse, FileExplorerResponse, FileWatchEventPayload, FileWriteResult, FileRefineResult, FileRefineDocument, FileRefineReference, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommitResponse, CheckoutGitCommitResponse, CheckoutGitCommitAgentResponse, CheckoutGitRollbackResponse, CheckoutGitFileHistoryResponse, CheckoutGitFileCommitDiffResponse, CheckoutGitFileBlameResponse, CheckoutGitFileOriginResponse, CheckoutGitGetOperationLogResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutGithubSetAutoMergeResponse, CheckoutGithubGetCheckDetailsResponse, PreviewListConfigResponse, PreviewStartResponse, PreviewBindTabResponse, PreviewStopResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, FileVersion, CheckoutCommit, ParsedDiffFile, WorkspaceRecoveryState, CheckoutForgeGetCheckDetailsResponse, CheckoutForgeSetAutoMergeResponse, ProjectCreateDirectoryResponse, FsFileWriteResult, FsFileWriteBinaryResult, GitHubSearchResponse, GitHubSearchRequest, ForgeSearchResponse, ForgeSearchRequest, GitHostingProviderId, HostingSearchRequest, HostingSearchResponse, HostingAuthStatusResponse, DirectorySuggestionsResponse, OttoWorktreeListResponse, OttoWorktreeArchiveResponse, ProjectIconResponse, ContextCategory, ContextPromptPreviewGetResponseMessage, ContextReportGetResponseMessage, ContextEdgeConvertResponseMessage, ContextFindingsFixResponseMessage, PersonalityMemoryListResponseMessage, PersonalityMemoryUpdateResponseMessage, PersonalityMemoryTransferResponseMessage, PersonalityMemoryStatsResponseMessage, ProjectAddResponse, ProjectScaffoldGit, ProjectScaffoldProgress, ProjectScaffoldResponse, HostingListRepositoriesResponse, HostingListOwnersResponse, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceArchivePreflightResponse, WorktreeBaseRefSetResponse, WorktreeReattachListResponse, WorktreeReattachResponse, WorktreeReattachTarget, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, StatsActivityGetResponseMessage, StatsActivityResetResponseMessage, UsageLogGetResponseMessage, AgentContextGetUsageResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, AttachmentsImagesClearResponse, AttachmentsImagesStatsResponse, HistoryAgentsClearArchivedResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, AgentPromptDelivery, TasksSuggestedStartMode, OttoConfigRaw, OttoConfigRevision, WorkspaceCreateRequest } from "@otto-code/protocol/messages";
5
7
  import type { AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, AgentProviderNotice, AgentProvider, AgentSessionConfig } from "@otto-code/protocol/agent-types";
6
8
  import type { OrchestrationGraph, PromptTemplate, Run } from "@otto-code/protocol/orchestration";
7
- import type { BrainCatalogModel, BrainEvals, BrainHfSearchResult, BrainHostStatus, BrainInstalledModel, BrainJob, BrainNetworkInfo, BrainRemoteConfig, BrainRepoQuant, BrainRuntime, ConnectorsListToolsResponse, CueMoment, MutableDaemonConfig, MutableDaemonConfigPatch, ProjectLink, SpeechSettingsOptions, SpeechTtsPreviewResult, SpeechTtsSpeakResult, SpeechTtsSpeakCancelResult, VisualizerVoiceCuesResult, AgentPersonalitiesGenerateProfileResult } from "@otto-code/protocol/messages";
9
+ import type { BrainCatalogModel, BrainDiskUsage, BrainEvals, BrainHfSearchResult, BrainHostStatus, BrainInstalledModel, BrainInventoryModel, BrainJob, BrainLogsTailResponse, BrainModelBudgetGetResponse, BrainModelDeleteResponse, BrainModelLoadResponse, BrainModelProfileGetResponse, BrainModelProfileSetResponse, BrainNetworkInfo, BrainRemoteConfig, BrainRepoQuant, BrainRuntime, ConnectorsListToolsResponse, ConnectorsOauthAuthorizeResponse, ConnectorsOauthDisconnectResponse, CueMoment, MutableDaemonConfig, MutableDaemonConfigPatch, ProjectLink, SpeechSettingsOptions, SpeechTtsPreviewResult, SpeechTtsSpeakResult, SpeechTtsSpeakCancelResult, VisualizerVoiceCuesResult, AgentPersonalitiesGenerateProfileResult } from "@otto-code/protocol/messages";
8
10
  import { type DaemonTransportFactory, type WebSocketFactory } from "./daemon-client-transport.js";
9
11
  import { type DaemonClientTrafficHotspot, type DaemonClientTrafficTotals } from "./daemon-client-runtime-metrics.js";
10
12
  import { type TerminalStreamEvent } from "./terminal-stream-router.js";
@@ -156,6 +158,12 @@ export interface CreateAgentRequestOptions extends AgentConfigOverrides {
156
158
  personality?: CreateAgentRequestMessage["personality"];
157
159
  env?: CreateAgentRequestMessage["env"];
158
160
  workspaceId?: string;
161
+ /**
162
+ * Caller agent making this request. The daemon resolves the caller's own
163
+ * workspace and parentage from it, so a managed CLI run nests under its
164
+ * parent exactly as agent-scoped MCP creation does.
165
+ */
166
+ callerAgentId?: string;
159
167
  initialPrompt?: string;
160
168
  clientMessageId?: string;
161
169
  outputSchema?: Record<string, unknown>;
@@ -168,7 +176,7 @@ export interface CreateAgentRequestOptions extends AgentConfigOverrides {
168
176
  requestId?: string;
169
177
  labels?: Record<string, string>;
170
178
  }
171
- export interface CreateOttoWorktreeInput extends Pick<CreateOttoWorktreeRequest, "cwd" | "projectId" | "worktreeSlug" | "firstAgentContext" | "refName" | "action" | "githubPrNumber"> {
179
+ export interface CreateOttoWorktreeInput extends Pick<CreateOttoWorktreeRequest, "cwd" | "projectId" | "worktreeSlug" | "firstAgentContext" | "refName" | "action" | "githubPrNumber" | "checkoutSource"> {
172
180
  }
173
181
  type CheckoutStatusPayload = CheckoutStatusResponse["payload"];
174
182
  type SubscribeCheckoutDiffPayload = Extract<SessionOutboundMessage, {
@@ -207,6 +215,23 @@ type StashListPayload = StashListResponse["payload"];
207
215
  type ValidateBranchPayload = ValidateBranchResponse["payload"];
208
216
  type BranchSuggestionsPayload = BranchSuggestionsResponse["payload"];
209
217
  type GitHubSearchPayload = GitHubSearchResponse["payload"];
218
+ type CheckoutForgeGetCheckDetailsPayload = CheckoutForgeGetCheckDetailsResponse["payload"];
219
+ type CheckoutForgeSetAutoMergePayload = CheckoutForgeSetAutoMergeResponse["payload"];
220
+ export type ProjectCreateDirectoryPayload = ProjectCreateDirectoryResponse["payload"];
221
+ export type ProjectListPayload = Extract<SessionOutboundMessage, {
222
+ type: "project.list.response";
223
+ }>["payload"];
224
+ export type WorkspaceGithubSearchRepositoriesPayload = Extract<SessionOutboundMessage, {
225
+ type: "workspace.github.search_repositories.response";
226
+ }>["payload"];
227
+ export interface AgentAttentionRequiredNotification {
228
+ agentId: string;
229
+ reason: "finished" | "error" | "permission";
230
+ timestamp: string;
231
+ shouldNotify: boolean;
232
+ notification?: AgentAttentionNotificationPayload;
233
+ }
234
+ type ForgeSearchPayload = ForgeSearchResponse["payload"];
210
235
  export type HostingSearchPayload = HostingSearchResponse["payload"];
211
236
  export type HostingAuthStatusPayload = HostingAuthStatusResponse["payload"];
212
237
  type DirectorySuggestionsPayload = DirectorySuggestionsResponse["payload"];
@@ -230,10 +255,12 @@ export interface FileReadResult {
230
255
  modifiedAt: string;
231
256
  /**
232
257
  * Detected line endings. Optional because only the inline JSON read path
233
- * reports them the chunked binary transfer never does, and neither do
258
+ * reports them - the chunked binary transfer never does, and neither do
234
259
  * daemons older than v0.4.4. Absent means "not reported", not "LF".
235
260
  */
236
261
  eol?: FileEol;
262
+ /** Opaque version tag for optimistic-concurrency writes; same caveat as eol. */
263
+ revision?: string;
237
264
  }
238
265
  export interface TextFileReadResult {
239
266
  path: string;
@@ -255,7 +282,24 @@ export interface FileWriteOptions {
255
282
  requestId?: string;
256
283
  }
257
284
  /**
258
- * The general file-mutation surface what exists in a directory, rather than
285
+ * Bytes to a workspace path. Gated on `features.binaryFileWrite`. Unlike
286
+ * {@link FileWriteOptions} this carries no precondition: `overwrite` is the
287
+ * whole policy - see `FsFileWriteBinaryRequestSchema` for why a generated
288
+ * artifact has nothing to reconcile against.
289
+ */
290
+ export interface FileWriteBinaryOptions {
291
+ cwd: string;
292
+ /** Workspace-relative, like every other file RPC. */
293
+ path: string;
294
+ /** Sent as file-transfer frames, not inside the request. */
295
+ bytes: Uint8Array | ArrayBuffer;
296
+ overwrite?: boolean;
297
+ requestId?: string;
298
+ /** Frame size, for tests that want to observe chunking. Defaults to 1 MB. */
299
+ chunkSize?: number;
300
+ }
301
+ /**
302
+ * The general file-mutation surface - what exists in a directory, rather than
259
303
  * what is inside a file. Gated on `features.fileMutations`; there is no
260
304
  * client-side substitute, so callers check the flag before offering the action.
261
305
  */
@@ -281,14 +325,14 @@ export interface FileRenameOptions {
281
325
  requestId?: string;
282
326
  }
283
327
  /**
284
- * Refine ask the daemon for proposed rewrites of a pinned set of documents.
328
+ * Refine - ask the daemon for proposed rewrites of a pinned set of documents.
285
329
  * This call never writes: accepted proposals go back through {@link
286
330
  * DaemonClient.writeFile}, one per file, like any other save.
287
331
  */
288
332
  export interface FileRefineOptions {
289
333
  /** Provider resolution only; the documents themselves travel inline. */
290
334
  cwd: string;
291
- /** What the model may rewrite this list is the request's blast radius. */
335
+ /** What the model may rewrite - this list is the request's blast radius. */
292
336
  documents: FileRefineDocument[];
293
337
  /** What it may read for context but must never rewrite. */
294
338
  references?: FileRefineReference[];
@@ -541,7 +585,21 @@ export interface FetchAgentTimelineOptions {
541
585
  requestId?: string;
542
586
  timeout?: number;
543
587
  }
588
+ export type ProviderSubagentListPayload = Extract<SessionOutboundMessage, {
589
+ type: "agent.provider_subagents.list.response";
590
+ }>["payload"];
591
+ export type ProviderSubagentTimelinePayload = Extract<SessionOutboundMessage, {
592
+ type: "agent.provider_subagents.timeline.get.response";
593
+ }>["payload"];
594
+ export interface FetchProviderSubagentTimelineOptions {
595
+ direction?: ProviderSubagentTimelinePayload["direction"];
596
+ cursor?: FetchAgentTimelineCursor;
597
+ limit?: number;
598
+ requestId?: string;
599
+ timeout?: number;
600
+ }
544
601
  export interface AgentForkContextOptions {
602
+ boundaryCursor?: FetchAgentTimelineCursor;
545
603
  boundaryMessageId?: string;
546
604
  requestId?: string;
547
605
  }
@@ -779,6 +837,9 @@ export interface WaitForFinishResult {
779
837
  error: string | null;
780
838
  lastMessage: string | null;
781
839
  }
840
+ type ProjectGithubClonePayload = Extract<SessionOutboundMessage, {
841
+ type: "project.github.clone.response";
842
+ }>["payload"];
782
843
  export declare class DaemonClient {
783
844
  private config;
784
845
  private transport;
@@ -801,6 +862,7 @@ export declare class DaemonClient {
801
862
  private connectionState;
802
863
  private checkoutDiffSubscriptions;
803
864
  private terminalDirectorySubscriptions;
865
+ private fileSubscriptions;
804
866
  private readonly terminalStreams;
805
867
  private readonly scaffoldProgressListeners;
806
868
  private pendingBinaryFileReads;
@@ -946,7 +1008,7 @@ export declare class DaemonClient {
946
1008
  * the whole archived set. Pass `dryRun: true` first to get the count the
947
1009
  * confirm dialog quotes, then the same call with `dryRun: false` to delete.
948
1010
  *
949
- * Removes Otto's records only provider transcripts are left on disk. Gated
1011
+ * Removes Otto's records only - provider transcripts are left on disk. Gated
950
1012
  * by `server_info.features.historyDelete`; there is no fallback path, so check
951
1013
  * the flag before offering the action.
952
1014
  */
@@ -967,7 +1029,7 @@ export declare class DaemonClient {
967
1029
  * `dryRun: false` to delete.
968
1030
  *
969
1031
  * Cleared images do not come back: a message that referenced one renders its
970
- * alt text from then on. Scope is the whole host filenames are a content
1032
+ * alt text from then on. Scope is the whole host - filenames are a content
971
1033
  * hash, so per-chat or per-workspace scope does not exist. Gated by
972
1034
  * `server_info.features.attachmentStorage`.
973
1035
  */
@@ -988,7 +1050,7 @@ export declare class DaemonClient {
988
1050
  stopObservedSubagent(agentId: string): Promise<void>;
989
1051
  /**
990
1052
  * Stop a running background shell task (Claude Bash tool run_in_background).
991
- * Not an AI subagent the daemon resolves it to its owning provider task and
1053
+ * Not an AI subagent - the daemon resolves it to its owning provider task and
992
1054
  * calls the provider's stopTask, same mechanism as stopObservedSubagent.
993
1055
  */
994
1056
  stopBackgroundShellTask(parentAgentId: string, taskId: string): Promise<void>;
@@ -999,7 +1061,7 @@ export declare class DaemonClient {
999
1061
  clearBackgroundShellTasks(parentAgentId: string, taskIds: readonly string[]): Promise<void>;
1000
1062
  /**
1001
1063
  * Start one or more suggested tasks (from `spawn_task` chips), applying the
1002
- * same mode to each a new worktree workspace per task, a new local session
1064
+ * same mode to each - a new worktree workspace per task, a new local session
1003
1065
  * per task, or steering the parent's current session. Individual actions pass
1004
1066
  * a single-element array; the "Start all" collective action passes the whole
1005
1067
  * pending queue. Resolves to the count started; throws only if all failed.
@@ -1025,7 +1087,7 @@ export declare class DaemonClient {
1025
1087
  clearFinishedRuns(): Promise<string[]>;
1026
1088
  /**
1027
1089
  * Orchestration: delete one finished (or draft) run. Throws with the
1028
- * daemon's reason when it refuses an active run has to be canceled first.
1090
+ * daemon's reason when it refuses - an active run has to be canceled first.
1029
1091
  */
1030
1092
  deleteRun(runId: string): Promise<string>;
1031
1093
  /** Orchestration: list the host's reusable graph templates. */
@@ -1091,6 +1153,55 @@ export declare class DaemonClient {
1091
1153
  resumeAgent(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>): Promise<AgentSnapshotPayload>;
1092
1154
  importAgent(input: ImportAgentInput): Promise<AgentSnapshotPayload>;
1093
1155
  refreshAgent(agentId: string, requestId?: string): Promise<AgentRefreshedStatusPayload>;
1156
+ listProviderSubagents(parentAgentId: string, options?: {
1157
+ requestId?: string;
1158
+ timeout?: number;
1159
+ }): Promise<ProviderSubagentListPayload>;
1160
+ fetchProviderSubagentTimeline(parentAgentId: string, subagentId: string, options?: FetchProviderSubagentTimelineOptions): Promise<ProviderSubagentTimelinePayload>;
1161
+ checkoutForgeGetCheckDetails(input: {
1162
+ cwd: string;
1163
+ repoOwner?: string;
1164
+ repoName?: string;
1165
+ checkRunId?: number;
1166
+ workflowRunId?: number;
1167
+ changeRequestNumber?: number;
1168
+ }, requestId?: string): Promise<CheckoutForgeGetCheckDetailsPayload>;
1169
+ checkoutForgeSetAutoMerge(cwd: string, input: {
1170
+ enabled: true;
1171
+ method: CheckoutPrMergeMethod;
1172
+ } | {
1173
+ enabled: false;
1174
+ }, requestId?: string): Promise<CheckoutForgeSetAutoMergePayload>;
1175
+ createProjectDirectory(input: {
1176
+ parentPath: string;
1177
+ name: string;
1178
+ }, requestId?: string): Promise<ProjectCreateDirectoryPayload>;
1179
+ getCommitFileDiff(cwd: string, sha: string, path: string, requestId?: string): Promise<{
1180
+ file: ParsedDiffFile | null;
1181
+ }>;
1182
+ inspectWorkspaceRecovery(workspaceId: string, requestId?: string): Promise<WorkspaceRecoveryState>;
1183
+ listCheckoutCommits(cwd: string, requestId?: string): Promise<{
1184
+ baseRef: string | null;
1185
+ commits: CheckoutCommit[];
1186
+ }>;
1187
+ listProjects(requestId?: string): Promise<ProjectListPayload>;
1188
+ onAgentAttentionRequired(handler: (notification: AgentAttentionRequiredNotification) => void): () => void;
1189
+ restoreWorkspace(workspaceId: string, requestId?: string): Promise<void>;
1190
+ searchGithubRepositories(input: {
1191
+ query: string;
1192
+ limit?: number;
1193
+ }, requestId?: string): Promise<WorkspaceGithubSearchRepositoriesPayload>;
1194
+ setAgentTimelineSubscription(agentIds: string[]): Promise<void>;
1195
+ setWorkspacePinned(workspaceId: string, pinned: boolean, requestId?: string): Promise<{
1196
+ pinnedAt: string | null;
1197
+ }>;
1198
+ subscribeFile(input: {
1199
+ cwd: string;
1200
+ path: string;
1201
+ }, onUpdate: (version: FileVersion) => void): Promise<{
1202
+ initial: FileVersion;
1203
+ unsubscribe: () => void;
1204
+ }>;
1094
1205
  fetchAgentTimeline(agentId: string, options?: FetchAgentTimelineOptions): Promise<FetchAgentTimelinePayload>;
1095
1206
  buildAgentForkContext(agentId: string, options?: AgentForkContextOptions): Promise<AgentForkContextPayload>;
1096
1207
  sendAgentMessage(agentId: string, text: string, options?: SendMessageOptions): Promise<SendAgentMessageResult>;
@@ -1106,7 +1217,7 @@ export declare class DaemonClient {
1106
1217
  } | null>;
1107
1218
  /**
1108
1219
  * Move one queued message to a new position. Resolves false when the entry
1109
- * was already drained or was already there the authoritative order arrives
1220
+ * was already drained or was already there - the authoritative order arrives
1110
1221
  * on the agent snapshot either way. Requires
1111
1222
  * `server_info.features.steerQueueReorder`.
1112
1223
  */
@@ -1118,13 +1229,13 @@ export declare class DaemonClient {
1118
1229
  cancelled?: boolean;
1119
1230
  }>;
1120
1231
  setAgentMode(agentId: string, modeId: string): Promise<AgentProviderNotice | null>;
1121
- setAgentModel(agentId: string, modelId: string | null): Promise<void>;
1232
+ setAgentModel(agentId: string, modelId: string | null): Promise<AgentProviderNotice | null>;
1122
1233
  setAgentFeature(agentId: string, featureId: string, value: unknown): Promise<void>;
1123
1234
  setAgentThinkingOption(agentId: string, thinkingOptionId: string | null): Promise<AgentProviderNotice | null>;
1124
1235
  /**
1125
1236
  * Live-switch a running agent's personality (null clears it). The daemon
1126
1237
  * re-resolves the roster id against the agent's cwd and applies the full
1127
- * personality system prompt, identity, model/mode/effort restarting the
1238
+ * personality - system prompt, identity, model/mode/effort - restarting the
1128
1239
  * provider query so the prompt takes effect on the next turn. Gate on
1129
1240
  * server_info.features.setAgentPersonality.
1130
1241
  */
@@ -1276,6 +1387,12 @@ export declare class DaemonClient {
1276
1387
  query?: string;
1277
1388
  limit?: number;
1278
1389
  }, requestId?: string): Promise<BranchSuggestionsPayload>;
1390
+ searchForge(options: {
1391
+ cwd: string;
1392
+ query: string;
1393
+ limit?: number;
1394
+ kinds?: ForgeSearchRequest["kinds"];
1395
+ }, requestId?: string): Promise<ForgeSearchPayload>;
1279
1396
  searchGitHub(options: {
1280
1397
  cwd: string;
1281
1398
  query: string;
@@ -1307,11 +1424,39 @@ export declare class DaemonClient {
1307
1424
  * save-precondition baseline (modifiedAt, eol, hash) alongside the content.
1308
1425
  */
1309
1426
  readTextFile(cwd: string, path: string, requestId?: string): Promise<TextFileReadResult>;
1310
- /** Conditional save — see FileWriteRequestSchema for the no-clobber contract. */
1427
+ /**
1428
+ * The fs.file.write RPC: optimistic-concurrency writes keyed by an opaque
1429
+ * revision. The hash-keyed `writeFile` below is kept for callers
1430
+ * that have not moved over.
1431
+ */
1432
+ writeFsFile(input: {
1433
+ cwd: string;
1434
+ path: string;
1435
+ content: string;
1436
+ expectedModifiedAt: string;
1437
+ expectedRevision?: string;
1438
+ }): Promise<FsFileWriteResult>;
1439
+ /** Conditional save - see FileWriteRequestSchema for the no-clobber contract. */
1311
1440
  writeFile(options: FileWriteOptions): Promise<FileWriteResult>;
1312
- /** Create an empty file or a directory. Never overwrites — see FileCreateResultSchema. */
1441
+ /**
1442
+ * Write bytes to a workspace file - the path for generated artifacts the
1443
+ * text write cannot carry (it refuses binary targets outright). Gated on
1444
+ * `features.binaryFileWrite`; there is no client-side substitute, because
1445
+ * the client never touches a workspace file on any platform.
1446
+ *
1447
+ * Shaped like {@link uploadFile}: the JSON request says where the bytes go
1448
+ * and how many to expect, then the bytes follow as file-transfer frames
1449
+ * correlated on the same `requestId`. The daemon answers at FileEnd.
1450
+ */
1451
+ writeBinaryFile(options: FileWriteBinaryOptions): Promise<FsFileWriteBinaryResult>;
1452
+ /**
1453
+ * FileBegin, chunks, FileEnd. Synchronous through `sendBinaryFrame`, so the
1454
+ * frames leave in order and behind the JSON request that announced them.
1455
+ */
1456
+ private sendFileTransfer;
1457
+ /** Create an empty file or a directory. Never overwrites - see FileCreateResultSchema. */
1313
1458
  createFileEntry(options: FileCreateOptions): Promise<FileCreateResult>;
1314
- /** Permanent delete an unlink, not a move to any trash. */
1459
+ /** Permanent delete - an unlink, not a move to any trash. */
1315
1460
  deleteFileEntry(options: FileDeleteOptions): Promise<FileDeleteResult>;
1316
1461
  /** Rename, which is also move. Never clobbers an occupied destination. */
1317
1462
  renameFileEntry(options: FileRenameOptions): Promise<FileRenameResult>;
@@ -1338,7 +1483,7 @@ export declare class DaemonClient {
1338
1483
  findCodeDefinition(input: CodeDefinitionQuery, requestId?: string): Promise<CodeDefinitionResult>;
1339
1484
  /**
1340
1485
  * Mirror the editor's current buffer to the daemon so definitions resolve against
1341
- * unsaved edits. Debounced by the caller this is not a per-keystroke RPC.
1486
+ * unsaved edits. Debounced by the caller - this is not a per-keystroke RPC.
1342
1487
  */
1343
1488
  syncCodeDocument(cwd: string, path: string, text: string, requestId?: string): Promise<void>;
1344
1489
  /** Release the daemon-side mirror when a file tab closes. */
@@ -1352,7 +1497,7 @@ export declare class DaemonClient {
1352
1497
  /** Every reference to the symbol at a position, for the references results tab. */
1353
1498
  findCodeReferences(input: CodeDefinitionQuery, requestId?: string): Promise<CodeReferencesResult>;
1354
1499
  /**
1355
- * A rename **dry run** every edit it would make, and nothing written. The client
1500
+ * A rename **dry run** - every edit it would make, and nothing written. The client
1356
1501
  * puts this in front of the user as a job to audit before applying.
1357
1502
  */
1358
1503
  previewCodeRename(input: CodeRenamePreviewQuery, requestId?: string): Promise<CodeRenamePlan>;
@@ -1386,7 +1531,7 @@ export declare class DaemonClient {
1386
1531
  *
1387
1532
  * Never throws and never carries an error the caller has to render. A workspace with no
1388
1533
  * solution, a host with no .NET SDK, and a host with the feature switched off all answer with an
1389
- * empty list, so the caller has one silent case "no switcher" rather than four states.
1534
+ * empty list, so the caller has one silent case - "no switcher" - rather than four states.
1390
1535
  */
1391
1536
  listSolutions(cwd: string, requestId?: string): Promise<SolutionRef[]>;
1392
1537
  /** One solution's organisation: folders, the projects inside them, configurations. */
@@ -1407,7 +1552,7 @@ export declare class DaemonClient {
1407
1552
  }, requestId?: string): Promise<SolutionProjectContents>;
1408
1553
  /** Definition symbols for a single file (document outline). */
1409
1554
  getCodeOutline(cwd: string, path: string, requestId?: string): Promise<CodeSymbolLocation[]>;
1410
- /** Preview-first project replace see FileReplaceRequestSchema. */
1555
+ /** Preview-first project replace - see FileReplaceRequestSchema. */
1411
1556
  replaceFiles(options: {
1412
1557
  cwd: string;
1413
1558
  replacement: string;
@@ -1461,7 +1606,7 @@ export declare class DaemonClient {
1461
1606
  *
1462
1607
  * Pass `workspaceId` whenever the write may be project-scoped: the daemon
1463
1608
  * binds the entry to the repo root that workspace resolves to, and an entry
1464
- * scoped to "project" with no root is filtered out of every brief stored,
1609
+ * scoped to "project" with no root is filtered out of every brief - stored,
1465
1610
  * listed, and never sent.
1466
1611
  */
1467
1612
  updatePersonalityMemory(input: {
@@ -1538,7 +1683,23 @@ export declare class DaemonClient {
1538
1683
  config: MutableDaemonConfig;
1539
1684
  }>;
1540
1685
  connectorsListTools(connectorId: string, requestId?: string): Promise<ConnectorsListToolsResponse["payload"]>;
1541
- brainHostStatus(requestId?: string): Promise<BrainHostStatus>;
1686
+ /**
1687
+ * Start a connector's OAuth login. Resolves with the URL to open, or with
1688
+ * status "authorized" when the daemon already held a usable token. The login
1689
+ * itself settles later on the `connectors.oauth.status` push, because the user
1690
+ * is in a browser by then.
1691
+ */
1692
+ connectorsOauthAuthorize(connectorId: string, scope?: string, requestId?: string): Promise<ConnectorsOauthAuthorizeResponse["payload"]>;
1693
+ /** Drop a connector's stored authorization. */
1694
+ connectorsOauthDisconnect(connectorId: string, requestId?: string): Promise<ConnectorsOauthDisconnectResponse["payload"]>;
1695
+ /**
1696
+ * The brain's status. Pass `resources` only from a surface that renders the
1697
+ * live CPU/RAM/GPU/slot numbers: it costs an `nvidia-smi` spawn plus a /slots
1698
+ * round trip on the brain, and this call is also the liveness poll.
1699
+ */
1700
+ brainHostStatus(options?: {
1701
+ resources?: boolean;
1702
+ }, requestId?: string): Promise<BrainHostStatus>;
1542
1703
  brainHostStart(model?: string | null, requestId?: string): Promise<BrainHostStatus>;
1543
1704
  brainHostStop(requestId?: string): Promise<BrainHostStatus>;
1544
1705
  brainHostRestart(model?: string | null, requestId?: string): Promise<BrainHostStatus>;
@@ -1560,6 +1721,40 @@ export declare class DaemonClient {
1560
1721
  brainBench(model?: string | null, requestId?: string): Promise<BrainJob>;
1561
1722
  brainJobsList(requestId?: string): Promise<BrainJob[]>;
1562
1723
  brainJobsCancel(jobId: string, requestId?: string): Promise<BrainJob[]>;
1724
+ /**
1725
+ * The joined model inventory: scan row, GGUF metadata, saved profile,
1726
+ * calibration state, VRAM budget and benchmark score per model, plus disk
1727
+ * usage. One call feeds the whole Models tab.
1728
+ */
1729
+ brainModelsInventory(requestId?: string): Promise<{
1730
+ models: BrainInventoryModel[];
1731
+ disk: BrainDiskUsage | null;
1732
+ }>;
1733
+ /** One model's saved profile, the field descriptors, and its warnings. */
1734
+ brainModelProfileGet(modelId: string, requestId?: string): Promise<BrainModelProfileGetResponse["payload"]>;
1735
+ /**
1736
+ * Write the editable profile fields. The reply carries the recomputed budget,
1737
+ * so an edit costs one round trip rather than a write the UI has to follow
1738
+ * with a read.
1739
+ */
1740
+ brainModelProfileSet(modelId: string, patch: Record<string, unknown>, requestId?: string): Promise<BrainModelProfileSetResponse["payload"]>;
1741
+ /**
1742
+ * The VRAM budget for a hypothetical profile. `overrides` are string-encoded
1743
+ * field values, so the UI can preview the budget while a control is mid-drag
1744
+ * without persisting a value the user is scrubbing past.
1745
+ */
1746
+ brainModelBudget(modelId: string, overrides?: Record<string, string>, requestId?: string): Promise<BrainModelBudgetGetResponse["payload"]>;
1747
+ /**
1748
+ * Load a model into the running brain. This is not `brainHostStart`, which
1749
+ * restarts the daemon's child process and has no remote equivalent.
1750
+ */
1751
+ brainModelLoad(modelId: string, requestId?: string): Promise<BrainModelLoadResponse["payload"]>;
1752
+ /** Unload the resident model, leaving the brain up and serving nothing. */
1753
+ brainModelUnload(requestId?: string): Promise<BrainHostStatus | null>;
1754
+ /** Delete a model's files. The brain refuses while that model is loaded. */
1755
+ brainModelDelete(modelId: string, requestId?: string): Promise<BrainModelDeleteResponse["payload"]>;
1756
+ /** Tail the brain's llama-server log. */
1757
+ brainLogsTail(limit?: number | null, requestId?: string): Promise<BrainLogsTailResponse["payload"]>;
1563
1758
  getSpeechSettingsOptions(requestId?: string): Promise<{
1564
1759
  requestId: string;
1565
1760
  options: SpeechSettingsOptions;
@@ -1613,7 +1808,7 @@ export declare class DaemonClient {
1613
1808
  listProviderUsage(options?: {
1614
1809
  requestId?: string;
1615
1810
  }): Promise<ProviderUsageListPayload>;
1616
- /** Daemon-wide "fun stats" see docs/data-model.md ActivityStatsStore. */
1811
+ /** Daemon-wide "fun stats" - see docs/data-model.md ActivityStatsStore. */
1617
1812
  getActivityStats(options?: {
1618
1813
  requestId?: string;
1619
1814
  }): Promise<StatsActivityGetResponseMessage["payload"]>;
@@ -1621,7 +1816,7 @@ export declare class DaemonClient {
1621
1816
  resetActivityStats(options?: {
1622
1817
  requestId?: string;
1623
1818
  }): Promise<StatsActivityResetResponseMessage["payload"]>;
1624
- /** Itemized usage ledger the scrollable rows behind the stats tiles (usage-ledger). */
1819
+ /** Itemized usage ledger - the scrollable rows behind the stats tiles (usage-ledger). */
1625
1820
  getUsageLog(options?: {
1626
1821
  limit?: number;
1627
1822
  before?: number;
@@ -1750,7 +1945,7 @@ export declare class DaemonClient {
1750
1945
  /**
1751
1946
  * Session totals for inbound daemon traffic, including the main-thread time
1752
1947
  * spent handling it. Null when runtime metrics are disabled for this client.
1753
- * Read by the app's resource monitor the wire is a first-class suspect when
1948
+ * Read by the app's resource monitor - the wire is a first-class suspect when
1754
1949
  * the UI thread degrades, so it has to be measurable rather than inferred.
1755
1950
  */
1756
1951
  getTrafficTotals(): DaemonClientTrafficTotals | null;
@@ -1775,8 +1970,67 @@ export declare class DaemonClient {
1775
1970
  private recordLivenessFailure;
1776
1971
  private handleSessionMessage;
1777
1972
  private resolveWaiters;
1973
+ private rejectWaitersForRequestId;
1778
1974
  private clearWaiters;
1779
1975
  private toEvent;
1780
1976
  private waitForWithCancel;
1977
+ cloneGithubProject(input: {
1978
+ repo: string;
1979
+ targetDirectory: string;
1980
+ cloneProtocol?: ProjectGithubCloneProtocol;
1981
+ }, requestId?: string): Promise<ProjectGithubClonePayload>;
1982
+ /**
1983
+ * `includeDiscovered` also returns the Scripts the workspace's own project
1984
+ * files declare (package.json scripts today), each tagged with its `source`.
1985
+ * Gate it on `server_info.features.workspaceScriptDiscovery` - an older
1986
+ * daemon ignores the flag and answers with the otto.json list only.
1987
+ */
1988
+ listWorkspaceScripts(workspaceId: string, options?: {
1989
+ includeDiscovered?: boolean;
1990
+ requestId?: string;
1991
+ }): Promise<Extract<SessionOutboundMessage, {
1992
+ type: "workspace.script.list.response";
1993
+ }>["payload"]>;
1994
+ startWorkspaceScriptWithStatus(workspaceId: string, scriptName: string, requestId?: string): Promise<Extract<SessionOutboundMessage, {
1995
+ type: "workspace.script.start.response";
1996
+ }>["payload"]>;
1997
+ stopWorkspaceScript(workspaceId: string, scriptName: string, requestId?: string): Promise<Extract<SessionOutboundMessage, {
1998
+ type: "workspace.script.stop.response";
1999
+ }>["payload"]>;
2000
+ connectHub(hubUrl: string, token: string, requestId?: string): Promise<{
2001
+ requestId: string;
2002
+ status: {
2003
+ state: "connected" | "connecting" | "not_connected" | "reconnecting" | "disconnecting" | "revoked";
2004
+ daemonId: string | null;
2005
+ hubOrigin: string | null;
2006
+ scopes: string[];
2007
+ connectedAt: string | null;
2008
+ lastError: string | null;
2009
+ };
2010
+ }>;
2011
+ getHubStatus(requestId?: string): Promise<{
2012
+ requestId: string;
2013
+ status: {
2014
+ state: "connected" | "connecting" | "not_connected" | "reconnecting" | "disconnecting" | "revoked";
2015
+ daemonId: string | null;
2016
+ hubOrigin: string | null;
2017
+ scopes: string[];
2018
+ connectedAt: string | null;
2019
+ lastError: string | null;
2020
+ };
2021
+ }>;
2022
+ disconnectHub(force?: boolean, requestId?: string): Promise<{
2023
+ requestId: string;
2024
+ status: {
2025
+ state: "connected" | "connecting" | "not_connected" | "reconnecting" | "disconnecting" | "revoked";
2026
+ daemonId: string | null;
2027
+ hubOrigin: string | null;
2028
+ scopes: string[];
2029
+ connectedAt: string | null;
2030
+ lastError: string | null;
2031
+ };
2032
+ warning?: string | undefined;
2033
+ }>;
2034
+ private requireHubRelationshipSupport;
1781
2035
  }
1782
2036
  //# sourceMappingURL=daemon-client.d.ts.map