From db8d3c6590909eff5f00a16a709b5d7cb0f67f2b Mon Sep 17 00:00:00 2001 From: Justin Carper Date: Tue, 16 Jun 2026 15:19:21 -0400 Subject: [PATCH 1/7] feat(read): surface lines-read/total in Read transcript label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor ReadArgs = { path } only — no offset/limit (cursor-sdk-shared ReadArgsSchema is a strip object). Two same-path reads are re-reads of identical content, never different sections. Derive per-call detail from result instead: count content lines and compare to totalLines. Title becomes e.g. "handlers.go (2000/5000 lines)" so a reader can spot redundant re-reads and see truncation at a glance. Also stores linesReturned + fileSize in block metadata, and documents the no-range constraint in a comment above the adapter so the question does not recur. --- src/provider/stream-map.ts | 19 ++++++++++++++++++- test/stream-map.test.ts | 25 +++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/provider/stream-map.ts b/src/provider/stream-map.ts index 768b485..8f0b488 100644 --- a/src/provider/stream-map.ts +++ b/src/provider/stream-map.ts @@ -313,6 +313,15 @@ const NATIVE_ADAPTERS: Record = { }, }, // Cursor `read` → opencode `read`. + // + // Cursor's read tool takes ONLY `{ path }` — there is no `offset`/`limit`/ + // line-range arg (see `@cursor/sdk` `ReadArgsSchema`, a `{ path: string }` + // "strip" object). The model therefore cannot request a sub-range, so two + // same-path reads in a transcript are RE-READS of the same content, never + // "different sections". The only per-call detail available is in the result + // `value` (`content`, `totalLines`, `fileSize`); we derive the lines-read + // count from `content` and surface `linesReturned/totalLines` in the title + // so a reader can see how much was read and spot redundant re-reads. read: { tool: "read", input: (args) => ({ filePath: strField(args, "path") ?? "" }), @@ -321,12 +330,20 @@ const NATIVE_ADAPTERS: Record = { if (content === undefined) return null; const filePath = strField(args, "path") ?? ""; const totalLines = numField(value, "totalLines"); + const fileSize = numField(value, "fileSize"); + const linesReturned = content.split("\n").length; + const lineLabel = + totalLines !== undefined + ? `${linesReturned}/${totalLines} lines` + : `${linesReturned} lines`; return { - title: filePath, + title: `${filePath} (${lineLabel})`, metadata: { preview: content.split("\n").slice(0, 20).join("\n"), loaded: [] as string[], + linesReturned, ...(totalLines !== undefined ? { totalLines } : {}), + ...(fileSize !== undefined ? { fileSize } : {}), }, output: content, }; diff --git a/test/stream-map.test.ts b/test/stream-map.test.ts index f1cf927..d18ef36 100644 --- a/test/stream-map.test.ts +++ b/test/stream-map.test.ts @@ -894,9 +894,30 @@ describe("native tool mapping (blocks)", () => { input: JSON.stringify({ filePath: "/a.ts" }), }); expect(foldedResult(result)).toMatchObject({ - title: "/a.ts", + title: "/a.ts (2/2 lines)", output: "l1\nl2", - metadata: { preview: "l1\nl2", totalLines: 2 }, + metadata: { + preview: "l1\nl2", + totalLines: 2, + linesReturned: 2, + fileSize: 6, + }, + }); + }); + + it("read title shows lines-read/total when Cursor truncates the file", async () => { + const { result } = await mapTool( + "read", + { path: "/a.ts" }, + { + status: "success", + value: { content: "l1", totalLines: 10, fileSize: 99 }, + }, + ); + expect(foldedResult(result)).toMatchObject({ + title: "/a.ts (1/10 lines)", + output: "l1", + metadata: { linesReturned: 1, totalLines: 10, fileSize: 99 }, }); }); From da16c6d28d400de13deb617c442831e06868af91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 04:15:15 +0000 Subject: [PATCH 2/7] chore(deps-dev): bump the dev-dependencies group with 2 updates Bumps the dev-dependencies group with 2 updates: [@opencode-ai/sdk](https://github.com/sst/opencode-sdk-js) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest). Updates `@opencode-ai/sdk` from 1.17.3 to 1.17.7 - [Release notes](https://github.com/sst/opencode-sdk-js/releases) - [Changelog](https://github.com/anomalyco/opencode-sdk-js/blob/main/CHANGELOG.md) - [Commits](https://github.com/sst/opencode-sdk-js/commits) Updates `vitest` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/vitest) --- updated-dependencies: - dependency-name: "@opencode-ai/sdk" dependency-version: 1.17.7 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: vitest dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] --- package-lock.json | 104 +++++++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb2ff70..74298bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -826,6 +826,15 @@ } } }, + "node_modules/@opencode-ai/plugin/node_modules/@opencode-ai/sdk": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.17.3.tgz", + "integrity": "sha512-oXrEjOuP3+J9pPNw3cmOnRma/xiVQ4WIIvGd6YkhPQgqqi2PnD/b1qfNY0AMead3QfNhKwKdDM4QFJdN2LpByg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "7.0.6" + } + }, "node_modules/@opencode-ai/plugin/node_modules/zod": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.8.tgz", @@ -836,9 +845,10 @@ } }, "node_modules/@opencode-ai/sdk": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.17.3.tgz", - "integrity": "sha512-oXrEjOuP3+J9pPNw3cmOnRma/xiVQ4WIIvGd6YkhPQgqqi2PnD/b1qfNY0AMead3QfNhKwKdDM4QFJdN2LpByg==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.17.7.tgz", + "integrity": "sha512-7q7StGM+N0OwUgRsmDc8Gyz3hMIH1XGig+qZ4lzWUpmSgFEjLx8U7R14GXY7KiMJVdbVf6FeaYloRz2Rcsma4A==", + "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "7.0.6" @@ -1593,16 +1603,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", - "integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", + "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -1611,13 +1621,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz", - "integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", + "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.8", + "@vitest/spy": "4.1.9", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -1638,9 +1648,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz", - "integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", + "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", "dev": true, "license": "MIT", "dependencies": { @@ -1651,13 +1661,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz", - "integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", + "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.9", "pathe": "^2.0.3" }, "funding": { @@ -1665,14 +1675,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz", - "integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", + "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/pretty-format": "4.1.9", + "@vitest/utils": "4.1.9", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -1681,9 +1691,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz", - "integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", + "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", "dev": true, "license": "MIT", "funding": { @@ -1691,13 +1701,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", - "integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", + "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", + "@vitest/pretty-format": "4.1.9", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -3724,19 +3734,19 @@ } }, "node_modules/vitest": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz", - "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", + "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.8", - "@vitest/mocker": "4.1.8", - "@vitest/pretty-format": "4.1.8", - "@vitest/runner": "4.1.8", - "@vitest/snapshot": "4.1.8", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/expect": "4.1.9", + "@vitest/mocker": "4.1.9", + "@vitest/pretty-format": "4.1.9", + "@vitest/runner": "4.1.9", + "@vitest/snapshot": "4.1.9", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -3764,12 +3774,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.8", - "@vitest/browser-preview": "4.1.8", - "@vitest/browser-webdriverio": "4.1.8", - "@vitest/coverage-istanbul": "4.1.8", - "@vitest/coverage-v8": "4.1.8", - "@vitest/ui": "4.1.8", + "@vitest/browser-playwright": "4.1.9", + "@vitest/browser-preview": "4.1.9", + "@vitest/browser-webdriverio": "4.1.9", + "@vitest/coverage-istanbul": "4.1.9", + "@vitest/coverage-v8": "4.1.9", + "@vitest/ui": "4.1.9", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" From bc72414bb2dd869a5941e250df316681e4a564a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 04:15:19 +0000 Subject: [PATCH 3/7] chore(deps): bump @cursor/sdk from 1.0.18 to 1.0.19 Bumps [@cursor/sdk](https://github.com/cursor/cursor) from 1.0.18 to 1.0.19. - [Commits](https://github.com/cursor/cursor/commits) --- updated-dependencies: - dependency-name: "@cursor/sdk" dependency-version: 1.0.19 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 716 +++------------------------------------------- 1 file changed, 32 insertions(+), 684 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb2ff70..1132b1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,50 +55,43 @@ "@bufbuild/protobuf": "^1.10.0" } }, - "node_modules/@connectrpc/connect-node": { + "node_modules/@connectrpc/connect-web": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@connectrpc/connect-node/-/connect-node-1.7.0.tgz", - "integrity": "sha512-6vaPIkG/NyhxlYgytLoR9KYbPhczEboFB2OYWkA9qvUz1K7efXfeGrlRxoLtpa+r8VxyIOw73w5ktNe743nD+A==", + "resolved": "https://registry.npmjs.org/@connectrpc/connect-web/-/connect-web-1.7.0.tgz", + "integrity": "sha512-qyP0YOnUPRWwCc/VfsoydMJvkb7EyUPr2q9sHgBuJzbADjiqck1gKH5V5ZPzPhTLBvmz5UvG+wiZ5sMRQHU1MQ==", "license": "Apache-2.0", - "dependencies": { - "undici": "^5.28.4" - }, - "engines": { - "node": ">=16.0.0" - }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", "@connectrpc/connect": "1.7.0" } }, "node_modules/@cursor/sdk": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk/-/sdk-1.0.18.tgz", - "integrity": "sha512-ha5EGHliMuTNuAqnPHzKFNnND4y6erddTqtxwIt9/p8ER+QsmMoRcP38PwA2sXfZnGvIBiozveBZqa4XwUddCw==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk/-/sdk-1.0.19.tgz", + "integrity": "sha512-DJbVnGeRJq7iwt9mz1cMACqVfAYP15IB+Q8Iz2eDtEN4A8Dp83yB0Y31YREj1jeA9EPUEdRZJRIYch/s+Wi9Ow==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@bufbuild/protobuf": "1.10.0", "@connectrpc/connect": "^1.6.1", - "@connectrpc/connect-node": "^1.6.1", + "@connectrpc/connect-web": "^1.6.1", "@statsig/js-client": "3.31.0", - "sqlite3": "^5.1.7", "zod": "^3.25.0" }, "engines": { - "node": ">=18" + "node": ">=22.13" }, "optionalDependencies": { - "@cursor/sdk-darwin-arm64": "1.0.18", - "@cursor/sdk-darwin-x64": "1.0.18", - "@cursor/sdk-linux-arm64": "1.0.18", - "@cursor/sdk-linux-x64": "1.0.18", - "@cursor/sdk-win32-x64": "1.0.18" + "@cursor/sdk-darwin-arm64": "1.0.19", + "@cursor/sdk-darwin-x64": "1.0.19", + "@cursor/sdk-linux-arm64": "1.0.19", + "@cursor/sdk-linux-x64": "1.0.19", + "@cursor/sdk-win32-x64": "1.0.19" } }, "node_modules/@cursor/sdk-darwin-arm64": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk-darwin-arm64/-/sdk-darwin-arm64-1.0.18.tgz", - "integrity": "sha512-gXfNz+n3uf2hWCUcSdU/gBYT7TFlWwJjZAAjXFzBJ3jGu+l7ShQRa9QI2sEKvPNRtUMC/18EcQ26ks1o261Bnw==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk-darwin-arm64/-/sdk-darwin-arm64-1.0.19.tgz", + "integrity": "sha512-CPhqcpDaqjjqkkVGMLsdfXv7PGznL5L6U5CJXps/oaGW5mtHoxDpsRNj1rszCRQXNAvmMU+EFxLWnBwlE8mUNg==", "cpu": [ "arm64" ], @@ -112,9 +105,9 @@ } }, "node_modules/@cursor/sdk-darwin-x64": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk-darwin-x64/-/sdk-darwin-x64-1.0.18.tgz", - "integrity": "sha512-nzcPqCvPPnYsuz21olPgandVgGUzDZkHN4cUls4ukm7mddp6XqujFJv8lh9qKmVefl0/3UL2R6GFANggjwifnA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk-darwin-x64/-/sdk-darwin-x64-1.0.19.tgz", + "integrity": "sha512-6/Jj0hxrxEs9V9wtYEApSkMcJwYAaT4Vwna9xBzgN6CK1K4Ws0E1/PfiddahAAFZpkp9pgjb8wQXwG7qJ2g77A==", "cpu": [ "x64" ], @@ -128,9 +121,9 @@ } }, "node_modules/@cursor/sdk-linux-arm64": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk-linux-arm64/-/sdk-linux-arm64-1.0.18.tgz", - "integrity": "sha512-MJyhVryN+0czP48SgMak/KA9xGneQ/gdsnDk1ZTJF+LemaFc+Tv7P1GT80h+3JBfu69kPyIX4epJVjroTMoFEA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk-linux-arm64/-/sdk-linux-arm64-1.0.19.tgz", + "integrity": "sha512-Dq/BhGT1jAZ6eHJwy1Vugi/Upc+yoL0X/LN6ppd9cVPM9OAB1xX5KIbvIwsGlNiZccPLVXFv/1KOp5SBK+y+jQ==", "cpu": [ "arm64" ], @@ -144,9 +137,9 @@ } }, "node_modules/@cursor/sdk-linux-x64": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk-linux-x64/-/sdk-linux-x64-1.0.18.tgz", - "integrity": "sha512-IaJqcKtXxtQEdPxivQjDWbvynw3UX31V8RdagcZ6RgHOo+B/i/P95D8svSNC4V9nbTHwVbNGfIDQ5S64gMS2hg==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk-linux-x64/-/sdk-linux-x64-1.0.19.tgz", + "integrity": "sha512-ZHgHH+SdEwYwfPg/uVKqZRVOIMCV3/3vghxc/usOMYMrhbY9TYXZxYqwWTduVLzCXH7Dz0aT19mSJHmhwkQ1CA==", "cpu": [ "x64" ], @@ -160,9 +153,9 @@ } }, "node_modules/@cursor/sdk-win32-x64": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/@cursor/sdk-win32-x64/-/sdk-win32-x64-1.0.18.tgz", - "integrity": "sha512-iqcGt1l/3xgnaT+PotY3237oyK3VnOZHtjUxSRP3Q7ahjaqsZVTnCwwljj+nal8ouvXidBHnxQLqGMSC2G6LTg==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@cursor/sdk-win32-x64/-/sdk-win32-x64-1.0.19.tgz", + "integrity": "sha512-XGIQmx3J0K8uKkA00qnoy1FJHFdFdwNdcmUqtRF1PXLcYup91YYetAHk9afXM7S/v1t0L4EatydsirL8uz7SIw==", "cpu": [ "x64" ], @@ -651,18 +644,6 @@ "node": ">=18" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1705,16 +1686,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/abbrev": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", - "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", - "license": "ISC", - "optional": true, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -1745,70 +1716,6 @@ "node": ">=12" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/bundle-require": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", @@ -1861,15 +1768,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -1936,34 +1834,11 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -1987,25 +1862,6 @@ "yaml": "^2.9.0" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/es-module-lexer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", @@ -2065,15 +1921,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -2084,13 +1931,6 @@ "node": ">=12.0.0" } }, - "node_modules/exponential-backoff": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", - "license": "Apache-2.0", - "optional": true - }, "node_modules/fast-check": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.8.0.tgz", @@ -2117,7 +1957,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -2131,12 +1971,6 @@ } } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, "node_modules/find-my-way-ts": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz", @@ -2155,12 +1989,6 @@ "rollup": "^4.34.8" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2176,45 +2004,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC", - "optional": true - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, "node_modules/ini": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-7.0.0.tgz", @@ -2566,54 +2355,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", @@ -2702,55 +2443,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.92.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.92.0.tgz", - "integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT" - }, - "node_modules/node-gyp": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", - "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", - "license": "MIT", - "optional": true, - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "graceful-fs": "^4.2.6", - "nopt": "^9.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5", - "tar": "^7.5.4", - "tinyglobby": "^0.2.12", - "undici": "^6.25.0", - "which": "^6.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/node-gyp-build-optional-packages": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", @@ -2766,48 +2458,6 @@ "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/node-gyp/node_modules/isexe": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", - "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", - "license": "BlueOak-1.0.0", - "optional": true, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-gyp/node_modules/which": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", - "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", - "license": "ISC", - "optional": true, - "dependencies": { - "isexe": "^4.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/nopt": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", - "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", - "license": "ISC", - "optional": true, - "dependencies": { - "abbrev": "^4.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2832,15 +2482,6 @@ "node": ">=12.20.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2868,7 +2509,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -2971,53 +2612,6 @@ } } }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", - "license": "ISC", - "optional": true, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/pure-rand": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz", @@ -3034,41 +2628,6 @@ ], "license": "MIT" }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -3172,38 +2731,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3232,51 +2759,6 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -3297,30 +2779,6 @@ "node": ">=0.10.0" } }, - "node_modules/sqlite3": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", - "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^7.0.0", - "prebuild-install": "^7.1.1", - "tar": "^6.1.11" - }, - "optionalDependencies": { - "node-gyp": "8.x" - }, - "peerDependencies": { - "node-gyp": "8.x" - }, - "peerDependenciesMeta": { - "node-gyp": { - "optional": true - } - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3335,24 +2793,6 @@ "dev": true, "license": "MIT" }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sucrase": { "version": "3.35.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", @@ -3376,56 +2816,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/tar": { - "version": "7.5.16", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz", - "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar-fs": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -3467,7 +2857,7 @@ "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -3577,18 +2967,6 @@ } } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", @@ -3610,15 +2988,6 @@ "dev": true, "license": "MIT" }, - "node_modules/undici": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.26.0.tgz", - "integrity": "sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, "node_modules/undici-types": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", @@ -3626,12 +2995,6 @@ "dev": true, "license": "MIT" }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/uuid": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", @@ -3855,21 +3218,6 @@ "node": ">=8" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/yaml": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", From d0e597aaa8ab40bfe91ca14d432311e84152e06b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 04:15:28 +0000 Subject: [PATCH 4/7] chore(deps): bump @opencode-ai/plugin from 1.17.3 to 1.17.7 Bumps @opencode-ai/plugin from 1.17.3 to 1.17.7. --- updated-dependencies: - dependency-name: "@opencode-ai/plugin" dependency-version: 1.17.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb2ff70..7f9f341 100644 --- a/package-lock.json +++ b/package-lock.json @@ -800,12 +800,12 @@ } }, "node_modules/@opencode-ai/plugin": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.17.3.tgz", - "integrity": "sha512-Qz1ADiWxxXwuetXs6FE2T0kQmPXM6F8XDXE73SdC/oBZFYg7Oc1nf74GaEGhrvqQSMYm4kR6dHNF2jPVKn4eFw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.17.7.tgz", + "integrity": "sha512-/MXRdz5z5tDySwMM4v02cN0om1QgALyE8FTXFU93zKV4I/oW5a0IjQ7dK8Iue3NpRc9e5UHhgO5ELeNLqnpWPA==", "license": "MIT", "dependencies": { - "@opencode-ai/sdk": "1.17.3", + "@opencode-ai/sdk": "1.17.7", "effect": "4.0.0-beta.74", "zod": "4.1.8" }, @@ -836,9 +836,9 @@ } }, "node_modules/@opencode-ai/sdk": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.17.3.tgz", - "integrity": "sha512-oXrEjOuP3+J9pPNw3cmOnRma/xiVQ4WIIvGd6YkhPQgqqi2PnD/b1qfNY0AMead3QfNhKwKdDM4QFJdN2LpByg==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.17.7.tgz", + "integrity": "sha512-7q7StGM+N0OwUgRsmDc8Gyz3hMIH1XGig+qZ4lzWUpmSgFEjLx8U7R14GXY7KiMJVdbVf6FeaYloRz2Rcsma4A==", "license": "MIT", "dependencies": { "cross-spawn": "7.0.6" From bff8ccd23cfee02a27266796ebabd0eef834ad94 Mon Sep 17 00:00:00 2001 From: Justin Carper Date: Wed, 17 Jun 2026 07:35:37 -0400 Subject: [PATCH 5/7] chore(release): 0.4.1-next.0 Consolidate dependency updates and Read transcript feature for @next prerelease: - feat(read): surface lines-read/total in Read transcript label (#26) - chore(deps-dev): bump dev-dependencies group, 2 updates (#27) - chore(deps): bump @cursor/sdk 1.0.18 -> 1.0.19 (#28) - chore(deps): bump @opencode-ai/plugin 1.17.3 -> 1.17.7 (#29) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d26c33c..934b228 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@stablekernel/opencode-cursor", - "version": "0.4.0", + "version": "0.4.1-next.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@stablekernel/opencode-cursor", - "version": "0.4.0", + "version": "0.4.1-next.0", "license": "MIT", "dependencies": { "@cursor/sdk": "^1.0.18", diff --git a/package.json b/package.json index 3a6604c..f00defe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@stablekernel/opencode-cursor", - "version": "0.4.0", + "version": "0.4.1-next.0", "description": "opencode provider plugin backed by the official Cursor SDK (@cursor/sdk) — adds a Cursor provider and lists its models", "type": "module", "license": "MIT", From 302b0883e329e29a07f9dbdb21ee563b8581a2a1 Mon Sep 17 00:00:00 2001 From: Justin Carper Date: Wed, 17 Jun 2026 07:45:18 -0400 Subject: [PATCH 6/7] refactor: remove obsolete sqlite3 native-binding self-heal @cursor/sdk@1.0.19 (#28) drops the sqlite3 native addon in favor of Node's built-in node:sqlite, so the self-heal that rebuilt sqlite3's binding under Bun is no longer needed. - Remove src/native-binding.ts and its tests - Drop ensureSqliteBinding() from cursor-runtime loadCursorSdk and the sidecar agent backend (direct SDK import / client delegation) - Remove the now-obsolete sqlite troubleshooting note from README Verified: clean npm ci has no sqlite3, @cursor/sdk@1.0.19 imports cleanly, and the opencode integration smoke test lists Cursor models. --- README.md | 4 - src/cursor-runtime.ts | 24 ++-- src/native-binding.ts | 172 ----------------------------- src/provider/agent-backend.ts | 13 +-- test/native-binding-wiring.test.ts | 42 ------- test/native-binding.test.ts | 120 -------------------- 6 files changed, 11 insertions(+), 364 deletions(-) delete mode 100644 src/native-binding.ts delete mode 100644 test/native-binding-wiring.test.ts delete mode 100644 test/native-binding.test.ts diff --git a/README.md b/README.md index f02e3d3..228ead0 100644 --- a/README.md +++ b/README.md @@ -267,10 +267,6 @@ Override with `OPENCODE_CURSOR_SIDECAR=1` (always sidecar) or `OPENCODE_CURSOR_S on your `PATH`. Install Node.js 22+, or force the sidecar with `OPENCODE_CURSOR_SIDECAR=1`. - **"Running under Bun without a usable Node sidecar" warning.** Install Node.js 22+, or set `OPENCODE_CURSOR_SIDECAR=0` to accept in-process behavior and silence the warning. -- **"Could not locate the bindings file" / `node_sqlite3.node` not found.** The `@cursor/sdk` - native sqlite3 addon was skipped during Bun install. The plugin self-heals on first load (needs - Node on `PATH`). If that fails, `cd` into the printed sqlite3 directory and run - `npx prebuild-install -r napi`. - **Plugin enabled but no `cursor` provider/models appear.** Stale opencode plugin cache. Pin an exact version (`@stablekernel/opencode-cursor@`) or delete `~/.cache/opencode/packages/` and restart. diff --git a/src/cursor-runtime.ts b/src/cursor-runtime.ts index 66c31a2..37398b0 100644 --- a/src/cursor-runtime.ts +++ b/src/cursor-runtime.ts @@ -6,27 +6,21 @@ * dependency is missing) degrades gracefully into a clear error instead of * crashing opencode at startup. */ -import { ensureSqliteBinding } from "./native-binding.js"; - export type CursorSdkModule = typeof import("@cursor/sdk"); let cached: Promise | undefined; export async function loadCursorSdk(): Promise { if (!cached) { - // @cursor/sdk eagerly requires sqlite3 (native addon); opencode's Bun - // install skips its build script, so repair the binding first if missing. - cached = ensureSqliteBinding() - .then(() => import("@cursor/sdk")) - .catch((err: unknown) => { - // Allow a later retry if the failure was transient. - cached = undefined; - const detail = err instanceof Error ? err.message : String(err); - throw new Error( - `[opencode-cursor] Failed to load "@cursor/sdk". Make sure it is installed ` + - `(\`npm install @cursor/sdk\`). Original error: ${detail}`, - ); - }); + cached = import("@cursor/sdk").catch((err: unknown) => { + // Allow a later retry if the failure was transient. + cached = undefined; + const detail = err instanceof Error ? err.message : String(err); + throw new Error( + `[opencode-cursor] Failed to load "@cursor/sdk". Make sure it is installed ` + + `(\`npm install @cursor/sdk\`). Original error: ${detail}`, + ); + }); } return cached; } diff --git a/src/native-binding.ts b/src/native-binding.ts deleted file mode 100644 index 5846130..0000000 --- a/src/native-binding.ts +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Self-heal for sqlite3's native binding. - * - * `@cursor/sdk` depends on `sqlite3` (a native addon). opencode installs - * plugin packages with Bun, which does not run sqlite3's `install` lifecycle - * script (`prebuild-install -r napi || node-gyp rebuild`), so the installed - * tree has **no** `node_sqlite3.node` binary and the SDK crashes at import - * with "Could not locate the bindings file". - * - * Before loading the SDK (in-process or via the Node sidecar) we check for a - * binding and, when it is missing, run sqlite3's own `prebuild-install -r napi` - * to fetch the prebuilt NAPI binary (ABI-portable across Node versions, also - * loadable by Bun). Failures degrade to a clear warning; the SDK import then - * surfaces its own error. - */ -import { execSync, spawn } from "node:child_process"; -import { existsSync, readdirSync, statSync } from "node:fs"; -import { createRequire } from "node:module"; -import { dirname, join } from "node:path"; - -export type EnsureResult = "present" | "repaired" | "failed" | "not-found"; - -export interface EnsureOptions { - /** Override the sqlite3 package directory (tests). */ - sqliteDir?: string; - /** Override the repair runner (tests). Returns true when the command succeeded. */ - run?: (sqliteDir: string) => Promise; - /** Override the warning sink (tests). */ - log?: (message: string) => void; -} - -/** Directories (relative to the sqlite3 package root) that may hold the binding. */ -const BINDING_ROOTS = ["build", "lib/binding", "compiled"]; - -function hasNodeFile(dir: string, depth: number): boolean { - if (depth < 0) return false; - let entries: string[]; - try { - entries = readdirSync(dir); - } catch { - return false; - } - for (const entry of entries) { - const path = join(dir, entry); - if (entry.endsWith(".node")) { - try { - if (statSync(path).isFile()) return true; - } catch { - // ignore unreadable entries - } - continue; - } - try { - if (statSync(path).isDirectory() && hasNodeFile(path, depth - 1)) return true; - } catch { - // ignore unreadable entries - } - } - return false; -} - -/** True when the sqlite3 package dir contains a compiled `.node` binding. */ -export function hasSqliteBinding(sqliteDir: string): boolean { - return BINDING_ROOTS.some((root) => hasNodeFile(join(sqliteDir, root), 3)); -} - -/** - * Locate the sqlite3 package directory that `@cursor/sdk` will load, walking - * the same resolution chain (our module -> @cursor/sdk -> sqlite3). - */ -export function resolveSqliteDir(): string | undefined { - const req = createRequire(import.meta.url); - try { - const sdkPkg = req.resolve("@cursor/sdk/package.json"); - return dirname(createRequire(sdkPkg).resolve("sqlite3/package.json")); - } catch { - // fall through: try resolving sqlite3 directly (hoisted installs) - } - try { - return dirname(req.resolve("sqlite3/package.json")); - } catch { - return undefined; - } -} - -function detectNodeExecutable(): string { - const isBun = typeof (globalThis as { Bun?: unknown }).Bun !== "undefined"; - if (!isBun) return process.execPath; - // Under Bun prefer a real Node (matches the sidecar runtime); prebuild-install - // itself is plain JS, so Bun works as a last resort. - try { - const out = execSync(process.platform === "win32" ? "where node" : "command -v node", { - encoding: "utf8", - stdio: ["ignore", "pipe", "ignore"], - }).trim(); - return out.split("\n")[0] || process.execPath; - } catch { - return process.execPath; - } -} - -/** Default repair: run sqlite3's own `prebuild-install -r napi` in its package dir. */ -async function runPrebuildInstall(sqliteDir: string): Promise { - let bin: string; - try { - const req = createRequire(join(sqliteDir, "package.json")); - const pkgPath = req.resolve("prebuild-install/package.json"); - const pkg = (await import(pkgPath, { with: { type: "json" } })) as { - default: { bin?: string | Record }; - }; - const binField = pkg.default.bin; - const rel = typeof binField === "string" ? binField : binField?.["prebuild-install"]; - if (!rel) return false; - bin = join(dirname(pkgPath), rel); - } catch { - return false; - } - if (!existsSync(bin)) return false; - - return new Promise((resolve) => { - const child = spawn(detectNodeExecutable(), [bin, "-r", "napi"], { - cwd: sqliteDir, - stdio: ["ignore", "ignore", "pipe"], - }); - let stderr = ""; - child.stderr?.on("data", (chunk: Buffer) => { - stderr += chunk.toString(); - }); - child.on("error", () => resolve(false)); - child.on("exit", (code) => { - if (code !== 0 && stderr && process.env["OPENCODE_CURSOR_DEBUG"]) { - console.error(`[opencode-cursor] prebuild-install stderr: ${stderr.trim()}`); - } - resolve(code === 0); - }); - }); -} - -let cached: Promise | undefined; - -/** - * Ensure the sqlite3 native binding exists, repairing it once per process if - * needed. Never throws; "failed"/"not-found" outcomes warn and let the SDK - * import surface its own error. - */ -export function ensureSqliteBinding(options: EnsureOptions = {}): Promise { - cached ??= (async () => { - const log = options.log ?? ((message: string) => console.error(message)); - const sqliteDir = options.sqliteDir ?? resolveSqliteDir(); - if (!sqliteDir || !existsSync(join(sqliteDir, "package.json"))) { - return "not-found"; - } - if (hasSqliteBinding(sqliteDir)) return "present"; - - const run = options.run ?? runPrebuildInstall; - const ok = await run(sqliteDir).catch(() => false); - if (ok && hasSqliteBinding(sqliteDir)) return "repaired"; - - log( - `[opencode-cursor] sqlite3 native binding is missing in ${sqliteDir} and automatic ` + - `repair failed. @cursor/sdk will not load. Fix manually with: ` + - `cd ${sqliteDir} && npx prebuild-install -r napi (or: npm rebuild sqlite3)`, - ); - return "failed"; - })(); - return cached; -} - -/** Test hook. */ -export function resetNativeBinding(): void { - cached = undefined; -} diff --git a/src/provider/agent-backend.ts b/src/provider/agent-backend.ts index 6529e46..7d3e1d8 100644 --- a/src/provider/agent-backend.ts +++ b/src/provider/agent-backend.ts @@ -14,7 +14,6 @@ import { execSync } from "node:child_process"; import { existsSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { loadCursorSdk } from "../cursor-runtime.js"; -import { ensureSqliteBinding } from "../native-binding.js"; import { SidecarClient, type AgentLike } from "./sidecar-client.js"; export type { AgentLike, AgentRunLike, AgentSendOptions } from "./sidecar-client.js"; @@ -94,18 +93,10 @@ export function resolveSidecarScript(): string | undefined { function sidecarBackend(nodePath: string, scriptPath: string): AgentBackend { const client = new SidecarClient({ scriptPath, nodePath }); - // The sidecar imports @cursor/sdk (which eagerly requires sqlite3's native - // binding) in the child process; repair the binding before first use. return { kind: "sidecar", - createAgent: async (options) => { - await ensureSqliteBinding(); - return client.createAgent(options); - }, - resumeAgent: async (agentId, options) => { - await ensureSqliteBinding(); - return client.resumeAgent(agentId, options); - }, + createAgent: (options) => client.createAgent(options), + resumeAgent: (agentId, options) => client.resumeAgent(agentId, options), }; } diff --git a/test/native-binding-wiring.test.ts b/test/native-binding-wiring.test.ts deleted file mode 100644 index 86cbfd6..0000000 --- a/test/native-binding-wiring.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { afterEach, describe, expect, it, vi } from "vitest"; - -const ensureSqliteBinding = vi.fn(async () => "present" as const); -vi.mock("../src/native-binding.js", () => ({ ensureSqliteBinding })); - -const createAgent = vi.fn(async () => ({ agentId: "sidecar-agent" })); -const resumeAgent = vi.fn(async () => ({ agentId: "sidecar-agent" })); -vi.mock("../src/provider/sidecar-client.js", () => ({ - SidecarClient: class { - createAgent = createAgent; - resumeAgent = resumeAgent; - }, -})); - -afterEach(() => { - vi.unstubAllEnvs(); - vi.clearAllMocks(); -}); - -describe("loadCursorSdk", () => { - it("ensures the sqlite binding before importing the SDK", async () => { - const { loadCursorSdk } = await import("../src/cursor-runtime.js"); - await loadCursorSdk(); - expect(ensureSqliteBinding).toHaveBeenCalled(); - }); -}); - -describe("sidecar backend", () => { - it("ensures the sqlite binding before creating an agent", async () => { - vi.stubEnv("OPENCODE_CURSOR_SIDECAR", "1"); - const { loadAgentBackend, resetAgentBackend } = await import( - "../src/provider/agent-backend.js" - ); - resetAgentBackend(); - const backend = loadAgentBackend(); - expect(backend.kind).toBe("sidecar"); - await backend.createAgent({}); - expect(ensureSqliteBinding).toHaveBeenCalled(); - expect(createAgent).toHaveBeenCalled(); - resetAgentBackend(); - }); -}); diff --git a/test/native-binding.test.ts b/test/native-binding.test.ts deleted file mode 100644 index e1ef665..0000000 --- a/test/native-binding.test.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -import { - ensureSqliteBinding, - hasSqliteBinding, - resetNativeBinding, - resolveSqliteDir, -} from "../src/native-binding.js"; - -let dir: string; - -beforeEach(() => { - resetNativeBinding(); - dir = mkdtempSync(join(tmpdir(), "oc-cursor-sqlite-")); -}); - -afterEach(() => { - rmSync(dir, { recursive: true, force: true }); -}); - -/** Lay down a minimal fake sqlite3 package dir. */ -function fakeSqliteDir(opts: { binding?: string } = {}): string { - writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "sqlite3", version: "5.1.7" })); - if (opts.binding) { - const bindingPath = join(dir, opts.binding); - mkdirSync(join(bindingPath, ".."), { recursive: true }); - writeFileSync(bindingPath, "fake-native"); - } - return dir; -} - -describe("hasSqliteBinding", () => { - it("finds a binding in build/Release", () => { - fakeSqliteDir({ binding: "build/Release/node_sqlite3.node" }); - expect(hasSqliteBinding(dir)).toBe(true); - }); - - it("finds a binding in lib/binding//", () => { - fakeSqliteDir({ binding: "lib/binding/napi-v6-darwin-arm64/node_sqlite3.node" }); - expect(hasSqliteBinding(dir)).toBe(true); - }); - - it("returns false when no .node binary exists", () => { - fakeSqliteDir(); - expect(hasSqliteBinding(dir)).toBe(false); - }); - - it("returns false for a missing directory", () => { - expect(hasSqliteBinding(join(dir, "nope"))).toBe(false); - }); -}); - -describe("resolveSqliteDir", () => { - it("resolves the real sqlite3 package dir from this repo", () => { - // Integration: @cursor/sdk and sqlite3 are real deps of this repo. - const resolved = resolveSqliteDir(); - expect(resolved).toBeDefined(); - expect(resolved).toMatch(/node_modules[/\\]sqlite3$/); - expect(hasSqliteBinding(resolved!)).toBe(true); - }); -}); - -describe("ensureSqliteBinding", () => { - it("reports present without running a repair when the binding exists", async () => { - fakeSqliteDir({ binding: "build/Release/node_sqlite3.node" }); - const run = vi.fn(); - const result = await ensureSqliteBinding({ sqliteDir: dir, run }); - expect(result).toBe("present"); - expect(run).not.toHaveBeenCalled(); - }); - - it("runs the repair and reports repaired when it produces a binding", async () => { - fakeSqliteDir(); - const run = vi.fn(async (cwd: string) => { - mkdirSync(join(cwd, "build", "Release"), { recursive: true }); - writeFileSync(join(cwd, "build", "Release", "node_sqlite3.node"), "built"); - return true; - }); - const result = await ensureSqliteBinding({ sqliteDir: dir, run }); - expect(result).toBe("repaired"); - expect(run).toHaveBeenCalledWith(dir); - }); - - it("reports failed (without throwing) when the repair does not produce a binding", async () => { - fakeSqliteDir(); - const log = vi.fn(); - const run = vi.fn(async () => false); - const result = await ensureSqliteBinding({ sqliteDir: dir, run, log }); - expect(result).toBe("failed"); - expect(log).toHaveBeenCalled(); - }); - - it("reports not-found when sqlite3 cannot be located", async () => { - const run = vi.fn(); - const result = await ensureSqliteBinding({ sqliteDir: join(dir, "missing"), run }); - expect(result).toBe("not-found"); - expect(run).not.toHaveBeenCalled(); - }); - - it("caches the outcome (repair runs once across concurrent calls)", async () => { - fakeSqliteDir(); - let calls = 0; - const run = async (cwd: string) => { - calls++; - mkdirSync(join(cwd, "build", "Release"), { recursive: true }); - writeFileSync(join(cwd, "build", "Release", "node_sqlite3.node"), "built"); - return true; - }; - const [a, b] = await Promise.all([ - ensureSqliteBinding({ sqliteDir: dir, run }), - ensureSqliteBinding({ sqliteDir: dir, run }), - ]); - expect(a).toBe("repaired"); - expect(b).toBe("repaired"); - expect(calls).toBe(1); - }); -}); From 09ec8f085176297c0beb2f7b584bb5e42675515e Mon Sep 17 00:00:00 2001 From: Justin Carper Date: Wed, 17 Jun 2026 08:04:03 -0400 Subject: [PATCH 7/7] chore(release): 0.4.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 934b228..011313f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@stablekernel/opencode-cursor", - "version": "0.4.1-next.0", + "version": "0.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@stablekernel/opencode-cursor", - "version": "0.4.1-next.0", + "version": "0.4.1", "license": "MIT", "dependencies": { "@cursor/sdk": "^1.0.18", diff --git a/package.json b/package.json index f00defe..57ec740 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@stablekernel/opencode-cursor", - "version": "0.4.1-next.0", + "version": "0.4.1", "description": "opencode provider plugin backed by the official Cursor SDK (@cursor/sdk) — adds a Cursor provider and lists its models", "type": "module", "license": "MIT",