@getpaseo/client 0.1.96 → 0.1.97-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,6 +1,6 @@
1
1
  import type { z } from "zod";
2
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, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, PaseoConfigRaw, PaseoConfigRevision } 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, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, 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, 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";
@@ -174,6 +174,9 @@ type PaseoWorktreeArchivePayload = PaseoWorktreeArchiveResponse["payload"];
174
174
  type CreatePaseoWorktreePayload = Extract<SessionOutboundMessage, {
175
175
  type: "create_paseo_worktree_response";
176
176
  }>["payload"];
177
+ type WorkspaceCreatePayload = Extract<SessionOutboundMessage, {
178
+ type: "workspace.create.response";
179
+ }>["payload"];
177
180
  type FileExplorerPayload = FileExplorerResponse["payload"];
178
181
  export type FileExplorerDirectoryPayload = NonNullable<FileExplorerPayload["directory"]>;
179
182
  type LegacyFileExplorerFilePayload = NonNullable<FileExplorerPayload["file"]>;
@@ -593,6 +596,7 @@ export declare class DaemonClient {
593
596
  sendHeartbeat(params: {
594
597
  deviceType: "web" | "mobile";
595
598
  focusedAgentId: string | null;
599
+ focusedTerminalId?: string | null;
596
600
  lastActivityAt: string;
597
601
  appVisible: boolean;
598
602
  appVisibilityChangedAt?: string;
@@ -638,6 +642,9 @@ export declare class DaemonClient {
638
642
  renameProject(projectId: string, customName: string | null, requestId?: string): Promise<{
639
643
  customName: string | null;
640
644
  }>;
645
+ setWorkspaceTitle(workspaceId: string, title: string | null, requestId?: string): Promise<{
646
+ title: string | null;
647
+ }>;
641
648
  resumeAgent(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>): Promise<AgentSnapshotPayload>;
642
649
  importAgent(input: ImportAgentInput): Promise<AgentSnapshotPayload>;
643
650
  refreshAgent(agentId: string, requestId?: string): Promise<AgentRefreshedStatusPayload>;
@@ -742,8 +749,15 @@ export declare class DaemonClient {
742
749
  worktreePath?: string;
743
750
  repoRoot?: string;
744
751
  branchName?: string;
752
+ workspaceId?: string;
753
+ scope?: "workspace" | "worktree";
745
754
  }, requestId?: string): Promise<PaseoWorktreeArchivePayload>;
746
755
  createPaseoWorktree(input: CreatePaseoWorktreeInput, requestId?: string): Promise<CreatePaseoWorktreePayload>;
756
+ createWorkspace(input: {
757
+ source: WorkspaceCreateRequest["source"];
758
+ title?: string;
759
+ firstAgentContext?: WorkspaceCreateRequest["firstAgentContext"];
760
+ }, requestId?: string): Promise<WorkspaceCreatePayload>;
747
761
  validateBranch(options: {
748
762
  cwd: string;
749
763
  branchName: string;
@@ -819,15 +833,20 @@ export declare class DaemonClient {
819
833
  waitForFinish(agentId: string, timeout?: number): Promise<WaitForFinishResult>;
820
834
  subscribeTerminals(input: {
821
835
  cwd: string;
836
+ workspaceId?: string;
822
837
  }): void;
823
838
  unsubscribeTerminals(input: {
824
839
  cwd: string;
840
+ workspaceId?: string;
825
841
  }): void;
826
- listTerminals(cwd?: string, requestId?: string): Promise<ListTerminalsPayload>;
842
+ listTerminals(cwd?: string, requestId?: string, options?: {
843
+ workspaceId?: string;
844
+ }): Promise<ListTerminalsPayload>;
827
845
  createTerminal(cwd: string, name?: string, requestId?: string, options?: {
828
846
  agentId?: string;
829
847
  command?: string;
830
848
  args?: string[];
849
+ workspaceId?: string;
831
850
  }): Promise<CreateTerminalPayload>;
832
851
  renameTerminal(input: RenameTerminalInput): Promise<RenameTerminalResult>;
833
852
  subscribeTerminal(terminalId: string, optionsOrRequestId?: {
@@ -1,6 +1,7 @@
1
1
  import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
2
2
  import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from "@getpaseo/protocol/messages";
3
3
  import { isRelayClientWebSocketUrl } from "@getpaseo/protocol/daemon-endpoints";
4
+ import { terminalSubscriptionKey } from "@getpaseo/protocol/terminal-subscription-key";
4
5
  import { asUint8Array, decodeFileTransferFrame, encodeFileTransferFrame, decodeTerminalStreamFrame, FileTransferOpcode, TerminalStreamOpcode, } from "@getpaseo/protocol/binary-frames/index";
5
6
  import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, } from "./daemon-client-transport.js";
6
7
  import { DaemonClientRuntimeMetrics } from "./daemon-client-runtime-metrics.js";
@@ -151,7 +152,7 @@ export class DaemonClient {
151
152
  this.lastErrorValue = null;
152
153
  this.connectionState = { status: "idle" };
153
154
  this.checkoutDiffSubscriptions = new Map();
154
- this.terminalDirectorySubscriptions = new Set();
155
+ this.terminalDirectorySubscriptions = new Map();
155
156
  this.terminalStreams = new TerminalStreamRouter();
156
157
  this.pendingBinaryFileReads = new Map();
157
158
  this.activeBinaryFileTransfers = new Map();
@@ -725,6 +726,7 @@ export class DaemonClient {
725
726
  type: "client_heartbeat",
726
727
  deviceType: params.deviceType,
727
728
  focusedAgentId: params.focusedAgentId,
729
+ focusedTerminalId: params.focusedTerminalId ?? null,
728
730
  lastActivityAt: params.lastActivityAt,
729
731
  appVisible: params.appVisible,
730
732
  appVisibilityChangedAt: params.appVisibilityChangedAt,
@@ -1006,10 +1008,13 @@ export class DaemonClient {
1006
1008
  if (this.terminalDirectorySubscriptions.size === 0) {
1007
1009
  return;
1008
1010
  }
1009
- for (const cwd of this.terminalDirectorySubscriptions) {
1011
+ for (const subscription of this.terminalDirectorySubscriptions.values()) {
1010
1012
  this.sendSessionMessage({
1011
1013
  type: "subscribe_terminals_request",
1012
- cwd,
1014
+ cwd: subscription.cwd,
1015
+ ...(subscription.workspaceId !== undefined
1016
+ ? { workspaceId: subscription.workspaceId }
1017
+ : {}),
1013
1018
  });
1014
1019
  }
1015
1020
  }
@@ -1158,6 +1163,22 @@ export class DaemonClient {
1158
1163
  }
1159
1164
  return { customName: payload.customName };
1160
1165
  }
1166
+ async setWorkspaceTitle(workspaceId, title, requestId) {
1167
+ const payload = await this.sendCorrelatedSessionRequest({
1168
+ requestId,
1169
+ message: {
1170
+ type: "workspace.title.set.request",
1171
+ workspaceId,
1172
+ title,
1173
+ },
1174
+ responseType: "workspace.title.set.response",
1175
+ timeout: 10000,
1176
+ });
1177
+ if (!payload.accepted) {
1178
+ throw new Error(payload.error ?? "setWorkspaceTitle rejected");
1179
+ }
1180
+ return { title: payload.title };
1181
+ }
1161
1182
  async resumeAgent(handle, overrides) {
1162
1183
  const requestId = this.createRequestId();
1163
1184
  const message = SessionInboundMessageSchema.parse({
@@ -2088,6 +2109,8 @@ export class DaemonClient {
2088
2109
  worktreePath: input.worktreePath,
2089
2110
  repoRoot: input.repoRoot,
2090
2111
  branchName: input.branchName,
2112
+ ...(input.workspaceId !== undefined ? { workspaceId: input.workspaceId } : {}),
2113
+ ...(input.scope !== undefined ? { scope: input.scope } : {}),
2091
2114
  },
2092
2115
  responseType: "paseo_worktree_archive_response",
2093
2116
  timeout: 60000,
@@ -2112,6 +2135,21 @@ export class DaemonClient {
2112
2135
  timeout: 60000,
2113
2136
  });
2114
2137
  }
2138
+ async createWorkspace(input, requestId) {
2139
+ return this.sendCorrelatedSessionRequest({
2140
+ requestId,
2141
+ message: {
2142
+ type: "workspace.create.request",
2143
+ source: input.source,
2144
+ ...(input.title !== undefined ? { title: input.title } : {}),
2145
+ ...(input.firstAgentContext !== undefined
2146
+ ? { firstAgentContext: input.firstAgentContext }
2147
+ : {}),
2148
+ },
2149
+ responseType: "workspace.create.response",
2150
+ timeout: 60000,
2151
+ });
2152
+ }
2115
2153
  async validateBranch(options, requestId) {
2116
2154
  return this.sendCorrelatedSessionRequest({
2117
2155
  requestId,
@@ -2599,30 +2637,36 @@ export class DaemonClient {
2599
2637
  // Terminals
2600
2638
  // ============================================================================
2601
2639
  subscribeTerminals(input) {
2602
- this.terminalDirectorySubscriptions.add(input.cwd);
2640
+ this.terminalDirectorySubscriptions.set(terminalSubscriptionKey(input.cwd, input.workspaceId), {
2641
+ cwd: input.cwd,
2642
+ workspaceId: input.workspaceId,
2643
+ });
2603
2644
  if (!this.transport || this.connectionState.status !== "connected") {
2604
2645
  return;
2605
2646
  }
2606
2647
  this.sendSessionMessage({
2607
2648
  type: "subscribe_terminals_request",
2608
2649
  cwd: input.cwd,
2650
+ ...(input.workspaceId !== undefined ? { workspaceId: input.workspaceId } : {}),
2609
2651
  });
2610
2652
  }
2611
2653
  unsubscribeTerminals(input) {
2612
- this.terminalDirectorySubscriptions.delete(input.cwd);
2654
+ this.terminalDirectorySubscriptions.delete(terminalSubscriptionKey(input.cwd, input.workspaceId));
2613
2655
  if (!this.transport || this.connectionState.status !== "connected") {
2614
2656
  return;
2615
2657
  }
2616
2658
  this.sendSessionMessage({
2617
2659
  type: "unsubscribe_terminals_request",
2618
2660
  cwd: input.cwd,
2661
+ ...(input.workspaceId !== undefined ? { workspaceId: input.workspaceId } : {}),
2619
2662
  });
2620
2663
  }
2621
- async listTerminals(cwd, requestId) {
2664
+ async listTerminals(cwd, requestId, options) {
2622
2665
  const resolvedRequestId = this.createRequestId(requestId);
2623
2666
  const message = SessionInboundMessageSchema.parse({
2624
2667
  type: "list_terminals_request",
2625
2668
  ...(cwd === undefined ? {} : { cwd }),
2669
+ ...(options?.workspaceId !== undefined ? { workspaceId: options.workspaceId } : {}),
2626
2670
  requestId: resolvedRequestId,
2627
2671
  });
2628
2672
  return this.sendCorrelatedRequest({
@@ -2642,6 +2686,7 @@ export class DaemonClient {
2642
2686
  agentId: options?.agentId,
2643
2687
  command: options?.command,
2644
2688
  args: options?.args,
2689
+ ...(options?.workspaceId !== undefined ? { workspaceId: options.workspaceId } : {}),
2645
2690
  requestId: resolvedRequestId,
2646
2691
  });
2647
2692
  return this.sendCorrelatedRequest({
package/dist/index.js CHANGED
@@ -64,9 +64,11 @@ function createWorkspaceHandleFactory(daemonClient) {
64
64
  id,
65
65
  latest: () => latest,
66
66
  refetch: async (options) => {
67
+ // Best-effort: fetches one page and matches by id client-side, so a workspace beyond
68
+ // the first page won't be found. TODO: add a "get workspace by id" lookup and resolve
69
+ // by exact id instead of paging.
67
70
  const result = await daemonClient.fetchWorkspaces({
68
71
  requestId: options?.requestId,
69
- filter: { idPrefix: id },
70
72
  page: { limit: 25 },
71
73
  });
72
74
  latest = result.entries.find((entry) => entry.id === id) ?? null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/client",
3
- "version": "0.1.96",
3
+ "version": "0.1.97-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.1.96",
39
- "@getpaseo/relay": "0.1.96",
38
+ "@getpaseo/protocol": "0.1.97-beta.1",
39
+ "@getpaseo/relay": "0.1.97-beta.1",
40
40
  "zod": "^3.23.8"
41
41
  },
42
42
  "devDependencies": {