diff --git a/apps/mobile/src/state/connection-transport-coordinator.test.ts b/apps/mobile/src/state/connection-transport-coordinator.test.ts index a418b7a..17ed26b 100644 --- a/apps/mobile/src/state/connection-transport-coordinator.test.ts +++ b/apps/mobile/src/state/connection-transport-coordinator.test.ts @@ -14,6 +14,28 @@ jest.mock("@opencode2-mobile/opencode-adapter", () => ({ typeof error === "object" && error !== null && "_tag" in error ? "UNAUTHORIZED" : "UNREACHABLE", })); +test("passes project snapshot cancellation in the request-options argument", async () => { + const stream = createEventStream(); + const snapshots = createSnapshotClient(true); + const coordinator = createCoordinator({ + eventClient: { event: { subscribe: stream.subscribe } } as never, + restClient: snapshots.client, + }); + + coordinator.start(); + await flush(); + + expect(snapshots.client.project.list).toHaveBeenCalledWith(undefined, { + signal: expect.any(AbortSignal), + }); + expect(snapshots.client.project.list).toHaveBeenCalledWith( + undefined, + stream.subscribe.mock.calls[0]?.[0], + ); + coordinator.stop(); + expect(stream.subscribe.mock.calls[0]?.[0]?.signal?.aborted).toBe(true); +}); + test("buffers events until authoritative snapshots are installed", async () => { const stream = createEventStream(); const snapshots = createSnapshotClient(); diff --git a/apps/mobile/src/state/connection-transport-coordinator.ts b/apps/mobile/src/state/connection-transport-coordinator.ts index 0aa542d..e0cb4bb 100644 --- a/apps/mobile/src/state/connection-transport-coordinator.ts +++ b/apps/mobile/src/state/connection-transport-coordinator.ts @@ -146,7 +146,7 @@ export class ConnectionTransportCoordinator { const requestOptions = { signal: controller.signal }; void Promise.all([ this.options.restClient.server.status(requestOptions), - this.options.restClient.project.list(requestOptions), + this.options.restClient.project.list(undefined, requestOptions), this.options.restClient.session.active(requestOptions), ]) .then(([health, projects, activeSessions]) => { diff --git a/packages/opencode-adapter/package.json b/packages/opencode-adapter/package.json index 6d36a0a..92488b2 100644 --- a/packages/opencode-adapter/package.json +++ b/packages/opencode-adapter/package.json @@ -18,7 +18,7 @@ "typecheck": "tsc -p tsconfig.json" }, "dependencies": { - "@opencode/client": "2.0.26" + "@opencode/client": "2.0.27" }, "devDependencies": { "@opencode2-mobile/test-fixtures": "workspace:*", diff --git a/packages/opencode-adapter/src/index.test.ts b/packages/opencode-adapter/src/index.test.ts index 7df9a4e..a7c5ddb 100644 --- a/packages/opencode-adapter/src/index.test.ts +++ b/packages/opencode-adapter/src/index.test.ts @@ -37,6 +37,7 @@ import { listOpenCodeModels, listOpenCodePermissionRequests, listOpenCodeProjectSessions, + listOpenCodeProjects, listOpenCodeSessionInbox, listOpenCodeSessions, listOpenCodeSkills, @@ -61,6 +62,20 @@ import { waitForOpenCodeSession, } from "./index"; +describe("project listing", () => { + it("forwards cancellation as request options without adding project filters", async () => { + const fixture = createFakeOpenCodeApi(); + const fetch = vi.fn(fixture.fetch); + const client = createOpenCodeClient({ baseUrl: "http://fake.invalid", fetch }); + const signal = new AbortController().signal; + + await expect(listOpenCodeProjects(client, { signal })).resolves.toEqual([]); + + expect(fetch.mock.calls[0]?.[1]?.signal).toBe(signal); + expect(fixture.requests).toEqual([{ method: "GET", path: "/api/project", query: {} }]); + }); +}); + describe("location MCP controls", () => { it("lists and connects/disconnects at the exact location without changing other locations", async () => { const fixture = createFakeOpenCodeApi({ diff --git a/packages/opencode-adapter/src/index.ts b/packages/opencode-adapter/src/index.ts index f853609..d84939c 100644 --- a/packages/opencode-adapter/src/index.ts +++ b/packages/opencode-adapter/src/index.ts @@ -23,7 +23,7 @@ import { import { ensurePromiseWithResolvers } from "./promise-with-resolvers"; -export const openCodeClientContractVersion = "2.0.26"; +export const openCodeClientContractVersion = "2.0.27"; export type OpenCodeClientOptions = { authorization?: string; @@ -354,7 +354,7 @@ export async function listOpenCodeProjects( client: OpenCodeClient, options?: OpenCodeRequestOptions, ) { - const projects = await client.project.list(options); + const projects = await client.project.list(undefined, options); if (!Array.isArray(projects) || !projects.every(isValidProject)) { throw new Error("MALFORMED_PROJECT_LIST"); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7dd692a..fcfb35b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -203,8 +203,8 @@ importers: packages/opencode-adapter: dependencies: '@opencode/client': - specifier: 2.0.26 - version: 2.0.26(effect@4.0.0-rc.112) + specifier: 2.0.27 + version: 2.0.27(effect@4.0.1) devDependencies: '@opencode2-mobile/test-fixtures': specifier: workspace:* @@ -1437,36 +1437,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': - resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} - cpu: [arm64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': - resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} - cpu: [x64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': - resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} - cpu: [arm64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': - resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} - cpu: [arm] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': - resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} - cpu: [x64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': - resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} - cpu: [x64] - os: [win32] - '@noble/ciphers@1.0.0': resolution: {integrity: sha512-wH5EHOmLi0rEazphPbecAzmjd12I6/Yv/SiHdkA9LSycsQk7RuuTp7am5/o62qYr0RScE7Pc9icXGBbsr6cesA==} engines: {node: ^14.21.3 || >=16} @@ -1536,17 +1506,6 @@ packages: '@opencode/ai@2.0.27': resolution: {integrity: sha512-RiVtSBo1veffbDnrWo++04XdlcSEzqCAxo1TWDtG/5fZSjWLuiII6OT6Fo/N8ScU/awy9X3omfvun1aq4Lfttw==} - '@opencode/client@2.0.26': - resolution: {integrity: sha512-0uqhXq6DJYjas3mc4roTyWAmhJpyO2gJaMcenoiA22RXJSOSIwPFho5K4qGmYDJGd5Fvvswh++Nr/wfjaHAYyg==} - peerDependencies: - effect: 4.0.0-rc.112 - solid-js: '>=1.9.0' - peerDependenciesMeta: - effect: - optional: true - solid-js: - optional: true - '@opencode/client@2.0.27': resolution: {integrity: sha512-RqJodg+QsUgqqJVo+b2PGk2w96l7424nM4BijUSb49Iep9IyUfjDH3zfii4OGfCsmZkNCYK83Mgk9e9EeRA1iQ==} peerDependencies: @@ -1575,15 +1534,9 @@ packages: solid-js: optional: true - '@opencode/protocol@2.0.26': - resolution: {integrity: sha512-Q+kbu0zTneh0RC4jhiuB19WeP8et9dWXGJVjb5EbUdJ8E1j5Eh0lAyqLXlM2tzTxfMfK3gos9ss6mxMVsvDFIg==} - '@opencode/protocol@2.0.27': resolution: {integrity: sha512-t1j+m5T3TBusHaL58t6gSSQQEFoi+qjVyQ0Eta/4mLeZLJDqSV8BNN6N93GFpV2MJ1iBpGmrH0C02n2Q+nDHfw==} - '@opencode/schema@2.0.26': - resolution: {integrity: sha512-DZ09xXCTkTI3Y9VzuQHsm5AMGh67EqkUM13lC0LGKvD12RAYaVmRX5lDv5AnD3OkmUmPPWLYWjicT18CDloy6Q==} - '@opencode/schema@2.0.27': resolution: {integrity: sha512-BxGuiIFo503tW6UYxoBrrgjyczEvPiU3fDn45FxUHtmZgBC8kFE+ldI56ab8kV0Lu5C94ZKOniRb2bWqDu4tAg==} @@ -2932,9 +2885,6 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@4.0.0-rc.112: - resolution: {integrity: sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==} - effect@4.0.1: resolution: {integrity: sha512-b1VlQG9g8fwxE5QnIZuPoOP/0MsqHJSRKxUijjoM80E5q95FXrX5yWtY5XI8G+GJsBQAVSDbLS458z9a++uVvw==} @@ -3283,10 +3233,6 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fast-check@4.9.0: - resolution: {integrity: sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==} - engines: {node: '>=12.17.0'} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -4354,13 +4300,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msgpackr-extract@3.0.4: - resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} - hasBin: true - - msgpackr@2.0.5: - resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==} - mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -4400,10 +4339,6 @@ packages: resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} engines: {node: '>= 6.13.0'} - node-gyp-build-optional-packages@5.2.2: - resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} - hasBin: true - node-gyp@12.4.0: resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} engines: {node: ^20.17.0 || >=22.9.0} @@ -4708,9 +4643,6 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - pure-rand@8.4.2: - resolution: {integrity: sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==} - qrcode-terminal@0.11.0: resolution: {integrity: sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==} hasBin: true @@ -7309,24 +7241,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': - optional: true - '@noble/ciphers@1.0.0': {} '@npmcli/agent@4.0.2(supports-color@8.1.1)': @@ -7469,13 +7383,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@opencode/client@2.0.26(effect@4.0.0-rc.112)': - dependencies: - '@opencode/protocol': 2.0.26 - '@opencode/schema': 2.0.26 - optionalDependencies: - effect: 4.0.0-rc.112 - '@opencode/client@2.0.27(effect@4.0.1)': dependencies: '@opencode/protocol': 2.0.27 @@ -7500,21 +7407,11 @@ snapshots: - supports-color - utf-8-validate - '@opencode/protocol@2.0.26': - dependencies: - '@opencode/schema': 2.0.26 - effect: 4.0.0-rc.112 - '@opencode/protocol@2.0.27': dependencies: '@opencode/schema': 2.0.27 effect: 4.0.1 - '@opencode/schema@2.0.26': - dependencies: - '@standard-schema/spec': 1.1.0 - effect: 4.0.0-rc.112 - '@opencode/schema@2.0.27': dependencies: '@standard-schema/spec': 1.1.0 @@ -8983,11 +8880,6 @@ snapshots: ee-first@1.1.1: {} - effect@4.0.0-rc.112: - dependencies: - fast-check: 4.9.0 - msgpackr: 2.0.5 - effect@4.0.1: {} electron-to-chromium@1.5.412: {} @@ -9377,10 +9269,6 @@ snapshots: extend@3.0.2: {} - fast-check@4.9.0: - dependencies: - pure-rand: 8.4.2 - fast-deep-equal@3.1.3: {} fast-json-stable-stringify@2.1.0: {} @@ -10940,22 +10828,6 @@ snapshots: ms@2.1.3: {} - msgpackr-extract@3.0.4: - dependencies: - node-gyp-build-optional-packages: 5.2.2 - optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 - optional: true - - msgpackr@2.0.5: - optionalDependencies: - msgpackr-extract: 3.0.4 - mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -10984,11 +10856,6 @@ snapshots: node-forge@1.4.0: {} - node-gyp-build-optional-packages@5.2.2: - dependencies: - detect-libc: 2.1.2 - optional: true - node-gyp@12.4.0: dependencies: env-paths: 2.2.1 @@ -11318,8 +11185,6 @@ snapshots: pure-rand@6.1.0: {} - pure-rand@8.4.2: {} - qrcode-terminal@0.11.0: {} qrcode-terminal@0.12.0: {}