@getpaseo/client 0.2.5 → 0.3.0-beta.1

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,4 +1,5 @@
1
1
  import { normalizeAgentModelDefinition } from "@getpaseo/protocol/agent-types";
2
+ import { expandProviderSnapshot } from "@getpaseo/protocol/provider-snapshot-codec";
2
3
  // COMPAT(model-normalize): daemon normalizes at source (provider-registry) — shim covers older daemons; drop when floor >= v0.1.104
3
4
  function normalizeAgentModels(models) {
4
5
  if (!models) {
@@ -30,7 +31,9 @@ export function normalizeListProviderModelsPayload(payload) {
30
31
  return models === payload.models ? payload : { ...payload, models };
31
32
  }
32
33
  export function normalizeProvidersSnapshotPayload(payload) {
33
- const entries = normalizeProviderSnapshotEntries(payload.entries);
34
+ const entries = payload.compactSnapshot
35
+ ? expandProviderSnapshot(payload.compactSnapshot)
36
+ : normalizeProviderSnapshotEntries(payload.entries);
34
37
  return entries === payload.entries ? payload : { ...payload, entries };
35
38
  }
36
39
  export function normalizeProviderSnapshotUpdateMessage(msg) {
@@ -2,7 +2,7 @@ import type { z } from "zod";
2
2
  import { type ClientCapability } from "@getpaseo/protocol/client-capabilities";
3
3
  import type { AgentAttentionNotificationPayload } from "@getpaseo/protocol/agent-attention-notification";
4
4
  import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, type ServerInfoStatusPayload } from "@getpaseo/protocol/messages";
5
- import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FileVersion, FileWriteResult, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommit, ParsedDiffFile, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutForgeSetAutoMergeResponse, CheckoutGithubSetAutoMergeResponse, CheckoutForgeGetCheckDetailsResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, ForgeSearchResponse, ForgeSearchRequest, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconResponse, ProjectAddResponse, ProjectCreateDirectoryResponse, OpenProjectResponseMessage, WorkspaceGithubSearchRepositoriesResponse, ProjectGithubCloneProtocol, ProjectGithubCloneResponse, 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, WorkspaceRecoveryState } from "@getpaseo/protocol/messages";
5
+ import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FileVersion, FileWriteResult, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommit, ParsedDiffFile, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutForgeSetAutoMergeResponse, CheckoutGithubSetAutoMergeResponse, CheckoutForgeGetCheckDetailsResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, ForgeSearchResponse, ForgeSearchRequest, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconSource, ProjectIconResponse, ProjectIconGetResponse, ProjectAddResponse, ProjectCreateDirectoryResponse, OpenProjectResponseMessage, WorkspaceGithubSearchRepositoriesResponse, ProjectGithubCloneProtocol, ProjectGithubCloneResponse, 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, WorkspaceRecoveryState } from "@getpaseo/protocol/messages";
6
6
  import type { AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, AgentProviderNotice, AgentProvider, AgentSessionConfig } from "@getpaseo/protocol/agent-types";
7
7
  import type { MutableDaemonConfig, MutableDaemonConfigPatch } from "@getpaseo/protocol/messages";
8
8
  import { type DaemonTransportFactory, type WebSocketFactory } from "./daemon-client-transport.js";
@@ -124,8 +124,14 @@ export interface DaemonClientConfig {
124
124
  };
125
125
  runtimeMetricsIntervalMs?: number;
126
126
  runtimeMetricsWindowMs?: number;
127
+ trace?: DaemonClientTrace;
127
128
  capabilities?: Partial<Record<ClientCapability, unknown>>;
128
129
  }
130
+ export interface DaemonClientTrace {
131
+ isEnabled(): boolean;
132
+ beginSection(name: string, args?: Record<string, string>): void;
133
+ endSection(): void;
134
+ }
129
135
  export interface SendMessageOptions {
130
136
  messageId?: string;
131
137
  images?: Array<{
@@ -343,9 +349,13 @@ export interface FetchAgentTimelineOptions {
343
349
  cursor?: FetchAgentTimelineCursor;
344
350
  limit?: number;
345
351
  projection?: FetchAgentTimelineProjection;
352
+ mergeWindow?: boolean;
346
353
  requestId?: string;
347
354
  timeout?: number;
348
355
  }
356
+ export type AgentTimelinePromptIndexPayload = Extract<SessionOutboundMessage, {
357
+ type: "agent.timeline.list_prompts.response";
358
+ }>["payload"];
349
359
  export type ProviderSubagentListPayload = Extract<SessionOutboundMessage, {
350
360
  type: "agent.provider_subagents.list.response";
351
361
  }>["payload"];
@@ -644,6 +654,11 @@ export declare class DaemonClient {
644
654
  }>) => void): () => void;
