@getpaseo/client 0.1.101 → 0.1.102-beta.2

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,6 +1,6 @@
1
1
  import type { z } from "zod";
2
- import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, type ServerInfoStatusPayload } from "@getpaseo/protocol/messages";
3
- import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FetchAgentTimelineResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutGithubSetAutoMergeResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconResponse, ProjectAddResponse, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, PaseoConfigRaw, PaseoConfigRevision, WorkspaceCreateRequest } from "@getpaseo/protocol/messages";
2
+ import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, type ServerInfoStatusPayload } from "@getpaseo/protocol/messages";
3
+ import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutGithubSetAutoMergeResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconResponse, ProjectAddResponse, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, PaseoConfigRaw, PaseoConfigRevision, WorkspaceCreateRequest } from "@getpaseo/protocol/messages";
4
4
  import type { AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, AgentProviderNotice, AgentProvider, AgentSessionConfig } from "@getpaseo/protocol/agent-types";
5
5
  import type { MutableDaemonConfig, MutableDaemonConfigPatch } from "@getpaseo/protocol/messages";
6
6
  import { type DaemonTransportFactory, type WebSocketFactory } from "./daemon-client-transport.js";
@@ -224,9 +224,11 @@ export interface WriteProjectConfigInput {
224
224
  requestId?: string;
225
225
  }
226
226
  interface ListCommandsOptions {
227
+ agentId: string;
227
228
  requestId?: string;
228
229
  draftConfig?: ListCommandsDraftConfig;
229
230
  }
231
+ type LegacyListCommandsOptions = Omit<ListCommandsOptions, "agentId">;
230
232
  type SetVoiceModePayload = Extract<SessionOutboundMessage, {
231
233
  type: "set_voice_mode_response";
232
234
  }>["payload"];
@@ -302,19 +304,44 @@ type ScheduleUpdatePayload = Extract<SessionOutboundMessage, {
302
304
  type: "schedule/update/response";
303
305
  }>["payload"];
304
306
  export type FetchAgentTimelinePayload = FetchAgentTimelineResponseMessage["payload"];
307
+ export type AgentForkContextPayload = AgentForkContextResponseMessage["payload"];
305
308
  export type FetchAgentTimelineDirection = FetchAgentTimelinePayload["direction"];
306
309
  export type FetchAgentTimelineProjection = FetchAgentTimelinePayload["projection"];
307
310
  export type FetchAgentTimelineCursor = NonNullable<FetchAgentTimelinePayload["startCursor"]>;
311
+ export interface FetchAgentOptions {
312
+ agentId: string;
313
+ requestId?: string;
314
+ timeout?: number;
315
+ }
316
+ type LegacyFetchAgentOptions = Omit<FetchAgentOptions, "agentId">;
308
317
  export interface FetchAgentTimelineOptions {
309
318
  direction?: FetchAgentTimelineDirection;
310
319
  cursor?: FetchAgentTimelineCursor;
311
320
  limit?: number;
312
321
  projection?: FetchAgentTimelineProjection;
313
322
  requestId?: string;
323
+ timeout?: number;
324
+ }
325
+ export interface AgentForkContextOptions {
326
+ boundaryMessageId?: string;
327
+ requestId?: string;
314
328
  }
315
329
  type AgentRefreshedStatusPayload = z.infer<typeof AgentRefreshedStatusPayloadSchema>;
316
330
  type RestartRequestedStatusPayload = z.infer<typeof RestartRequestedStatusPayloadSchema>;
317
331
  type ShutdownRequestedStatusPayload = z.infer<typeof ShutdownRequestedStatusPayloadSchema>;
332
+ export interface ShutdownServerOptions {
333
+ requestId?: string;
334
+ timeout?: number;
335
+ }
336
+ export interface DaemonStatusOptions {
337
+ requestId?: string;
338
+ timeout?: number;
339
+ }
340
+ export interface DaemonPairingOfferOptions {
341
+ requestId?: string;
342
+ timeout?: number;
343
+ }
344
+ type DaemonUpdateResponse = z.infer<typeof DaemonUpdateResponseSchema>;
318
345
  type FetchAgentsPayload = Extract<SessionOutboundMessage, {
319
346
  type: "fetch_agents_response";
320
347
  }>["payload"];
@@ -323,6 +350,7 @@ type FetchAgentsRequest = Extract<SessionInboundMessage, {
323
350
  }>;
324
351
  export type FetchAgentsOptions = Omit<FetchAgentsRequest, "type" | "requestId"> & {
325
352
  requestId?: string;
353
+ timeout?: number;
326
354
  };
327
355
  export type FetchAgentsEntry = FetchAgentsPayload["entries"][number];
328
356
  export type FetchAgentsPageInfo = FetchAgentsPayload["pageInfo"];
@@ -384,6 +412,7 @@ export interface ReadChatMessagesOptions {
384
412
  since?: string;
385
413
  authorAgentId?: string;
386
414
  requestId?: string;
415
+ timeout?: number;
387
416
  }
