import { type GitRunStackedActionResult, type GitStatusResult, type GitStatusStreamEvent, ORCHESTRATION_WS_METHODS, WS_METHODS,} from "@t3tools/contracts";import type { WsRpcClient } from "@t3tools/client-runtime";import { applyGitStatusStreamEvent } from "@t3tools/shared/git"; import { resetWsReconnectBackoff } from "./wsConnectionState";import { WsTransport } from "./wsTransport"; export type { WsRpcClient }; export function createWsRpcClient(transport: WsTransport): WsRpcClient { return { dispose: () => transport.dispose(), reconnect: async () => { resetWsReconnectBackoff(); await transport.reconnect(); }, terminal: { open: (input) => transport.request((client) => client[WS_METHODS.terminalOpen](input)), write: (input) => transport.request((client) => client[WS_METHODS.terminalWrite](input)), resize: (input) => transport.request((client) => client[WS_METHODS.terminalResize](input)), clear: (input) => transport.request((client) => client[WS_METHODS.terminalClear](input)), restart: (input) => transport.request((client) => client[WS_METHODS.terminalRestart](input)), close: (input) => transport.request((client) => client[WS_METHODS.terminalClose](input)), onEvent: (listener, options) => transport.subscribe( (client) => client[WS_METHODS.subscribeTerminalEvents]({}), listener, options, ), }, projects: { searchEntries: (input) => transport.request((client) => client[WS_METHODS.projectsSearchEntries](input)), writeFile: (input) => transport.request((client) => client[WS_METHODS.projectsWriteFile](input)), }, shell: { openInEditor: (input) => transport.request((client) => client[WS_METHODS.shellOpenInEditor](input)), }, git: { pull: (input) => transport.request((client) => client[WS_METHODS.gitPull](input)), refreshStatus: (input) => transport.request((client) => client[WS_METHODS.gitRefreshStatus](input)), onStatus: (input, listener, options) => { let current: GitStatusResult | null = null; return transport.subscribe( (client) => client[WS_METHODS.subscribeGitStatus](input), (event: GitStatusStreamEvent) => { current = applyGitStatusStreamEvent(current, event); listener(current); }, options, ); }, runStackedAction: async (input, options) => { let result: GitRunStackedActionResult | null = null; await transport.requestStream( (client) => client[WS_METHODS.gitRunStackedAction](input), (event) => { options?.onProgress?.(event); if (event.kind === "action_finished") { result = event.result; } }, ); if (result) { return result; } throw new Error("Git action stream completed without a final result."); }, listBranches: (input) => transport.request((client) => client[WS_METHODS.gitListBranches](input)), createWorktree: (input) => transport.request((client) => client[WS_METHODS.gitCreateWorktree](input)), removeWorktree: (input) => transport.request((client) => client[WS_METHODS.gitRemoveWorktree](input)), createBranch: (input) => transport.request((client) => client[WS_METHODS.gitCreateBranch](input)), checkout: (input) => transport.request((client) => client[WS_METHODS.gitCheckout](input)), init: (input) => transport.request((client) => client[WS_METHODS.gitInit](input)), resolvePullRequest: (input) => transport.request((client) => client[WS_METHODS.gitResolvePullRequest](input)), preparePullRequestThread: (input) => transport.request((client) => client[WS_METHODS.gitPreparePullRequestThread](input)), }, server: { getConfig: () => transport.request((client) => client[WS_METHODS.serverGetConfig]({})), refreshProviders: () => transport.request((client) => client[WS_METHODS.serverRefreshProviders]({})), upsertKeybinding: (input) => transport.request((client) => client[WS_METHODS.serverUpsertKeybinding](input)), getSettings: () => transport.request((client) => client[WS_METHODS.serverGetSettings]({})), updateSettings: (patch) => transport.request((client) => client[WS_METHODS.serverUpdateSettings]({ patch })), subscribeConfig: (listener, options) => transport.subscribe( (client) => client[WS_METHODS.subscribeServerConfig]({}), listener, options, ), subscribeLifecycle: (listener, options) => transport.subscribe( (client) => client[WS_METHODS.subscribeServerLifecycle]({}), listener, options, ), subscribeAuthAccess: (listener, options) => transport.subscribe( (client) => client[WS_METHODS.subscribeAuthAccess]({}), listener, options, ), }, orchestration: { dispatchCommand: (input) => transport.request((client) => client[ORCHESTRATION_WS_METHODS.dispatchCommand](input)), getTurnDiff: (input) => transport.request((client) => client[ORCHESTRATION_WS_METHODS.getTurnDiff](input)), getFullThreadDiff: (input) => transport.request((client) => client[ORCHESTRATION_WS_METHODS.getFullThreadDiff](input)), subscribeShell: (listener, options) => transport.subscribe( (client) => client[ORCHESTRATION_WS_METHODS.subscribeShell]({}), listener, options, ), subscribeThread: (input, listener, options) => transport.subscribe( (client) => client[ORCHESTRATION_WS_METHODS.subscribeThread](input), listener, options, ), }, };}
import {
type GitRunStackedActionResult,
type GitStatusResult,
type GitStatusStreamEvent,
ORCHESTRATION_WS_METHODS,
WS_METHODS,
} from "@t3tools/contracts";
import type { WsRpcClient } from "@t3tools/client-runtime";
import { applyGitStatusStreamEvent } from "@t3tools/shared/git";
import { resetWsReconnectBackoff } from "./wsConnectionState";
import { WsTransport } from "./wsTransport";
export type { WsRpcClient };
export function createWsRpcClient(transport: WsTransport): WsRpcClient {
return {
dispose: () => transport.dispose(),
reconnect: async () => {
resetWsReconnectBackoff();
await transport.reconnect();
},
terminal: {
open: (input) => transport.request((client) => client[WS_METHODS.terminalOpen](input)),
write: (input) => transport.request((client) => client[WS_METHODS.terminalWrite](input)),
resize: (input) => transport.request((client) => client[WS_METHODS.terminalResize](input)),
clear: (input) => transport.request((client) => client[WS_METHODS.terminalClear](input)),
restart: (input) => transport.request((client) => client[WS_METHODS.terminalRestart](input)),
close: (input) => transport.request((client) => client[WS_METHODS.terminalClose](input)),
onEvent: (listener, options) =>
transport.subscribe(
(client) => client[WS_METHODS.subscribeTerminalEvents]({}),
listener,
options,
),
},
projects: {
searchEntries: (input) =>
transport.request((client) => client[WS_METHODS.projectsSearchEntries](input)),
writeFile: (input) =>
transport.request((client) => client[WS_METHODS.projectsWriteFile](input)),
},
shell: {
openInEditor: (input) =>
transport.request((client) => client[WS_METHODS.shellOpenInEditor](input)),
},
git: {
pull: (input) => transport.request((client) => client[WS_METHODS.gitPull](input)),
refreshStatus: (input) =>
transport.request((client) => client[WS_METHODS.gitRefreshStatus](input)),
onStatus: (input, listener, options) => {
let current: GitStatusResult | null = null;
return transport.subscribe(
(client) => client[WS_METHODS.subscribeGitStatus](input),
(event: GitStatusStreamEvent) => {
current = applyGitStatusStreamEvent(current, event);
listener(current);
},
options,
);
},
runStackedAction: async (input, options) => {
let result: GitRunStackedActionResult | null = null;
await transport.requestStream(
(client) => client[WS_METHODS.gitRunStackedAction](input),
(event) => {
options?.onProgress?.(event);
if (event.kind === "action_finished") {
result = event.result;
}
},
);
if (result) {
return result;
}
throw new Error("Git action stream completed without a final result.");
},
listBranches: (input) =>
transport.request((client) => client[WS_METHODS.gitListBranches](input)),
createWorktree: (input) =>
transport.request((client) => client[WS_METHODS.gitCreateWorktree](input)),
removeWorktree: (input) =>
transport.request((client) => client[WS_METHODS.gitRemoveWorktree](input)),
createBranch: (input) =>
transport.request((client) => client[WS_METHODS.gitCreateBranch](input)),
checkout: (input) => transport.request((client) => client[WS_METHODS.gitCheckout](input)),
init: (input) => transport.request((client) => client[WS_METHODS.gitInit](input)),
resolvePullRequest: (input) =>
transport.request((client) => client[WS_METHODS.gitResolvePullRequest](input)),
preparePullRequestThread: (input) =>
transport.request((client) => client[WS_METHODS.gitPreparePullRequestThread](input)),
},
server: {
getConfig: () => transport.request((client) => client[WS_METHODS.serverGetConfig]({})),
refreshProviders: () =>
transport.request((client) => client[WS_METHODS.serverRefreshProviders]({})),
upsertKeybinding: (input) =>
transport.request((client) => client[WS_METHODS.serverUpsertKeybinding](input)),
getSettings: () => transport.request((client) => client[WS_METHODS.serverGetSettings]({})),
updateSettings: (patch) =>
transport.request((client) => client[WS_METHODS.serverUpdateSettings]({ patch })),
subscribeConfig: (listener, options) =>
transport.subscribe(
(client) => client[WS_METHODS.subscribeServerConfig]({}),
listener,
options,
),
subscribeLifecycle: (listener, options) =>
transport.subscribe(
(client) => client[WS_METHODS.subscribeServerLifecycle]({}),
listener,
options,
),
subscribeAuthAccess: (listener, options) =>
transport.subscribe(
(client) => client[WS_METHODS.subscribeAuthAccess]({}),
listener,
options,
),
},
orchestration: {
dispatchCommand: (input) =>
transport.request((client) => client[ORCHESTRATION_WS_METHODS.dispatchCommand](input)),
getTurnDiff: (input) =>
transport.request((client) => client[ORCHESTRATION_WS_METHODS.getTurnDiff](input)),
getFullThreadDiff: (input) =>
transport.request((client) => client[ORCHESTRATION_WS_METHODS.getFullThreadDiff](input)),
subscribeShell: (listener, options) =>
transport.subscribe(
(client) => client[ORCHESTRATION_WS_METHODS.subscribeShell]({}),
listener,
options,
),
subscribeThread: (input, listener, options) =>
transport.subscribe(
(client) => client[ORCHESTRATION_WS_METHODS.subscribeThread](input),
listener,
options,
),
},
};
}