645
655
  on(handler: DaemonEventHandler): () => void;
646
656
  onAgentAttentionRequired(handler: (notification: AgentAttentionRequiredNotification) => void): () => void;
657
+ private beginTraceSection;
658
+ private endTraceSection;
659
+ private traceInstant;
660
+ private sendJsonMessage;
661
+ private sendTransportFrame;
647
662
  /**
648
663
  * Send a session message. For fire-and-forget messages (heartbeats, etc.),
649
664
  * failures are suppressed if `suppressSendErrors` is configured.
@@ -753,6 +768,7 @@ export declare class DaemonClient {
753
768
  renameProject(projectId: string, customName: string | null, requestId?: string): Promise<{
754
769
  customName: string | null;
755
770
  }>;
771
+ setProjectIcon(projectId: string, source: ProjectIconSource, requestId?: string): Promise<void>;
756
772
  removeProject(projectId: string, requestId?: string): Promise<{
757
773
  removedWorkspaceIds: string[];
758
774
  }>;
@@ -768,6 +784,10 @@ export declare class DaemonClient {
768
784
  importAgent(input: ImportAgentInput): Promise<AgentSnapshotPayload>;
769
785
  refreshAgent(agentId: string, requestId?: string): Promise<AgentRefreshedStatusPayload>;
770
786
  fetchAgentTimeline(agentId: string, options?: FetchAgentTimelineOptions): Promise<FetchAgentTimelinePayload>;
787
+ listAgentTimelinePrompts(agentId: string, options?: {
788
+ requestId?: string;
789
+ timeout?: number;
790
+ }): Promise<AgentTimelinePromptIndexPayload>;
771
791
  listProviderSubagents(parentAgentId: string, options?: {
772
792
  requestId?: string;
773
793
  timeout?: number;
@@ -955,6 +975,7 @@ export declare class DaemonClient {
955
975
  uploadFile(input: FileUploadInput): Promise<FileUploadResult>;
956
976
  requestDownloadToken(cwd: string, path: string, requestId?: string): Promise<FileDownloadTokenPayload>;
957
977
  requestProjectIcon(cwd: string, requestId?: string): Promise<ProjectIconResponse["payload"]>;
978
+ getProjectIcon(projectId: string, requestId?: string): Promise<ProjectIconGetResponse["payload"]>;
958
979
  listProviderModels(provider: AgentProvider, options?: {
959
980
  cwd?: string;
960
981
  requestId?: string;
@@ -971,6 +992,7 @@ export declare class DaemonClient {
971
992
  }): Promise<ListAvailableProvidersPayload>;
972
993
  getProvidersSnapshot(options?: {
973
994
  cwd?: string;
995
+ ifNoneMatch?: string;
974
996
  requestId?: string;
975
997
  }): Promise<GetProvidersSnapshotPayload>;
976
998
  getDaemonConfig(requestId?: string): Promise<{
@@ -179,6 +179,21 @@ function concatByteChunks(chunks, size) {
179
179
  }
180
180
  return bytes;
181
181
  }
182
+ function getTransportFrameSize(frame) {
183
+ if (typeof frame === "string") {
184
+ return frame.length;
185
+ }
186
+ return frame.byteLength;
187
+ }
188
+ function describeInboundTransportFrame(frame, rawBytes) {
189
+ if (typeof frame === "string") {
190
+ return { kind: "text", size: String(frame.length) };
191
+ }
192
+ if (rawBytes) {
193
+ return { kind: "binary", size: String(rawBytes.byteLength) };
194
+ }
195
+ return { kind: "unknown", size: "0" };
196
+ }
182
197
  function hashForLog(value) {
183
198
  let hash = 0;
184
199
  for (let index = 0; index < value.length; index += 1) {
@@ -584,6 +599,45 @@ export class DaemonClient {
584
599
  // ============================================================================
585
600
  // Core Send Helpers
586
601
  // ============================================================================
602
+ beginTraceSection(name, args) {
603
+ const trace = this.config.trace;
604
+ if (!trace?.isEnabled()) {
605
+ return false;
606
+ }
607
+ trace.beginSection(name, args);
608
+ return true;
609
+ }
610
+ endTraceSection(isOpen) {
611
+ if (isOpen) {
612
+ this.config.trace?.endSection();
613
+ }
614
+ }
615
+ traceInstant(name, args) {
616
+ const isOpen = this.beginTraceSection(name, args);
617
+ this.endTraceSection(isOpen);
618
+ }
619
+ sendJsonMessage(envelopeType, messageType, message) {
620
+ this.traceInstant("paseo.ws.message.outbound", {
621
+ envelopeType,
622
+ messageType,
623
+ });
624
+ this.sendTransportFrame(JSON.stringify(message));
625
+ }
626
+ sendTransportFrame(frame) {
627
+ if (!this.transport) {
628
+ throw new Error("Transport not connected");
629
+ }
630
+ const isOpen = this.beginTraceSection("paseo.ws.frame.outbound", {
631
+ kind: typeof frame === "string" ? "text" : "binary",
632
+ size: String(getTransportFrameSize(frame)),
633
+ });
634
+ try {
635
+ this.transport.send(frame);
636
+ }
637
+ finally {
638
+ this.endTraceSection(isOpen);
639
+ }
640
+ }
587
641
  /**
588
642
  * Send a session message. For fire-and-forget messages (heartbeats, etc.),
589
643
  * failures are suppressed if `suppressSendErrors` is configured.
@@ -598,7 +652,7 @@ export class DaemonClient {
598
652
  }
599
653
  const payload = SessionInboundMessageSchema.parse(message);
600
654
  try {
601
- this.transport.send(JSON.stringify({ type: "session", message: payload }));
655
+ this.sendJsonMessage("session", payload.type, { type: "session", message: payload });
602
656
  }
603
657
  catch (error) {
604
658
  if (this.config.suppressSendErrors) {
@@ -615,7 +669,11 @@ export class DaemonClient {
615
669
  throw new Error(`Transport not connected (status: ${this.connectionState.status})`);
616
670
  }
617
671
  try {
618
- this.transport.send(frame);
672
+ this.traceInstant("paseo.ws.message.outbound", {
673
+ envelopeType: "binary",
674
+ messageType: "binary",
675
+ });
676
+ this.sendTransportFrame(frame);
619
677
  }
620
678
  catch (error) {
621
679
  if (this.config.suppressSendErrors) {
@@ -635,7 +693,7 @@ export class DaemonClient {
635
693
  // If connected, send immediately
636
694
  if (this.transport && status === "connected") {
637
695
  const payload = SessionInboundMessageSchema.parse(message);
638
- this.transport.send(JSON.stringify({ type: "session", message: payload }));
696
+ this.sendJsonMessage("session", payload.type, { type: "session", message: payload });
639
697
  return Promise.resolve();
640
698
  }
641
699
  // If connecting, queue the message to be sent once connected
@@ -666,7 +724,7 @@ export class DaemonClient {
666
724
  try {
667
725
  if (this.transport && this.connectionState.status === "connected") {
668
726
  const payload = SessionInboundMessageSchema.parse(pending.message);
669
- this.transport.send(JSON.stringify({ type: "session", message: payload }));
727
+ this.sendJsonMessage("session", payload.type, { type: "session", message: payload });
670
728
  pending.resolve();
671
729
  }
672
730
  else {
@@ -774,7 +832,7 @@ export class DaemonClient {
774
832
  }
775
833
  const payload = SessionInboundMessageSchema.parse(message);
776
834
  try {
777
- this.transport.send(JSON.stringify({ type: "session", message: payload }));
835
+ this.sendJsonMessage("session", payload.type, { type: "session", message: payload });
778
836
  }
779
837
  catch (error) {
780
838
  throw error instanceof Error ? error : new Error(String(error));
@@ -923,7 +981,7 @@ export class DaemonClient {
923
981
  };
924
982
  this.pingProbe = probe;
925
983
  try {
926
- this.transport.send(JSON.stringify({ type: "ping" }));
984
+ this.sendJsonMessage("ping", "ping", { type: "ping" });
927
985
  }
928
986
  catch (error) {
929
987
  this.clearPingProbe();
@@ -1415,6 +1473,14 @@ export class DaemonClient {
1415
1473
  }
1416
1474
  return { customName: payload.customName };
1417
1475
  }
1476
+ async setProjectIcon(projectId, source, requestId) {
1477
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1478
+ requestId,
1479
+ message: { type: "project.icon.set.request", projectId, source },
1480
+ });
1481
+ if (!payload.accepted)
1482
+ throw new Error(payload.error ?? "setProjectIcon rejected");
1483
+ }
1418
1484
  async removeProject(projectId, requestId) {
1419
1485
  const payload = await this.sendNamespacedCorrelatedSessionRequest({
1420
1486
  requestId,
@@ -1575,6 +1641,7 @@ export class DaemonClient {
1575
1641
  ...(options.cursor ? { cursor: options.cursor } : {}),
1576
1642
  ...(typeof options.limit === "number" ? { limit: options.limit } : {}),
1577
1643
  ...(options.projection ? { projection: options.projection } : {}),
1644
+ ...(options.mergeWindow === true ? { mergeWindow: true } : {}),
1578
1645
  });
1579
1646
  const payload = await this.sendRequest({
1580
1647
  requestId: resolvedRequestId,
@@ -1596,6 +1663,28 @@ export class DaemonClient {
1596
1663
  }
1597
1664
  return payload;
1598
1665
  }
1666
+ async listAgentTimelinePrompts(agentId, options = {}) {
1667
+ const requestId = this.createRequestId(options.requestId);
1668
+ const message = SessionInboundMessageSchema.parse({
1669
+ type: "agent.timeline.list_prompts.request",
1670
+ agentId,
1671
+ requestId,
1672
+ });
1673
+ const payload = await this.sendRequest({
1674
+ requestId,
1675
+ message,
1676
+ timeout: options.timeout,
1677
+ options: { skipQueue: true },
1678
+ select: (response) => response.type === "agent.timeline.list_prompts.response" &&
1679
+ response.payload.requestId === requestId
1680
+ ? response.payload
1681
+ : null,
1682
+ });
1683
+ if (payload.error) {
1684
+ throw new Error(payload.error);
1685
+ }
1686
+ return payload;
1687
+ }
1599
1688
  async listProviderSubagents(parentAgentId, options = {}) {
1600
1689
  const requestId = this.createRequestId(options.requestId);
1601
1690
  const message = SessionInboundMessageSchema.parse({
@@ -2827,6 +2916,12 @@ export class DaemonClient {
2827
2916
  responseType: "project_icon_response",
2828
2917
  });
2829
2918
  }
2919
+ async getProjectIcon(projectId, requestId) {
2920
+ return this.sendNamespacedCorrelatedSessionRequest({
2921
+ requestId,
2922
+ message: { type: "project.icon.get.request", projectId },
2923
+ });
2924
+ }
2830
2925
  // ============================================================================
2831
2926
  // Provider Models / Commands
2832
2927
  // ============================================================================
@@ -2882,6 +2977,7 @@ export class DaemonClient {
2882
2977
  message: {
2883
2978
  type: "get_providers_snapshot_request",
2884
2979
  cwd: options?.cwd,
2980
+ ifNoneMatch: options?.ifNoneMatch,
2885
2981
  },
2886
2982
  responseType: "get_providers_snapshot_response",
2887
2983
  });
@@ -3637,7 +3733,7 @@ export class DaemonClient {
3637
3733
  return;
3638
3734
  }
3639
3735
  try {
3640
- this.transport.send(JSON.stringify({
3736
+ this.sendJsonMessage("hello", "hello", {
3641
3737
  type: "hello",
3642
3738
  clientId: this.config.clientId,
3643
3739
  clientType: this.config.clientType ?? "cli",
@@ -3648,10 +3744,11 @@ export class DaemonClient {
3648
3744
  [CLIENT_CAPS.terminalReflowableSnapshot]: true,
3649
3745
  [CLIENT_CAPS.providerSubagents]: true,
3650
3746
  [CLIENT_CAPS.projectUpdates]: true,
3747
+ [CLIENT_CAPS.compactProviderSnapshots]: true,
3651
3748
  ...this.config.capabilities,
3652
3749
  },
3653
3750
  ...(this.config.appVersion ? { appVersion: this.config.appVersion } : {}),
3654
- }));
3751
+ });
3655
3752
  }
3656
3753
  catch (error) {
3657
3754
  const message = error instanceof Error ? error.message : "Failed to send hello message";
@@ -3716,25 +3813,37 @@ export class DaemonClient {
3716
3813
  return;
3717
3814
  }
3718
3815
  const rawBytes = asUint8Array(rawData);
3719
- if (rawBytes && this.tryHandleBinaryFrame(rawBytes)) {
3720
- return;
3816
+ const isOpen = this.beginTraceSection("paseo.ws.frame.inbound", describeInboundTransportFrame(rawData, rawBytes));
3817
+ try {
3818
+ if (rawBytes && this.tryHandleBinaryFrame(rawBytes)) {
3819
+ return;
3820
+ }
3821
+ const payload = decodeMessageData(rawData);
3822
+ if (!payload) {
3823
+ return;
3824
+ }
3825
+ this.handleJsonPayload(payload, rawBytes?.byteLength);
3721
3826
  }
3722
- const payload = decodeMessageData(rawData);
3723
- if (!payload) {
3724
- return;
3827
+ finally {
3828
+ this.endTraceSection(isOpen);
3725
3829
  }
3726
- this.handleJsonPayload(payload, rawBytes?.byteLength);
3727
3830
  }
3728
3831
  handleJsonPayload(payload, rawBytesLength) {
3729
3832
  const bytes = rawBytesLength ?? payload.length;
3730
3833
  const startMs = perfNow();
3731
3834
  let parsedJson;
3835
+ const parseTraceOpen = this.beginTraceSection("paseo.ws.json.parse", {
3836
+ size: String(bytes),
3837
+ });
3732
3838
  try {
3733
3839
  parsedJson = JSON.parse(payload);
3734
3840
  }
3735
3841
  catch {
3736
3842
  return;
3737
3843
  }
3844
+ finally {
3845
+ this.endTraceSection(parseTraceOpen);
3846
+ }
3738
3847
  const parsed = validateWSOutboundMessage(parsedJson);
3739
3848
  if (!parsed.success) {
3740
3849
  const responseIdentity = extractCorrelatedResponseIdentity(parsedJson);
@@ -3753,10 +3862,18 @@ export class DaemonClient {
3753
3862
  }
3754
3863
  this.consecutiveLivenessFailures = 0;
3755
3864
  if (parsed.data.type === "pong") {
3865
+ this.traceInstant("paseo.ws.message.inbound", {
3866
+ envelopeType: "pong",
3867
+ messageType: "pong",
3868
+ });
3756
3869
  this.resolvePingProbe();
3757
3870
  this.runtimeMetrics?.recordMessage("pong", bytes, perfNow() - startMs);
3758
3871
  return;
3759
3872
  }
3873
+ this.traceInstant("paseo.ws.message.inbound", {
3874
+ envelopeType: "session",
3875
+ messageType: parsed.data.message.type,
3876
+ });
3760
3877
  this.handleSessionMessage(parsed.data.message);
3761
3878
  const msgType = parsed.data.message.type;
3762
3879
  this.runtimeMetrics?.recordMessage(msgType, bytes, perfNow() - startMs);
@@ -3767,6 +3884,11 @@ export class DaemonClient {
3767
3884
  tryHandleBinaryFrame(rawBytes) {
3768
3885
  const fileFrame = decodeFileTransferFrame(rawBytes);
3769
3886
  if (fileFrame) {
3887
+ this.traceInstant("paseo.ws.message.inbound", {
3888
+ envelopeType: "binary",
3889
+ messageType: "file",
3890
+ opcode: String(fileFrame.opcode),
3891
+ });
3770
3892
  this.consecutiveLivenessFailures = 0;
3771
3893
  this.handleFileTransferFrame(fileFrame);
3772
3894
  this.runtimeMetrics?.recordBinaryFrame("other", rawBytes.byteLength, 0);
@@ -3776,6 +3898,11 @@ export class DaemonClient {
3776
3898
  if (!frame) {
3777
3899
  return false;
3778
3900
  }
3901
+ this.traceInstant("paseo.ws.message.inbound", {
3902
+ envelopeType: "binary",
3903
+ messageType: "terminal",
3904
+ opcode: String(frame.opcode),
3905
+ });
3779
3906
  this.consecutiveLivenessFailures = 0;
3780
3907
  const binaryStartMs = perfNow();
3781
3908
  this.terminalStreams.handleFrame(frame);
package/dist/index.js CHANGED
@@ -121,7 +121,9 @@ function createAgentHandleFactory(daemonClient) {
121
121
  latest = result?.agent ?? null;
122
122
  return result;
123
123
  },
124
- send: (text, options) => daemonClient.sendAgentMessage(id, text, options),
124
+ send: async (text, options) => {
125
+ await daemonClient.sendAgentMessage(id, text, options);
126
+ },
125
127
  archive: async () => {
126
128
  const result = await daemonClient.archiveAgent(id);
127
129
  if (latest) {
@@ -56,6 +56,7 @@ export class TerminalStreamRouter {
56
56
  payload: encodeTerminalResizePayload({
57
57
  rows: message.rows,
58
58
  cols: message.cols,
59
+ ...(message.intent ? { intent: message.intent } : {}),
59
60
  }),
60
61
  });
61
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/client",
3
- "version": "0.2.5",
3
+ "version": "0.3.0-beta.1",
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.2.5",
39
- "@getpaseo/relay": "0.2.5",
38
+ "@getpaseo/protocol": "0.3.0-beta.1",
39
+ "@getpaseo/relay": "0.3.0-beta.1",
40
40
  "zod": "^4.4.3"
41
41
  },
42
42
  "devDependencies": {