388
417
  export interface WaitForChatMessagesOptions {
389
418
  room: string;
@@ -637,7 +666,9 @@ export declare class DaemonClient {
637
666
  }>["payload"]>;
638
667
  archiveWorkspace(workspaceId: string, requestId?: string): Promise<ArchiveWorkspacePayload>;
639
668
  fetchWorkspaceSetupStatus(workspaceId: string, requestId?: string): Promise<WorkspaceSetupStatusPayload>;
669
+ fetchAgent(options: FetchAgentOptions): Promise<FetchAgentResult | null>;
640
670
  fetchAgent(agentId: string, requestId?: string): Promise<FetchAgentResult | null>;
671
+ fetchAgent(agentId: string, options?: LegacyFetchAgentOptions): Promise<FetchAgentResult | null>;
641
672
  private resubscribeCheckoutDiffSubscriptions;
642
673
  private resubscribeTerminalDirectorySubscriptions;
643
674
  createAgent(options: CreateAgentRequestOptions): Promise<AgentSnapshotPayload>;
@@ -663,6 +694,7 @@ export declare class DaemonClient {
663
694
  importAgent(input: ImportAgentInput): Promise<AgentSnapshotPayload>;
664
695
  refreshAgent(agentId: string, requestId?: string): Promise<AgentRefreshedStatusPayload>;
665
696
  fetchAgentTimeline(agentId: string, options?: FetchAgentTimelineOptions): Promise<FetchAgentTimelinePayload>;
697
+ buildAgentForkContext(agentId: string, options?: AgentForkContextOptions): Promise<AgentForkContextPayload>;
666
698
  sendAgentMessage(agentId: string, text: string, options?: SendMessageOptions): Promise<void>;
667
699
  sendMessage(agentId: string, text: string, options?: SendMessageOptions): Promise<void>;
668
700
  rewindAgent(agentId: string, messageId: string, mode: "conversation" | "files" | "both"): Promise<AgentRewindResponseMessage["payload"]>;
@@ -672,7 +704,8 @@ export declare class DaemonClient {
672
704
  setAgentFeature(agentId: string, featureId: string, value: unknown): Promise<void>;
673
705
  setAgentThinkingOption(agentId: string, thinkingOptionId: string | null): Promise<AgentProviderNotice | null>;
674
706
  restartServer(reason?: string, requestId?: string): Promise<RestartRequestedStatusPayload>;
675
- shutdownServer(requestId?: string): Promise<ShutdownRequestedStatusPayload>;
707
+ shutdownServer(options?: ShutdownServerOptions): Promise<ShutdownRequestedStatusPayload>;
708
+ updateDaemon(requestId?: string): Promise<DaemonUpdateResponse["payload"]>;
676
709
  setVoiceMode(enabled: boolean, agentId?: string): Promise<SetVoiceModePayload>;
677
710
  sendVoiceAudioChunk(audio: string, format: string, isLast?: boolean): Promise<void>;
678
711
  startDictationStream(dictationId: string, format: string): Promise<void>;
@@ -823,8 +856,8 @@ export declare class DaemonClient {
823
856
  requestId: string;
824
857
  config: MutableDaemonConfig;
825
858
  }>;
826
- getDaemonStatus(requestId?: string): Promise<DaemonStatusPayload>;
827
- getDaemonPairingOffer(requestId?: string): Promise<DaemonPairingOfferPayload>;
859
+ getDaemonStatus(options?: DaemonStatusOptions): Promise<DaemonStatusPayload>;
860
+ getDaemonPairingOffer(options?: DaemonPairingOfferOptions): Promise<DaemonPairingOfferPayload>;
828
861
  collectDiagnostics(requestId?: string): Promise<DiagnosticsPayload>;
829
862
  patchDaemonConfig(config: MutableDaemonConfigPatch, requestId?: string): Promise<{
830
863
  requestId: string;
@@ -843,8 +876,9 @@ export declare class DaemonClient {
843
876
  listProviderUsage(options?: {
844
877
  requestId?: string;
845
878
  }): Promise<ProviderUsageListPayload>;
879
+ listCommands(options: ListCommandsOptions): Promise<ListCommandsPayload>;
846
880
  listCommands(agentId: string, requestId?: string): Promise<ListCommandsPayload>;
847
- listCommands(agentId: string, options?: ListCommandsOptions): Promise<ListCommandsPayload>;
881
+ listCommands(agentId: string, options?: LegacyListCommandsOptions): Promise<ListCommandsPayload>;
848
882
  respondToPermission(agentId: string, requestId: string, response: AgentPermissionResponse): Promise<void>;
849
883
  respondToPermissionAndWait(agentId: string, requestId: string, response: AgentPermissionResponse, timeout?: number): Promise<AgentPermissionResolvedPayload>;
850
884
  waitForAgentUpsert(agentId: string, predicate: (snapshot: AgentSnapshotPayload) => boolean, timeout?: number): Promise<AgentSnapshotPayload>;
@@ -1,5 +1,5 @@
1
1
  import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
2
- import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from "@getpaseo/protocol/messages";
2
+ import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from "@getpaseo/protocol/messages";
3
3
  import { isRelayClientWebSocketUrl } from "@getpaseo/protocol/daemon-endpoints";
4
4
  import { terminalSubscriptionKey } from "@getpaseo/protocol/terminal-subscription-key";
5
5
  import { asUint8Array, decodeFileTransferFrame, encodeFileTransferFrame, decodeTerminalStreamFrame, FileTransferOpcode, TerminalStreamOpcode, } from "@getpaseo/protocol/binary-frames/index";
@@ -21,6 +21,26 @@ function normalizePassword(value) {
21
21
  }
22
22
  return value.length > 0 ? value : null;
23
23
  }
24
+ // COMPAT(daemon-client-object-options): added in v0.1.102; remove after
25
+ // 2026-12-29 once SDK callers have migrated to object parameters.
26
+ function normalizeFetchAgentOptions(input, legacyOptions) {
27
+ if (typeof input !== "string") {
28
+ return input;
29
+ }
30
+ if (typeof legacyOptions === "string") {
31
+ return { agentId: input, requestId: legacyOptions };
32
+ }
33
+ return { agentId: input, ...legacyOptions };
34
+ }
35
+ function normalizeListCommandsOptions(input, legacyOptions) {
36
+ if (typeof input !== "string") {
37
+ return input;
38
+ }
39
+ if (typeof legacyOptions === "string") {
40
+ return { agentId: input, requestId: legacyOptions };
41
+ }
42
+ return { agentId: input, ...legacyOptions };
43
+ }
24
44
  class DaemonRpcError extends Error {
25
45
  constructor(params) {
26
46
  const parts = [params.error];
@@ -50,14 +70,15 @@ function toTimeoutError(error, label, timeoutMs) {
50
70
  }
51
71
  const DEFAULT_RECONNECT_BASE_DELAY_MS = 1500;
52
72
  const DEFAULT_RECONNECT_MAX_DELAY_MS = 30000;
73
+ const DEFAULT_SESSION_RPC_TIMEOUT_MS = 60000;
53
74
  const DEFAULT_CONNECT_TIMEOUT_MS = 15000;
54
75
  const DEFAULT_LIVENESS_TIMEOUT_MS = 5000;
55
76
  const LIVENESS_HEARTBEAT_INTERVAL_MS = 10000;
56
77
  const LIVENESS_HEARTBEAT_TIMEOUT_MS = 15000;
57
78
  const LIVENESS_FAILURE_RECONNECT_THRESHOLD = 2;
58
79
  /** Default timeout for waiting for connection before sending queued messages */
59
- const DEFAULT_SEND_QUEUE_TIMEOUT_MS = 10000;
60
- const DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS = 15000;
80
+ const DEFAULT_SEND_QUEUE_TIMEOUT_MS = DEFAULT_SESSION_RPC_TIMEOUT_MS;
81
+ const DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS = DEFAULT_SESSION_RPC_TIMEOUT_MS;
61
82
  const DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
62
83
  const DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS = 5000;
63
84
  function isWaiterTimeoutError(error) {
@@ -603,6 +624,7 @@ export class DaemonClient {
603
624
  }
604
625
  }
605
626
  async sendRequest(params) {
627
+ const timeout = params.timeout ?? DEFAULT_SESSION_RPC_TIMEOUT_MS;
606
628
  const { promise, cancel } = this.waitForWithCancel((msg) => {
607
629
  if (msg.type === "rpc_error" && msg.payload.requestId === params.requestId) {
608
630
  return {
@@ -620,7 +642,7 @@ export class DaemonClient {
620
642
  return null;
621
643
  }
622
644
  return { kind: "ok", value };
623
- }, params.timeout, params.options);
645
+ }, timeout, params.options);
624
646
  try {
625
647
  await this.sendSessionMessageOrThrow(params.message);
626
648
  }
@@ -702,7 +724,6 @@ export class DaemonClient {
702
724
  await this.sendRequest({
703
725
  requestId,
704
726
  message,
705
- timeout: 15000,
706
727
  options: { skipQueue: true },
707
728
  select: (msg) => {
708
729
  if (msg.type !== "clear_agent_attention_response") {
@@ -725,7 +746,6 @@ export class DaemonClient {
725
746
  const response = await this.sendRequest({
726
747
  requestId,
727
748
  message,
728
- timeout: 15000,
729
749
  options: { skipQueue: true },
730
750
  select: (msg) => {
731
751
  if (msg.type !== "workspace.clear_attention.response") {
@@ -891,7 +911,7 @@ export class DaemonClient {
891
911
  return this.sendRequest({
892
912
  requestId: resolvedRequestId,
893
913
  message,
894
- timeout: 10000,
914
+ timeout: options?.timeout,
895
915
  options: { skipQueue: true },
896
916
  select: (msg) => {
897
917
  if (msg.type !== "fetch_agents_response") {
@@ -916,7 +936,6 @@ export class DaemonClient {
916
936
  return this.sendRequest({
917
937
  requestId: resolvedRequestId,
918
938
  message,
919
- timeout: 10000,
920
939
  options: { skipQueue: true },
921
940
  select: (msg) => {
922
941
  if (msg.type !== "fetch_agent_history_response") {
@@ -942,7 +961,6 @@ export class DaemonClient {
942
961
  return this.sendRequest({
943
962
  requestId: resolvedRequestId,
944
963
  message,
945
- timeout: 10000,
946
964
  options: { skipQueue: true },
947
965
  select: (msg) => {
948
966
  if (msg.type !== "fetch_recent_provider_sessions_response") {
@@ -968,7 +986,6 @@ export class DaemonClient {
968
986
  return this.sendRequest({
969
987
  requestId: resolvedRequestId,
970
988
  message,
971
- timeout: 10000,
972
989
  options: { skipQueue: true },
973
990
  select: (msg) => {
974
991
  if (msg.type !== "fetch_workspaces_response") {
@@ -989,7 +1006,6 @@ export class DaemonClient {
989
1006
  cwd,
990
1007
  },
991
1008
  responseType: "open_project_response",
992
- timeout: 10000,
993
1009
  });
994
1010
  }
995
1011
  async addProject(cwd, requestId) {
@@ -1000,7 +1016,6 @@ export class DaemonClient {
1000
1016
  cwd,
1001
1017
  },
1002
1018
  responseType: "project.add.response",
1003
- timeout: 10000,
1004
1019
  });
1005
1020
  }
1006
1021
  async startWorkspaceScript(workspaceId, scriptName, requestId) {
@@ -1012,7 +1027,6 @@ export class DaemonClient {
1012
1027
  scriptName,
1013
1028
  },
1014
1029
  responseType: "start_workspace_script_response",
1015
- timeout: 10000,
1016
1030
  });
1017
1031
  }
1018
1032
  async archiveWorkspace(workspaceId, requestId) {
@@ -1023,7 +1037,6 @@ export class DaemonClient {
1023
1037
  workspaceId,
1024
1038
  },
1025
1039
  responseType: "archive_workspace_response",
1026
- timeout: 10000,
1027
1040
  });
1028
1041
  }
1029
1042
  async fetchWorkspaceSetupStatus(workspaceId, requestId) {
@@ -1034,20 +1047,20 @@ export class DaemonClient {
1034
1047
  workspaceId,
1035
1048
  },
1036
1049
  responseType: "workspace_setup_status_response",
1037
- timeout: 10000,
1038
1050
  });
1039
1051
  }
1040
- async fetchAgent(agentId, requestId) {
1041
- const resolvedRequestId = this.createRequestId(requestId);
1052
+ async fetchAgent(input, legacyOptions) {
1053
+ const options = normalizeFetchAgentOptions(input, legacyOptions);
1054
+ const resolvedRequestId = this.createRequestId(options.requestId);
1042
1055
  const message = SessionInboundMessageSchema.parse({
1043
1056
  type: "fetch_agent_request",
1044
1057
  requestId: resolvedRequestId,
1045
- agentId,
1058
+ agentId: options.agentId,
1046
1059
  });
1047
1060
  const payload = await this.sendRequest({
1048
1061
  requestId: resolvedRequestId,
1049
1062
  message,
1050
- timeout: 10000,
1063
+ timeout: options.timeout,
1051
1064
  options: { skipQueue: true },
1052
1065
  select: (msg) => {
1053
1066
  if (msg.type !== "fetch_agent_response") {
@@ -1126,7 +1139,6 @@ export class DaemonClient {
1126
1139
  const status = await this.sendRequest({
1127
1140
  requestId,
1128
1141
  message,
1129
- timeout: 60000,
1130
1142
  options: { skipQueue: true },
1131
1143
  select: (msg) => {
1132
1144
  if (msg.type !== "status") {
@@ -1158,7 +1170,6 @@ export class DaemonClient {
1158
1170
  await this.sendRequest({
1159
1171
  requestId,
1160
1172
  message,
1161
- timeout: 10000,
1162
1173
  options: { skipQueue: true },
1163
1174
  select: (msg) => {
1164
1175
  if (msg.type !== "agent_deleted") {
@@ -1181,7 +1192,6 @@ export class DaemonClient {
1181
1192
  const result = await this.sendRequest({
1182
1193
  requestId,
1183
1194
  message,
1184
- timeout: 10000,
1185
1195
  options: { skipQueue: true },
1186
1196
  select: (msg) => {
1187
1197
  if (msg.type !== "agent_archived") {
@@ -1201,7 +1211,6 @@ export class DaemonClient {
1201
1211
  type: "agent.detach.request",
1202
1212
  agentId,
1203
1213
  },
1204
- timeout: 10000,
1205
1214
  });
1206
1215
  if (!payload.accepted) {
1207
1216
  throw new Error(payload.error ?? "detachAgent rejected");
@@ -1221,7 +1230,6 @@ export class DaemonClient {
1221
1230
  const payload = await this.sendRequest({
1222
1231
  requestId,
1223
1232
  message,
1224
- timeout: 10000,
1225
1233
  options: { skipQueue: true },
1226
1234
  select: (msg) => {
1227
1235
  if (msg.type !== "update_agent_response") {
@@ -1246,7 +1254,6 @@ export class DaemonClient {
1246
1254
  customName,
1247
1255
  },
1248
1256
  responseType: "project.rename.response",
1249
- timeout: 10000,
1250
1257
  });
1251
1258
  if (!payload.accepted) {
1252
1259
  throw new Error(payload.error ?? "renameProject rejected");
@@ -1260,7 +1267,6 @@ export class DaemonClient {
1260
1267
  type: "project.remove.request",
1261
1268
  projectId,
1262
1269
  },
1263
- timeout: 10000,
1264
1270
  });
1265
1271
  if (!payload.accepted) {
1266
1272
  throw new Error(payload.error ?? "removeProject rejected");
@@ -1276,7 +1282,6 @@ export class DaemonClient {
1276
1282
  title,
1277
1283
  },
1278
1284
  responseType: "workspace.title.set.response",
1279
- timeout: 10000,
1280
1285
  });
1281
1286
  if (!payload.accepted) {
1282
1287
  throw new Error(payload.error ?? "setWorkspaceTitle rejected");
@@ -1294,7 +1299,6 @@ export class DaemonClient {
1294
1299
  const status = await this.sendRequest({
1295
1300
  requestId,
1296
1301
  message,
1297
- timeout: 15000,
1298
1302
  options: { skipQueue: true },
1299
1303
  select: (msg) => {
1300
1304
  if (msg.type !== "status") {
@@ -1323,7 +1327,6 @@ export class DaemonClient {
1323
1327
  const status = await this.sendRequest({
1324
1328
  requestId,
1325
1329
  message,
1326
- timeout: 15000,
1327
1330
  options: { skipQueue: true },
1328
1331
  select: (msg) => {
1329
1332
  if (msg.type !== "status") {
@@ -1355,7 +1358,6 @@ export class DaemonClient {
1355
1358
  return this.sendRequest({
1356
1359
  requestId: resolvedRequestId,
1357
1360
  message,
1358
- timeout: 15000,
1359
1361
  options: { skipQueue: true },
1360
1362
  select: (msg) => {
1361
1363
  if (msg.type !== "status") {
@@ -1383,7 +1385,7 @@ export class DaemonClient {
1383
1385
  const payload = await this.sendRequest({
1384
1386
  requestId: resolvedRequestId,
1385
1387
  message,
1386
- timeout: 15000,
1388
+ timeout: options.timeout,
1387
1389
  options: { skipQueue: true },
1388
1390
  select: (msg) => {
1389
1391
  if (msg.type !== "fetch_agent_timeline_response") {
@@ -1400,6 +1402,34 @@ export class DaemonClient {
1400
1402
  }
1401
1403
  return payload;
1402
1404
  }
1405
+ async buildAgentForkContext(agentId, options = {}) {
1406
+ const resolvedRequestId = this.createRequestId(options.requestId);
1407
+ const message = SessionInboundMessageSchema.parse({
1408
+ type: "agent.fork_context.request",
1409
+ agentId,
1410
+ requestId: resolvedRequestId,
1411
+ ...(options.boundaryMessageId ? { boundaryMessageId: options.boundaryMessageId } : {}),
1412
+ });
1413
+ const payload = await this.sendRequest({
1414
+ requestId: resolvedRequestId,
1415
+ message,
1416
+ timeout: 15000,
1417
+ options: { skipQueue: true },
1418
+ select: (msg) => {
1419
+ if (msg.type !== "agent.fork_context.response") {
1420
+ return null;
1421
+ }
1422
+ if (msg.payload.requestId !== resolvedRequestId) {
1423
+ return null;
1424
+ }
1425
+ return msg.payload;
1426
+ },
1427
+ });
1428
+ if (payload.error) {
1429
+ throw new Error(payload.error);
1430
+ }
1431
+ return payload;
1432
+ }
1403
1433
  // ============================================================================
1404
1434
  // Agent Interaction
1405
1435
  // ============================================================================
@@ -1418,7 +1448,6 @@ export class DaemonClient {
1418
1448
  const payload = await this.sendRequest({
1419
1449
  requestId,
1420
1450
  message,
1421
- timeout: 15000,
1422
1451
  options: { skipQueue: true },
1423
1452
  select: (msg) => {
1424
1453
  if (msg.type !== "send_agent_message_response") {
@@ -1449,7 +1478,6 @@ export class DaemonClient {
1449
1478
  const payload = await this.sendRequest({
1450
1479
  requestId,
1451
1480
  message,
1452
- timeout: 15000,
1453
1481
  options: { skipQueue: true },
1454
1482
  select: (msg) => {
1455
1483
  if (msg.type !== "agent.rewind.response") {
@@ -1476,7 +1504,6 @@ export class DaemonClient {
1476
1504
  await this.sendRequest({
1477
1505
  requestId,
1478
1506
  message,
1479
- timeout: 15000,
1480
1507
  options: { skipQueue: true },
1481
1508
  select: (msg) => {
1482
1509
  if (msg.type !== "cancel_agent_response") {
@@ -1500,7 +1527,6 @@ export class DaemonClient {
1500
1527
  const payload = await this.sendRequest({
1501
1528
  requestId,
1502
1529
  message,
1503
- timeout: 15000,
1504
1530
  options: { skipQueue: true },
1505
1531
  select: (msg) => {
1506
1532
  if (msg.type !== "set_agent_mode_response") {
@@ -1528,7 +1554,6 @@ export class DaemonClient {
1528
1554
  const payload = await this.sendRequest({
1529
1555
  requestId,
1530
1556
  message,
1531
- timeout: 15000,
1532
1557
  options: { skipQueue: true },
1533
1558
  select: (msg) => {
1534
1559
  if (msg.type !== "set_agent_model_response") {
@@ -1556,7 +1581,6 @@ export class DaemonClient {
1556
1581
  const payload = await this.sendRequest({
1557
1582
  requestId,
1558
1583
  message,
1559
- timeout: 15000,
1560
1584
  options: { skipQueue: true },
1561
1585
  select: (msg) => {
1562
1586
  if (msg.type !== "set_agent_feature_response") {
@@ -1583,7 +1607,6 @@ export class DaemonClient {
1583
1607
  const payload = await this.sendRequest({
1584
1608
  requestId,
1585
1609
  message,
1586
- timeout: 15000,
1587
1610
  options: { skipQueue: true },
1588
1611
  select: (msg) => {
1589
1612
  if (msg.type !== "set_agent_thinking_response") {
@@ -1610,7 +1633,6 @@ export class DaemonClient {
1610
1633
  return this.sendRequest({
1611
1634
  requestId: resolvedRequestId,
1612
1635
  message,
1613
- timeout: 10000,
1614
1636
  options: { skipQueue: true },
1615
1637
  select: (msg) => {
1616
1638
  if (msg.type !== "status") {
@@ -1627,8 +1649,8 @@ export class DaemonClient {
1627
1649
  },
1628
1650
  });
1629
1651
  }
1630
- async shutdownServer(requestId) {
1631
- const resolvedRequestId = this.createRequestId(requestId);
1652
+ async shutdownServer(options) {
1653
+ const resolvedRequestId = this.createRequestId(options?.requestId);
1632
1654
  const message = SessionInboundMessageSchema.parse({
1633
1655
  type: "shutdown_server_request",
1634
1656
  requestId: resolvedRequestId,
@@ -1636,7 +1658,7 @@ export class DaemonClient {
1636
1658
  return this.sendRequest({
1637
1659
  requestId: resolvedRequestId,
1638
1660
  message,
1639
- timeout: 10000,
1661
+ timeout: options?.timeout,
1640
1662
  options: { skipQueue: true },
1641
1663
  select: (msg) => {
1642
1664
  if (msg.type !== "status") {
@@ -1653,6 +1675,29 @@ export class DaemonClient {
1653
1675
  },
1654
1676
  });
1655
1677
  }
1678
+ async updateDaemon(requestId) {
1679
+ const resolvedRequestId = this.createRequestId(requestId);
1680
+ const message = SessionInboundMessageSchema.parse({
1681
+ type: "daemon.update.request",
1682
+ requestId: resolvedRequestId,
1683
+ });
1684
+ return this.sendRequest({
1685
+ requestId: resolvedRequestId,
1686
+ message,
1687
+ timeout: 300000, // 5 minutes — npm update can be slow on remote machines
1688
+ options: { skipQueue: true },
1689
+ select: (msg) => {
1690
+ const parsed = DaemonUpdateResponseSchema.safeParse(msg);
1691
+ if (!parsed.success) {
1692
+ return null;
1693
+ }
1694
+ if (parsed.data.payload.requestId !== resolvedRequestId) {
1695
+ return null;
1696
+ }
1697
+ return parsed.data.payload;
1698
+ },
1699
+ });
1700
+ }
1656
1701
  // ============================================================================
1657
1702
  // Audio / Voice
1658
1703
  // ============================================================================
@@ -1667,7 +1712,6 @@ export class DaemonClient {
1667
1712
  const response = await this.sendRequest({
1668
1713
  requestId,
1669
1714
  message,
1670
- timeout: 10000,
1671
1715
  select: (msg) => {
1672
1716
  if (msg.type !== "set_voice_mode_response") {
1673
1717
  return null;
@@ -1874,7 +1918,6 @@ export class DaemonClient {
1874
1918
  const responsePromise = this.sendRequest({
1875
1919
  requestId: resolvedRequestId,
1876
1920
  message,
1877
- timeout: 60000,
1878
1921
  options: { skipQueue: true },
1879
1922
  select: (msg) => {
1880
1923
  if (msg.type !== "checkout_status_response") {
@@ -1958,7 +2001,6 @@ export class DaemonClient {
1958
2001
  requestId: resolvedRequestId,
1959
2002
  message,
1960
2003
  responseType: "subscribe_checkout_diff_response",
1961
- timeout: 60000,
1962
2004
  options: { skipQueue: true },
1963
2005
  selectPayload: (payload) => {
1964
2006
  if (payload.subscriptionId !== subscriptionId) {
@@ -1995,7 +2037,6 @@ export class DaemonClient {
1995
2037
  addAll: input.addAll,
1996
2038
  },
1997
2039
  responseType: "checkout_commit_response",
1998
- timeout: 60000,
1999
2040
  });
2000
2041
  }
2001
2042
  async checkoutMerge(cwd, input, requestId) {
@@ -2009,7 +2050,6 @@ export class DaemonClient {
2009
2050
  requireCleanTarget: input.requireCleanTarget,
2010
2051
  },
2011
2052
  responseType: "checkout_merge_response",
2012
- timeout: 60000,
2013
2053
  });
2014
2054
  }
2015
2055
  async checkoutMergeFromBase(cwd, input, requestId) {
@@ -2022,7 +2062,6 @@ export class DaemonClient {
2022
2062
  requireCleanTarget: input.requireCleanTarget,
2023
2063
  },
2024
2064
  responseType: "checkout_merge_from_base_response",
2025
- timeout: 60000,
2026
2065
  });
2027
2066
  }
2028
2067
  async checkoutPull(cwd, requestId) {
@@ -2033,7 +2072,6 @@ export class DaemonClient {
2033
2072
  cwd,
2034
2073
  },
2035
2074
  responseType: "checkout_pull_response",
2036
- timeout: 60000,
2037
2075
  });
2038
2076
  }
2039
2077
  async checkoutPush(cwd, requestId) {
@@ -2044,7 +2082,6 @@ export class DaemonClient {
2044
2082
  cwd,
2045
2083
  },
2046
2084
  responseType: "checkout_push_response",
2047
- timeout: 60000,
2048
2085
  });
2049
2086
  }
2050
2087
  async checkoutRefresh(cwd, requestId) {
@@ -2055,7 +2092,6 @@ export class DaemonClient {
2055
2092
  cwd,
2056
2093
  },
2057
2094
  responseType: "checkout.refresh.response",
2058
- timeout: 60000,
2059
2095
  });
2060
2096
  }
2061
2097
  async checkoutPrCreate(cwd, input, requestId) {
@@ -2069,7 +2105,6 @@ export class DaemonClient {
2069
2105
  baseRef: input.baseRef,
2070
2106
  },
2071
2107
  responseType: "checkout_pr_create_response",
2072
- timeout: 60000,
2073
2108
  });
2074
2109
  }
2075
2110
  async checkoutPrMerge(cwd, input, requestId) {
@@ -2081,7 +2116,6 @@ export class DaemonClient {
2081
2116
  mergeMethod: input.method,
2082
2117
  },
2083
2118
  responseType: "checkout_pr_merge_response",
2084
- timeout: 60000,
2085
2119
  });
2086
2120
  }
2087
2121
  async checkoutGithubSetAutoMerge(cwd, input, requestId) {
@@ -2093,7 +2127,6 @@ export class DaemonClient {
2093
2127
  enabled: input.enabled,
2094
2128
  ...(input.enabled ? { mergeMethod: input.method } : {}),
2095
2129
  },
2096
- timeout: 60000,
2097
2130
  });
2098
2131
  }
2099
2132
  async checkoutGithubGetCheckDetails(input, requestId) {
@@ -2107,7 +2140,6 @@ export class DaemonClient {
2107
2140
  checkRunId: input.checkRunId,
2108
2141
  workflowRunId: input.workflowRunId,
2109
2142
  },
2110
- timeout: 60000,
2111
2143
  });
2112
2144
  }
2113
2145
  async checkoutPrStatus(cwd, requestId) {
@@ -2118,7 +2150,6 @@ export class DaemonClient {
2118
2150
  cwd,
2119
2151
  },
2120
2152
  responseType: "checkout_pr_status_response",
2121
- timeout: 60000,
2122
2153
  });
2123
2154
  }
2124
2155
  async pullRequestTimeline(input, requestId) {
@@ -2132,7 +2163,6 @@ export class DaemonClient {
2132
2163
  repoName: input.repoName,
2133
2164
  },
2134
2165
  responseType: "pull_request_timeline_response",
2135
- timeout: 60000,
2136
2166
  });
2137
2167
  }
2138
2168
  async checkoutSwitchBranch(cwd, branch, requestId) {
@@ -2144,7 +2174,6 @@ export class DaemonClient {
2144
2174
  branch,
2145
2175
  },
2146
2176
  responseType: "checkout_switch_branch_response",
2147
- timeout: 30000,
2148
2177
  });
2149
2178
  }
2150
2179
  async renameBranch(input) {
@@ -2156,7 +2185,6 @@ export class DaemonClient {
2156
2185
  branch: input.branch,
2157
2186
  },
2158
2187
  responseType: "checkout.rename_branch.response",
2159
- timeout: 30000,
2160
2188
  });
2161
2189
  }
2162
2190
  async stashSave(cwd, options, requestId) {
@@ -2168,7 +2196,6 @@ export class DaemonClient {
2168
2196
  branch: options?.branch,
2169
2197
  },
2170
2198
  responseType: "stash_save_response",
2171
- timeout: 30000,
2172
2199
  });
2173
2200
  }
2174
2201
  async stashPop(cwd, stashIndex, requestId) {
@@ -2180,7 +2207,6 @@ export class DaemonClient {
2180
2207
  stashIndex,
2181
2208
  },
2182
2209
  responseType: "stash_pop_response",
2183
- timeout: 30000,
2184
2210
  });
2185
2211
  }
2186
2212
  async stashList(cwd, options, requestId) {
@@ -2192,7 +2218,6 @@ export class DaemonClient {
2192
2218
  paseoOnly: options?.paseoOnly,
2193
2219
  },
2194
2220
  responseType: "stash_list_response",
2195
- timeout: 10000,
2196
2221
  });
2197
2222
  }
2198
2223
  async getPaseoWorktreeList(input, requestId) {
@@ -2204,7 +2229,6 @@ export class DaemonClient {
2204
2229
  repoRoot: input.repoRoot,
2205
2230
  },
2206
2231
  responseType: "paseo_worktree_list_response",
2207
- timeout: 60000,
2208
2232
  });
2209
2233
  }
2210
2234
  async archivePaseoWorktree(input, requestId) {
@@ -2219,7 +2243,6 @@ export class DaemonClient {
2219
2243
  ...(input.scope !== undefined ? { scope: input.scope } : {}),
2220
2244
  },
2221
2245
  responseType: "paseo_worktree_archive_response",
2222
- timeout: 60000,
2223
2246
  });
2224
2247
  }
2225
2248
  async createPaseoWorktree(input, requestId) {
@@ -2238,7 +2261,6 @@ export class DaemonClient {
2238
2261
  ...(input.githubPrNumber !== undefined ? { githubPrNumber: input.githubPrNumber } : {}),
2239
2262
  },
2240
2263
  responseType: "create_paseo_worktree_response",
2241
- timeout: 60000,
2242
2264
  });
2243
2265
  }
2244
2266
  async createWorkspace(input, requestId) {
@@ -2253,7 +2275,6 @@ export class DaemonClient {
2253
2275
  : {}),
2254
2276
  },
2255
2277
  responseType: "workspace.create.response",
2256
- timeout: 60000,
2257
2278
  });
2258
2279
  }
2259
2280
  async validateBranch(options, requestId) {
@@ -2265,7 +2286,6 @@ export class DaemonClient {
2265
2286
  branchName: options.branchName,
2266
2287
  },
2267
2288
  responseType: "validate_branch_response",
2268
- timeout: 10000,
2269
2289
  });
2270
2290
  }
2271
2291
  async getBranchSuggestions(options, requestId) {
@@ -2278,7 +2298,6 @@ export class DaemonClient {
2278
2298
  limit: options.limit,
2279
2299
  },
2280
2300
  responseType: "branch_suggestions_response",
2281
- timeout: 10000,
2282
2301
  });
2283
2302
  }
2284
2303
  async searchGitHub(options, requestId) {
@@ -2292,7 +2311,6 @@ export class DaemonClient {
2292
2311
  kinds: options.kinds,
2293
2312
  },
2294
2313
  responseType: "github_search_response",
2295
- timeout: 15000,
2296
2314
  });
2297
2315
  }
2298
2316
  async getDirectorySuggestions(options, requestId) {
@@ -2308,7 +2326,8 @@ export class DaemonClient {
2308
2326
  limit: options.limit,
2309
2327
  },
2310
2328
  responseType: "directory_suggestions_response",
2311
- timeout: 10000,
2329
+ // Home-tree scans on large home dirs can take several seconds; don't cut
2330
+ // the suggestion request off early (it would surface as an empty list).
2312
2331
  });
2313
2332
  }
2314
2333
  // ============================================================================
@@ -2325,7 +2344,6 @@ export class DaemonClient {
2325
2344
  ...(acceptBinary ? { acceptBinary: true } : {}),
2326
2345
  },
2327
2346
  responseType: "file_explorer_response",
2328
- timeout: 10000,
2329
2347
  });
2330
2348
  }
2331
2349
  async listDirectory(cwd, path, requestId) {
@@ -2379,7 +2397,6 @@ export class DaemonClient {
2379
2397
  requestId: resolvedRequestId,
2380
2398
  },
2381
2399
  responseType: "file.upload.response",
2382
- timeout: 60000,
2383
2400
  options: { skipQueue: true },
2384
2401
  });
2385
2402
  this.sendBinaryFrame(encodeFileTransferFrame({
@@ -2416,7 +2433,6 @@ export class DaemonClient {
2416
2433
  path,
2417
2434
  },
2418
2435
  responseType: "file_download_token_response",
2419
- timeout: 10000,
2420
2436
  });
2421
2437
  }
2422
2438
  async requestProjectIcon(cwd, requestId) {
@@ -2427,7 +2443,6 @@ export class DaemonClient {
2427
2443
  cwd,
2428
2444
  },
2429
2445
  responseType: "project_icon_response",
2430
- timeout: 10000,
2431
2446
  });
2432
2447
  }
2433
2448
  // ============================================================================
@@ -2476,7 +2491,6 @@ export class DaemonClient {
2476
2491
  type: "list_available_providers_request",
2477
2492
  },
2478
2493
  responseType: "list_available_providers_response",
2479
- timeout: 60000,
2480
2494
  });
2481
2495
  }
2482
2496
  async getProvidersSnapshot(options) {
@@ -2487,7 +2501,6 @@ export class DaemonClient {
2487
2501
  cwd: options?.cwd,
2488
2502
  },
2489
2503
  responseType: "get_providers_snapshot_response",
2490
- timeout: 10000,
2491
2504
  });
2492
2505
  }
2493
2506
  async getDaemonConfig(requestId) {
@@ -2497,27 +2510,26 @@ export class DaemonClient {
2497
2510
  type: "get_daemon_config_request",
2498
2511
  },
2499
2512
  responseType: "get_daemon_config_response",
2500
- timeout: 10000,
2501
2513
  });
2502
2514
  }
2503
- async getDaemonStatus(requestId) {
2515
+ async getDaemonStatus(options) {
2504
2516
  return this.sendCorrelatedSessionRequest({
2505
- requestId,
2517
+ requestId: options?.requestId,
2506
2518
  message: {
2507
2519
  type: "daemon.get_status.request",
2508
2520
  },
2509
2521
  responseType: "daemon.get_status.response",
2510
- timeout: 10000,
2522
+ timeout: options?.timeout,
2511
2523
  });
2512
2524
  }
2513
- async getDaemonPairingOffer(requestId) {
2525
+ async getDaemonPairingOffer(options) {
2514
2526
  return this.sendCorrelatedSessionRequest({
2515
- requestId,
2527
+ requestId: options?.requestId,
2516
2528
  message: {
2517
2529
  type: "daemon.get_pairing_offer.request",
2518
2530
  },
2519
2531
  responseType: "daemon.get_pairing_offer.response",
2520
- timeout: 10000,
2532
+ timeout: options?.timeout,
2521
2533
  });
2522
2534
  }
2523
2535
  async collectDiagnostics(requestId) {
@@ -2526,7 +2538,6 @@ export class DaemonClient {
2526
2538
  message: {
2527
2539
  type: "diagnostics.request",
2528
2540
  },
2529
- timeout: 30000,
2530
2541
  });
2531
2542
  }
2532
2543
  async patchDaemonConfig(config, requestId) {
@@ -2537,7 +2548,6 @@ export class DaemonClient {
2537
2548
  config,
2538
2549
  },
2539
2550
  responseType: "set_daemon_config_response",
2540
- timeout: 10000,
2541
2551
  });
2542
2552
  }
2543
2553
  async readProjectConfig(repoRoot, requestId) {
@@ -2548,7 +2558,6 @@ export class DaemonClient {
2548
2558
  repoRoot,
2549
2559
  },
2550
2560
  responseType: "read_project_config_response",
2551
- timeout: 10000,
2552
2561
  });
2553
2562
  }
2554
2563
  async writeProjectConfig(input) {
@@ -2561,7 +2570,6 @@ export class DaemonClient {
2561
2570
  expectedRevision: input.expectedRevision,
2562
2571
  },
2563
2572
  responseType: "write_project_config_response",
2564
- timeout: 10000,
2565
2573
  });
2566
2574
  }
2567
2575
  async refreshProvidersSnapshot(options) {
@@ -2593,21 +2601,18 @@ export class DaemonClient {
2593
2601
  message: {
2594
2602
  type: "provider.usage.list.request",
2595
2603
  },
2596
- timeout: 30000,
2597
2604
  });
2598
2605
  }
2599
- async listCommands(agentId, requestIdOrOptions) {
2600
- const requestId = typeof requestIdOrOptions === "string" ? requestIdOrOptions : requestIdOrOptions?.requestId;
2601
- const draftConfig = typeof requestIdOrOptions === "string" ? undefined : requestIdOrOptions?.draftConfig;
2606
+ async listCommands(input, legacyOptions) {
2607
+ const options = normalizeListCommandsOptions(input, legacyOptions);
2602
2608
  return this.sendCorrelatedSessionRequest({
2603
- requestId,
2609
+ requestId: options.requestId,
2604
2610
  message: {
2605
2611
  type: "list_commands_request",
2606
- agentId,
2607
- ...(draftConfig ? { draftConfig } : {}),
2612
+ agentId: options.agentId,
2613
+ ...(options.draftConfig ? { draftConfig: options.draftConfig } : {}),
2608
2614
  },
2609
2615
  responseType: "list_commands_response",
2610
- timeout: 30000,
2611
2616
  });
2612
2617
  }
2613
2618
  // ============================================================================
@@ -2651,11 +2656,17 @@ export class DaemonClient {
2651
2656
  // Waiting / Streaming Helpers
2652
2657
  // ============================================================================
2653
2658
  async waitForAgentUpsert(agentId, predicate, timeout = 60000) {
2654
- const initialResult = await this.fetchAgent(agentId).catch(() => null);
2659
+ const deadline = Date.now() + timeout;
2660
+ const remainingTimeoutMs = () => Math.max(1, deadline - Date.now());
2661
+ const timeoutError = () => new Error(`Timed out waiting for agent ${agentId}`);
2662
+ const fetchAgentWithinDeadline = () => this.fetchAgent({ agentId, timeout: remainingTimeoutMs() }).catch(() => null);
2663
+ const initialResult = await fetchAgentWithinDeadline();
2655
2664
  if (initialResult && predicate(initialResult.agent)) {
2656
2665
  return initialResult.agent;
2657
2666
  }
2658
- const deadline = Date.now() + timeout;
2667
+ if (Date.now() >= deadline) {
2668
+ throw timeoutError();
2669
+ }
2659
2670
  return await new Promise((resolve, reject) => {
2660
2671
  let settled = false;
2661
2672
  let pollInFlight = false;
@@ -2701,7 +2712,7 @@ export class DaemonClient {
2701
2712
  }
2702
2713
  pollInFlight = true;
2703
2714
  try {
2704
- const result = await this.fetchAgent(agentId).catch(() => null);
2715
+ const result = await fetchAgentWithinDeadline();
2705
2716
  maybeResolve(result?.agent ?? null);
2706
2717
  }
2707
2718
  finally {
@@ -2725,7 +2736,7 @@ export class DaemonClient {
2725
2736
  timeoutTimer = setTimeout(() => {
2726
2737
  finish({
2727
2738
  kind: "error",
2728
- error: new Error(`Timed out waiting for agent ${agentId}`),
2739
+ error: timeoutError(),
2729
2740
  });
2730
2741
  }, remaining);
2731
2742
  pollTimer = setInterval(() => {
@@ -2797,7 +2808,6 @@ export class DaemonClient {
2797
2808
  requestId: resolvedRequestId,
2798
2809
  message,
2799
2810
  responseType: "list_terminals_response",
2800
- timeout: 10000,
2801
2811
  options: { skipQueue: true },
2802
2812
  });
2803
2813
  }
@@ -2817,7 +2827,6 @@ export class DaemonClient {
2817
2827
  requestId: resolvedRequestId,
2818
2828
  message,
2819
2829
  responseType: "create_terminal_response",
2820
- timeout: 10000,
2821
2830
  options: { skipQueue: true },
2822
2831
  });
2823
2832
  }
@@ -2830,7 +2839,6 @@ export class DaemonClient {
2830
2839
  title: input.title,
2831
2840
  },
2832
2841
  responseType: "terminal.rename.response",
2833
- timeout: 10000,
2834
2842
  });
2835
2843
  }
2836
2844
  async subscribeTerminal(terminalId, optionsOrRequestId) {
@@ -2847,7 +2855,6 @@ export class DaemonClient {
2847
2855
  requestId: resolvedRequestId,
2848
2856
  message,
2849
2857
  responseType: "subscribe_terminal_response",
2850
- timeout: 10000,
2851
2858
  options: { skipQueue: true },
2852
2859
  });
2853
2860
  if (payload.error === null) {
@@ -2885,7 +2892,6 @@ export class DaemonClient {
2885
2892
  requestId: resolvedRequestId,
2886
2893
  message,
2887
2894
  responseType: "kill_terminal_response",
2888
- timeout: 10000,
2889
2895
  options: { skipQueue: true },
2890
2896
  });
2891
2897
  }
@@ -2901,7 +2907,6 @@ export class DaemonClient {
2901
2907
  requestId: resolvedRequestId,
2902
2908
  message,
2903
2909
  responseType: "close_items_response",
2904
- timeout: 10000,
2905
2910
  options: { skipQueue: true },
2906
2911
  });
2907
2912
  }
@@ -2919,7 +2924,6 @@ export class DaemonClient {
2919
2924
  requestId: resolvedRequestId,
2920
2925
  message,
2921
2926
  responseType: "capture_terminal_response",
2922
- timeout: 10000,
2923
2927
  options: { skipQueue: true },
2924
2928
  });
2925
2929
  }
@@ -2932,7 +2936,6 @@ export class DaemonClient {
2932
2936
  ...(options.purpose ? { purpose: options.purpose } : {}),
2933
2937
  },
2934
2938
  responseType: "chat/create/response",
2935
- timeout: 10000,
2936
2939
  });
2937
2940
  }
2938
2941
  async listChatRooms(requestId) {
@@ -2942,7 +2945,6 @@ export class DaemonClient {
2942
2945
  type: "chat/list",
2943
2946
  },
2944
2947
  responseType: "chat/list/response",
2945
- timeout: 10000,
2946
2948
  });
2947
2949
  }
2948
2950
  async inspectChatRoom(options) {
@@ -2953,7 +2955,6 @@ export class DaemonClient {
2953
2955
  room: options.room,
2954
2956
  },
2955
2957
  responseType: "chat/inspect/response",
2956
- timeout: 10000,
2957
2958
  });
2958
2959
  }
2959
2960
  async deleteChatRoom(options) {
@@ -2964,7 +2965,6 @@ export class DaemonClient {
2964
2965
  room: options.room,
2965
2966
  },
2966
2967
  responseType: "chat/delete/response",
2967
- timeout: 10000,
2968
2968
  });
2969
2969
  }
2970
2970
  async postChatMessage(options) {
@@ -2978,7 +2978,6 @@ export class DaemonClient {
2978
2978
  ...(options.replyToMessageId ? { replyToMessageId: options.replyToMessageId } : {}),
2979
2979
  },
2980
2980
  responseType: "chat/post/response",
2981
- timeout: 10000,
2982
2981
  });
2983
2982
  }
2984
2983
  async readChatMessages(options) {
@@ -2992,7 +2991,7 @@ export class DaemonClient {
2992
2991
  ...(options.authorAgentId ? { authorAgentId: options.authorAgentId } : {}),
2993
2992
  },
2994
2993
  responseType: "chat/read/response",
2995
- timeout: 10000,
2994
+ timeout: options.timeout,
2996
2995
  });
2997
2996
  }
2998
2997
  async waitForChatMessages(options) {
@@ -3022,7 +3021,6 @@ export class DaemonClient {
3022
3021
  ...(typeof options.runOnCreate === "boolean" ? { runOnCreate: options.runOnCreate } : {}),
3023
3022
  },
3024
3023
  responseType: "schedule/create/response",
3025
- timeout: 10000,
3026
3024
  });
3027
3025
  }
3028
3026
  async scheduleList(requestId) {
@@ -3032,7 +3030,6 @@ export class DaemonClient {
3032
3030
  type: "schedule/list",
3033
3031
  },
3034
3032
  responseType: "schedule/list/response",
3035
- timeout: 10000,
3036
3033
  });
3037
3034
  }
3038
3035
  async scheduleInspect(options) {
@@ -3043,7 +3040,6 @@ export class DaemonClient {
3043
3040
  scheduleId: options.id,
3044
3041
  },
3045
3042
  responseType: "schedule/inspect/response",
3046
- timeout: 10000,
3047
3043
  });
3048
3044
  }
3049
3045
  async scheduleLogs(options) {
@@ -3054,7 +3050,6 @@ export class DaemonClient {
3054
3050
  scheduleId: options.id,
3055
3051
  },
3056
3052
  responseType: "schedule/logs/response",
3057
- timeout: 10000,
3058
3053
  });
3059
3054
  }
3060
3055
  async schedulePause(options) {
@@ -3065,7 +3060,6 @@ export class DaemonClient {
3065
3060
  scheduleId: options.id,
3066
3061
  },
3067
3062
  responseType: "schedule/pause/response",
3068
- timeout: 10000,
3069
3063
  });
3070
3064
  }
3071
3065
  async scheduleResume(options) {
@@ -3076,7 +3070,6 @@ export class DaemonClient {
3076
3070
  scheduleId: options.id,
3077
3071
  },
3078
3072
  responseType: "schedule/resume/response",
3079
- timeout: 10000,
3080
3073
  });
3081
3074
  }
3082
3075
  async scheduleDelete(options) {
@@ -3087,7 +3080,6 @@ export class DaemonClient {
3087
3080
  scheduleId: options.id,
3088
3081
  },
3089
3082
  responseType: "schedule/delete/response",
3090
- timeout: 10000,
3091
3083
  });
3092
3084
  }
3093
3085
  async scheduleRunOnce(options) {
@@ -3098,7 +3090,6 @@ export class DaemonClient {
3098
3090
  scheduleId: options.id,
3099
3091
  },
3100
3092
  responseType: "schedule/run-once/response",
3101
- timeout: 10000,
3102
3093
  });
3103
3094
  }
3104
3095
  async scheduleUpdate(options) {
@@ -3115,7 +3106,6 @@ export class DaemonClient {
3115
3106
  ...(options.expiresAt !== undefined ? { expiresAt: options.expiresAt } : {}),
3116
3107
  },
3117
3108
  responseType: "schedule/update/response",
3118
- timeout: 10000,
3119
3109
  });
3120
3110
  }
3121
3111
  async loopRun(options) {
@@ -3143,7 +3133,6 @@ export class DaemonClient {
3143
3133
  ...(typeof options.maxTimeMs === "number" ? { maxTimeMs: options.maxTimeMs } : {}),
3144
3134
  },
3145
3135
  responseType: "loop/run/response",
3146
- timeout: 15000,
3147
3136
  });
3148
3137
  }
3149
3138
  async loopList(requestId) {
@@ -3153,7 +3142,6 @@ export class DaemonClient {
3153
3142
  type: "loop/list",
3154
3143
  },
3155
3144
  responseType: "loop/list/response",
3156
- timeout: 10000,
3157
3145
  });
3158
3146
  }
3159
3147
  async loopInspect(options) {
@@ -3165,7 +3153,6 @@ export class DaemonClient {
3165
3153
  id: normalized.id,
3166
3154
  },
3167
3155
  responseType: "loop/inspect/response",
3168
- timeout: 10000,
3169
3156
  });
3170
3157
  }
3171
3158
  async loopLogs(options, afterSeq) {
@@ -3178,7 +3165,6 @@ export class DaemonClient {
3178
3165
  ...(typeof normalized.afterSeq === "number" ? { afterSeq: normalized.afterSeq } : {}),
3179
3166
  },
3180
3167
  responseType: "loop/logs/response",
3181
- timeout: 10000,
3182
3168
  });
3183
3169
  }
3184
3170
  async loopStop(options) {
@@ -3190,7 +3176,6 @@ export class DaemonClient {
3190
3176
  id: normalized.id,
3191
3177
  },
3192
3178
  responseType: "loop/stop/response",
3193
- timeout: 10000,
3194
3179
  });
3195
3180
  }
3196
3181
  onTerminalStreamEvent(handler) {
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ function createAgentHandleFactory(daemonClient) {
117
117
  },
118
118
  latest: () => latest,
119
119
  refetch: async (requestId) => {
120
- const result = await daemonClient.fetchAgent(id, requestId);
120
+ const result = await daemonClient.fetchAgent({ agentId: id, requestId });
121
121
  latest = result?.agent ?? null;
122
122
  return result;
123
123
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/client",
3
- "version": "0.1.101",
3
+ "version": "0.1.102-beta.2",
4
4
  "description": "Paseo client SDK package",
5
5
  "files": [
6
6
  "dist",
@@ -35,8 +35,8 @@
35
35
  "test": "vitest run"
36
36
  },
37
37
  "dependencies": {
38
- "@getpaseo/protocol": "0.1.101",
39
- "@getpaseo/relay": "0.1.101",
38
+ "@getpaseo/protocol": "0.1.102-beta.2",
39
+ "@getpaseo/relay": "0.1.102-beta.2",
40
40
  "zod": "^4.4.3"
41
41
  },
42
42
  "devDependencies": {