Publish the TypeScript SDK and integration guides (#3141)
* feat(client): publish the TypeScript SDK surface Make the high-level client API usable for external integrations and document complete agent, workspace, provider, event, and recipe flows. * fix(client): correlate provider snapshots by daemon cwd Return the daemon's canonical snapshot identity so waitForReady can match updates for relative, tilde, and otherwise non-canonical paths without duplicating filesystem rules in the SDK. * test(server): make snapshot cwd assertion portable * fix(client): gate canonical provider snapshot waits Older daemons do not expose the canonical snapshot identity needed to correlate workspace updates safely. Require the advertised capability and fail with an update-host message instead of guessing across workspaces.
This commit is contained in:
@@ -116,6 +116,23 @@ describe("ProviderCatalogSession", () => {
|
||||
expect(pull?.payload.entries).toEqual(push?.payload.entries);
|
||||
});
|
||||
|
||||
it("returns the canonical cwd used by snapshot updates", async () => {
|
||||
const getSnapshot = vi.fn((_cwd?: string) => makeEntries());
|
||||
const { subsystem, emitted } = makeSubsystem({
|
||||
snapshot: { getSnapshot },
|
||||
});
|
||||
|
||||
await subsystem.handleGetProvidersSnapshotRequest({
|
||||
type: "get_providers_snapshot_request",
|
||||
requestId: "canonical-cwd",
|
||||
cwd: "/repo/./sdk",
|
||||
});
|
||||
|
||||
const canonicalCwd = getSnapshot.mock.calls[0]?.[0];
|
||||
expect(canonicalCwd).toEqual(expect.any(String));
|
||||
expect(findByType(emitted, "get_providers_snapshot_response")?.payload.cwd).toBe(canonicalCwd);
|
||||
});
|
||||
|
||||
it("pushes the compact encoding to capable clients", () => {
|
||||
const { subsystem, emitted, pushSnapshotChange } = makeSubsystem({
|
||||
supportsCustomModeIcons: true,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import type { SessionInboundMessage, SessionOutboundMessage } from "../../messages.js";
|
||||
import {
|
||||
isGlobalProviderSnapshotKey,
|
||||
resolveSnapshotCwd,
|
||||
type ProviderSnapshotManager,
|
||||
} from "../../agent/provider-snapshot-manager.js";
|
||||
import {
|
||||
@@ -391,8 +392,9 @@ export class ProviderCatalogSession {
|
||||
msg: Extract<SessionInboundMessage, { type: "get_providers_snapshot_request" }>,
|
||||
): Promise<void> {
|
||||
// COMPAT(providersSnapshot): keep legacy provider-list RPCs alongside snapshot flow.
|
||||
const snapshotCwd = msg.cwd?.trim() ? resolveSnapshotCwd(expandTilde(msg.cwd)) : undefined;
|
||||
const entries = this.providerSnapshotManager
|
||||
.getSnapshot(msg.cwd ? expandTilde(msg.cwd) : undefined)
|
||||
.getSnapshot(snapshotCwd)
|
||||
.filter((entry) => this.host.isProviderVisibleToClient(entry.provider));
|
||||
const clientEntries = this.downgradeEntryModesForClient(entries);
|
||||
|
||||
@@ -402,6 +404,7 @@ export class ProviderCatalogSession {
|
||||
this.host.emit({
|
||||
type: "get_providers_snapshot_response",
|
||||
payload: {
|
||||
...(snapshotCwd ? { cwd: snapshotCwd } : {}),
|
||||
entries: [],
|
||||
...(!notModified ? { compactSnapshot: encoded.compactSnapshot } : {}),
|
||||
snapshotHash: encoded.snapshotHash,
|
||||
@@ -416,6 +419,7 @@ export class ProviderCatalogSession {
|
||||
this.host.emit({
|
||||
type: "get_providers_snapshot_response",
|
||||
payload: {
|
||||
...(snapshotCwd ? { cwd: snapshotCwd } : {}),
|
||||
entries: clientEntries,
|
||||
generatedAt: new Date().toISOString(),
|
||||
requestId: msg.requestId,
|
||||
|
||||
@@ -933,6 +933,7 @@ describe("relay external socket reconnect behavior", () => {
|
||||
|
||||
expect(serverInfo.features?.stableProjectIdentity).toBe(true);
|
||||
expect(serverInfo.features?.canonicalSubmittedPrompts).toBe(true);
|
||||
expect(serverInfo.features?.providersSnapshotCwd).toBe(true);
|
||||
expect(serverInfo.features?.["terminal-input-mode-replay"]).toBe(true);
|
||||
expect(serverInfo.features?.["terminal-size-ownership"]).toBe(true);
|
||||
expect(serverInfo.features?.agentTurnIdentity).toBeUndefined();
|
||||
|
||||
@@ -1526,6 +1526,8 @@ export class VoiceAssistantWebSocketServer {
|
||||
features: {
|
||||
// COMPAT(providersSnapshot): keep optional until all clients rely on snapshot flow.
|
||||
providersSnapshot: true,
|
||||
// COMPAT(providersSnapshotCwd): added in v0.3.2, remove gate after 2027-02-10.
|
||||
providersSnapshotCwd: true,
|
||||
// COMPAT(checkoutForgeSetAutoMerge): added in v0.1.106, remove old
|
||||
// checkoutGithubSetAutoMerge fallback after 2026-12-28.
|
||||
checkoutForgeSetAutoMerge: true,
|
||||
|
||||
Reference in New Issue
Block a user