From 6d935d2f98a768587b329b411e742f1b59cc4055 Mon Sep 17 00:00:00 2001 From: Jasdeep Date: Tue, 10 Nov 2026 19:05:45 +0000 Subject: [PATCH 1/2] chore(deps): DBDiff 3.0.0-rc.34, pg-conformance 0.0.19 and @oclif/core 5 @oclif/core 5.1.12 takes minimatch 11, so the install no longer carries GHSA-g3hv-75wg-m249 and its audit exception goes: npm audit of what a user installs is clean. oclif 5 requires Node 22, so SupaForge now does too (Node 20 reached end of life in April 2026): engines, the .mcpb runtime, the build target, the docs and the CI matrix. oclif 5 waits for a stdout drain that never comes when a reader closes the pipe early (supaforge --help | head), and Node then exits 13 with an unsettled top-level await warning. bin/run.js now ends such a run as a success, and a test closes stdout before the CLI writes to prove it. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 2 +- .github/workflows/manual-release.yml | 2 +- .github/workflows/release-dry-run.yml | 2 +- .github/workflows/release.yml | 6 +- packages/cli/README.md | 2 +- packages/cli/bin/run.js | 8 + packages/cli/mcpb/manifest.template.json | 2 +- packages/cli/package-lock.json | 227 +++++++++++---------- packages/cli/package.json | 8 +- packages/cli/scripts/audit-exceptions.json | 4 +- packages/cli/test/bin-run.test.ts | 20 ++ packages/cli/tsup.config.ts | 2 +- packages/mcp/package-lock.json | 12 +- packages/mcp/package.json | 2 +- packages/vscode/README.md | 2 +- packages/vscode/extension.js | 2 +- 16 files changed, 172 insertions(+), 131 deletions(-) create mode 100644 packages/cli/test/bin-run.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e55210a..d31ecd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [20.x, 22.x, 24.x, 25.x] + node-version: [22.x, 24.x, 25.x] steps: - name: Checkout code diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml index 6b1503b..4422c6a 100644 --- a/.github/workflows/manual-release.yml +++ b/.github/workflows/manual-release.yml @@ -78,7 +78,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' - name: Set git identity run: | diff --git a/.github/workflows/release-dry-run.yml b/.github/workflows/release-dry-run.yml index 2f9d2f8..6629760 100644 --- a/.github/workflows/release-dry-run.yml +++ b/.github/workflows/release-dry-run.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' registry-url: 'https://registry.npmjs.org' cache: npm cache-dependency-path: packages/cli/package-lock.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25b3477..04ecf2a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' cache: npm cache-dependency-path: packages/cli/package-lock.json @@ -66,7 +66,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' registry-url: 'https://registry.npmjs.org' - name: npm whoami env: @@ -131,7 +131,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' registry-url: 'https://registry.npmjs.org' cache: npm cache-dependency-path: packages/cli/package-lock.json diff --git a/packages/cli/README.md b/packages/cli/README.md index 7148a62..8bd06e3 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -48,7 +48,7 @@ Everything that writes previews first. Add `--apply` to make it happen. | VS Code and its forks | The SupaForge extension: commands, and the MCP server for the editor's agent. Each [release](https://github.com/akalsoftware/supaforge/releases/latest) carries it as a `.vsix` | | Cursor, VS Code, Claude | One-click installs of the MCP server — see [MCP](#mcp-ai-agents) | -It needs Node.js 20 or newer. DBDiff, its diff engine, comes with it as a +It needs Node.js 22 or newer. DBDiff, its diff engine, comes with it as a native binary for your platform, so there is nothing else to install. The Docker image needs nothing at all, and carries the PostgreSQL client tools `--prove` uses; pass connection strings with `-e`, and mount the project at diff --git a/packages/cli/bin/run.js b/packages/cli/bin/run.js index d8c1b65..80ac452 100755 --- a/packages/cli/bin/run.js +++ b/packages/cli/bin/run.js @@ -8,6 +8,14 @@ import {execute, settings} from '@oclif/core' // not find it. A checkout keeps the lookup, which its tests rely on. if (!existsSync(new URL('../src', import.meta.url))) settings.enableAutoTranspile = false +// A reader that stops early (supaforge --help | head) closes stdout. oclif +// then waits for a drain that never comes and Node exits 13 with a warning; +// there is nothing left to write to, so finish as a completed run would. +process.stdout.on('error', (err) => { + if (err?.code === 'EPIPE') process.exit(process.exitCode ?? 0) + throw err +}) + await execute({dir: import.meta.url}).catch((err) => { // oclif handles CLIError internally — this catches truly unexpected errors. if (err && typeof err === 'object' && 'oclif' in err) return diff --git a/packages/cli/mcpb/manifest.template.json b/packages/cli/mcpb/manifest.template.json index cb95ada..50866c2 100644 --- a/packages/cli/mcpb/manifest.template.json +++ b/packages/cli/mcpb/manifest.template.json @@ -37,6 +37,6 @@ ], "compatibility": { "platforms": ["__OS__"], - "runtimes": { "node": ">=20.0.0" } + "runtimes": { "node": ">=22.0.0" } } } diff --git a/packages/cli/package-lock.json b/packages/cli/package-lock.json index 5e90a13..9fddbe0 100644 --- a/packages/cli/package-lock.json +++ b/packages/cli/package-lock.json @@ -9,10 +9,10 @@ "version": "0.0.41", "license": "MIT", "dependencies": { - "@akal/pg-conformance": "~0.0.18", - "@dbdiff/cli": "3.0.0-rc.33", + "@akal/pg-conformance": "~0.0.19", + "@dbdiff/cli": "3.0.0-rc.34", "@modelcontextprotocol/sdk": "^1.32.1", - "@oclif/core": "^4", + "@oclif/core": "^5.1.12", "@supabase/supabase-js": "^2.103.0", "libpg-query": "~18.1.5", "pg": "^8", @@ -30,22 +30,22 @@ "vitest": "^4.1.11" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@akal/pg-conformance": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/@akal/pg-conformance/-/pg-conformance-0.0.18.tgz", - "integrity": "sha512-q9yhMRZrt0fUF5HCS1if1AQqwTm5uyBQUxUvmA3TnJvB9+xG1EAaJyS3y7MccScQlJovcufoksIBPKIDl3FvaA==", + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/@akal/pg-conformance/-/pg-conformance-0.0.19.tgz", + "integrity": "sha512-6f3fRTwAkRWnCKfh9oixLaB54KVnlpRT95yIHb/iV18UbdIHrO4/jrKPM06jBchMyPG7cklmUvnDOXrgaUMPeg==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@dbdiff/cli": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli/-/cli-3.0.0-rc.33.tgz", - "integrity": "sha512-6UtWrTQUrL3JIRavhYbql7N1NHiPlI1xqb7GrYsS+u1F8FeJXMI41H0MN2ldJ84aFjyWR2sAAcKf84d46UenqA==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli/-/cli-3.0.0-rc.34.tgz", + "integrity": "sha512-Mb4b8AIC3TRFIuIxdNZALAbmvC639oPzBArmdTJs8OJF2kYfM7tt0dTqklb6pXUP5rHi6uII1XUSNF7rcl4jDw==", "license": "MIT", "bin": { "dbdiff": "bin/dbdiff.js" @@ -54,20 +54,20 @@ "node": ">=18.0.0" }, "optionalDependencies": { - "@dbdiff/cli-darwin-arm64": "3.0.0-rc.33", - "@dbdiff/cli-darwin-x64": "3.0.0-rc.33", - "@dbdiff/cli-linux-arm64": "3.0.0-rc.33", - "@dbdiff/cli-linux-arm64-musl": "3.0.0-rc.33", - "@dbdiff/cli-linux-x64": "3.0.0-rc.33", - "@dbdiff/cli-linux-x64-musl": "3.0.0-rc.33", - "@dbdiff/cli-win32-arm64": "3.0.0-rc.33", - "@dbdiff/cli-win32-x64": "3.0.0-rc.33" + "@dbdiff/cli-darwin-arm64": "3.0.0-rc.34", + "@dbdiff/cli-darwin-x64": "3.0.0-rc.34", + "@dbdiff/cli-linux-arm64": "3.0.0-rc.34", + "@dbdiff/cli-linux-arm64-musl": "3.0.0-rc.34", + "@dbdiff/cli-linux-x64": "3.0.0-rc.34", + "@dbdiff/cli-linux-x64-musl": "3.0.0-rc.34", + "@dbdiff/cli-win32-arm64": "3.0.0-rc.34", + "@dbdiff/cli-win32-x64": "3.0.0-rc.34" } }, "node_modules/@dbdiff/cli-darwin-arm64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-darwin-arm64/-/cli-darwin-arm64-3.0.0-rc.33.tgz", - "integrity": "sha512-axNX2BXfsUOOFdGYNfFpHYOq7Urtj2auiMXAp2wsKha4tTfO+0vuqmNDeM3J0/BmpNA3khuNDcYZudPFYkGyxA==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-darwin-arm64/-/cli-darwin-arm64-3.0.0-rc.34.tgz", + "integrity": "sha512-ww8ZvFh+1C/P+mhwxxmljTn43dzxfPIZVbWe2TaZc7xVcZbO6PfqY8d/WpLgFZnp9f6FjXrCOqcUEfxcaAGU1Q==", "cpu": [ "arm64" ], @@ -78,9 +78,9 @@ ] }, "node_modules/@dbdiff/cli-darwin-x64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-darwin-x64/-/cli-darwin-x64-3.0.0-rc.33.tgz", - "integrity": "sha512-dibUIyl6dfbf+NEphNbO6u8kzLhi3msiLyL9FICZTZgLc22vtqHGgfVtILSEl04gpWshTsFK5NZ27Ng4PhKMOQ==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-darwin-x64/-/cli-darwin-x64-3.0.0-rc.34.tgz", + "integrity": "sha512-LqAaeaWzGU5St1KFDfwSQT2NGYWJ2eqWpcZYientMScwYOaBT0QiV9d0ZEB9VXO6QpCJUCRkx8zdjpjZAMLdYQ==", "cpu": [ "x64" ], @@ -91,9 +91,9 @@ ] }, "node_modules/@dbdiff/cli-linux-arm64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-arm64/-/cli-linux-arm64-3.0.0-rc.33.tgz", - "integrity": "sha512-OjHjZcTXPCvdqaGgLcykrWpYM9fyd5OrW3hB0Hk8BuUUh+gFhjVTGeLXeqLs+pq7zp7gbxnuSpoAazA2g0bFEA==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-arm64/-/cli-linux-arm64-3.0.0-rc.34.tgz", + "integrity": "sha512-C1k5y1wbzbYtNlsqQ5Av/YOnPjVw/iy1XlYyoAHfQb/Jx8rhIDnT7HQmY+hiThVnXFNsUI9pRy/h9O0WRC98kQ==", "cpu": [ "arm64" ], @@ -107,9 +107,9 @@ ] }, "node_modules/@dbdiff/cli-linux-arm64-musl": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-arm64-musl/-/cli-linux-arm64-musl-3.0.0-rc.33.tgz", - "integrity": "sha512-K8AW8Wl85Mu8VXT50xgWoUOqQjPpuYTiFDdSW50FJWlxV3zC1Gjhz1WAFmLqhLqJwe5EtQaf2cXTizjlSmDg+Q==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-arm64-musl/-/cli-linux-arm64-musl-3.0.0-rc.34.tgz", + "integrity": "sha512-ISqJIKkmYMTqXHtGf1Iyv3LVFMW+XZxODv94fqS/3SowsLTQUN1bi66rjodWx94yDgXdCtFJMIJHuNJrJ61Xdw==", "cpu": [ "arm64" ], @@ -123,9 +123,9 @@ ] }, "node_modules/@dbdiff/cli-linux-x64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-x64/-/cli-linux-x64-3.0.0-rc.33.tgz", - "integrity": "sha512-+Bho4umz27gmA4R6ANVJjkNnNh/IANhalJK3mRebia2fNGq0F0A9NoGONU4QV8v53jrN3wYaL6Gm2IukTHwdLg==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-x64/-/cli-linux-x64-3.0.0-rc.34.tgz", + "integrity": "sha512-EIsk+Tt7XKZ7usB5fTIeOZmfTpQJbC1mmSzn+ClfpDiz3HWSMnrq/2Wbk7tz3YSldwPUhDopj6DJGne39+DhFQ==", "cpu": [ "x64" ], @@ -139,9 +139,9 @@ ] }, "node_modules/@dbdiff/cli-linux-x64-musl": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-x64-musl/-/cli-linux-x64-musl-3.0.0-rc.33.tgz", - "integrity": "sha512-1HOP1QPkafu4xv0HAvY2gDmkJB4xop+12FeF4FRm2K7uC85sYmz8HPZ8Nk0a/PdvSI7yy4xtIJHW14Lm/n/PfA==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-linux-x64-musl/-/cli-linux-x64-musl-3.0.0-rc.34.tgz", + "integrity": "sha512-OTztwU7ZSe+J+lQTtaWCjC1d6fydKcJ+xGpghEsK8xtuEmbp3Jz1BydCIhUAjdPCYvrcXQXMCwk3pCvQwxwQWQ==", "cpu": [ "x64" ], @@ -155,9 +155,9 @@ ] }, "node_modules/@dbdiff/cli-win32-arm64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-win32-arm64/-/cli-win32-arm64-3.0.0-rc.33.tgz", - "integrity": "sha512-YhSD3xXgcCSApHrUjtDaTimZohsF/EZxero04xpDY7Qb9tmVrJhZb/up3mNZbsdNw3C64JmMW5iWh2j079XX/A==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-win32-arm64/-/cli-win32-arm64-3.0.0-rc.34.tgz", + "integrity": "sha512-jFQQujnB2f6HdmYbe3NJWgcs1x43U9nXCASgsj0MAb4j5FNc1QklGMcmGlguf8I5yLKZ8ltakOwTLeBa7awDkA==", "cpu": [ "arm64" ], @@ -168,9 +168,9 @@ ] }, "node_modules/@dbdiff/cli-win32-x64": { - "version": "3.0.0-rc.33", - "resolved": "https://registry.npmjs.org/@dbdiff/cli-win32-x64/-/cli-win32-x64-3.0.0-rc.33.tgz", - "integrity": "sha512-zTnQjuW0RqhF7mVe/J6vyIE7j5WrExEgtCrdq/9Ym8Gb0WOZwIg7mpo6/PwMbek89UseEQ03GBmO7DO6izk6Hw==", + "version": "3.0.0-rc.34", + "resolved": "https://registry.npmjs.org/@dbdiff/cli-win32-x64/-/cli-win32-x64-3.0.0-rc.34.tgz", + "integrity": "sha512-DukdCJfW3AkI7redPgHn3zTz1qDURmMtD/18793uIRBM14OIo6T+Xl3E0/H35+ehRd9QVe/LPpsoHKQT1MEeUg==", "cpu": [ "x64" ], @@ -720,9 +720,9 @@ } }, "node_modules/@oclif/core": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.10.1.tgz", - "integrity": "sha512-SeT6K9arGKh6IJ585gC+ueCS9xZfbsO+k6UEjVO6H3vElrOEWOWLI0KYnSl0rmg6MOXqM5fSiqIQZtDeJuIXlw==", + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-5.1.12.tgz", + "integrity": "sha512-t8W/ljOb9DIsFNXbfLU4UpZ8+C/X0QuvJOuQXQVCthiw5zSdwKnKoq7HmyBUJwwo28302eiN0rRj8vN9k1U1Mw==", "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.2", @@ -730,22 +730,22 @@ "clean-stack": "^3.0.1", "cli-spinners": "^2.9.2", "debug": "^4.4.3", - "ejs": "^3.1.10", + "ejs": "^6", "get-package-type": "^0.1.0", "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", "lilconfig": "^3.1.3", - "minimatch": "^10.2.4", - "semver": "^7.7.3", + "minimatch": "^11.0.1", + "semver": "^7.8.1", "string-width": "^4.2.3", "supports-color": "^8", - "tinyglobby": "^0.2.14", + "tinyglobby": "^0.2.17", "widest-line": "^3.1.0", "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^7.0.0", + "wsl-utils": "^0.4.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=22.0.0" } }, "node_modules/@oxc-project/types": { @@ -1779,12 +1779,6 @@ "node": ">=12" } }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" - }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -2140,18 +2134,15 @@ "license": "MIT" }, "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-6.0.1.tgz", + "integrity": "sha512-UaaM14yby8U3k02ihS1Bmj5Kz2d7CCQM1scxpgs4Mhkq8F1wR2gl3+Ts4h5Ne4Mnt7M9m4Dw7jsuMr3+xO4vZA==", "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, "bin": { "ejs": "bin/cli.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12.18" } }, "node_modules/emoji-regex": { @@ -2416,15 +2407,6 @@ } } }, - "node_modules/filelist": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", - "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, "node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", @@ -2692,15 +2674,15 @@ } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2715,6 +2697,24 @@ "node": ">=8" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", @@ -2722,15 +2722,18 @@ "license": "MIT" }, "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isexe": { @@ -2739,23 +2742,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jose": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", @@ -3164,9 +3150,9 @@ } }, "node_modules/minimatch": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-11.0.5.tgz", - "integrity": "sha512-snPlVppFcYWfLLFQGhDxUyBcHNtMlWmn3jtj7pEaO+DP8pqL0IvAzXhMYmn1z9ASNtgmwLBdFxSf4tMUB0OTKA==", + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-11.0.6.tgz", + "integrity": "sha512-6NZbDPQIRnsJFjJ9wbd5659OKaTHCqpPHdldE3WwArjxr5wLxHIwnx4eTGcPebpVBZZQbITvQQIx8K0VGXoT3Q==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/nonrecursive-glob-match": "^1.1.0", @@ -3422,6 +3408,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -3578,6 +3565,18 @@ "node": ">=0.10.0" } }, + "node_modules/powershell-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz", + "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/proxy-addr": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz", @@ -3780,9 +3779,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz", + "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4586,6 +4585,22 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.4.0.tgz", + "integrity": "sha512-9YmF+2sFEd+T7TkwlmE337F0IVzfDvDknhtpBQxxXzEOfgPphGlFYpyx0cTuCIFj8/p+sqwBYAeGxOMNSzPPDA==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0", + "powershell-utils": "^0.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/packages/cli/package.json b/packages/cli/package.json index 27d83d7..0b736c5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -55,10 +55,10 @@ "topicSeparator": " " }, "dependencies": { - "@akal/pg-conformance": "~0.0.18", - "@dbdiff/cli": "3.0.0-rc.33", + "@akal/pg-conformance": "~0.0.19", + "@dbdiff/cli": "3.0.0-rc.34", "@modelcontextprotocol/sdk": "^1.32.1", - "@oclif/core": "^4", + "@oclif/core": "^5.1.12", "@supabase/supabase-js": "^2.103.0", "libpg-query": "~18.1.5", "pg": "^8", @@ -73,7 +73,7 @@ "vitest": "^4.1.11" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "overrides": { "minimatch": "^11.0.5", diff --git a/packages/cli/scripts/audit-exceptions.json b/packages/cli/scripts/audit-exceptions.json index cffa08d..0967ef4 100644 --- a/packages/cli/scripts/audit-exceptions.json +++ b/packages/cli/scripts/audit-exceptions.json @@ -1,3 +1 @@ -{ - "GHSA-g3hv-75wg-m249": "minimatch < 11.0.1, required as ^10.2.5 by @oclif/core (latest 5.1.11 included). Only oclif matches its own plugin names with it, never user input. Remove once @oclif/core accepts minimatch 11 (oclif/core#1664)." -} +{} diff --git a/packages/cli/test/bin-run.test.ts b/packages/cli/test/bin-run.test.ts new file mode 100644 index 0000000..25bbf4d --- /dev/null +++ b/packages/cli/test/bin-run.test.ts @@ -0,0 +1,20 @@ +import {describe, expect, it} from 'vitest' +import {spawn} from 'node:child_process' +import {fileURLToPath} from 'node:url' + +const bin = fileURLToPath(new URL('../bin/run.js', import.meta.url)) + +// A reader that stops early (supaforge --help | head) closes stdout before the +// CLI is done writing. That must end the run as a success, not as Node's exit +// 13 for a top-level await that never settled. +describe('bin/run.js', () => { + it('exits 0 when stdout is closed before it writes', async () => { + const child = spawn(process.execPath, [bin, '--version'], {stdio: ['ignore', 'pipe', 'pipe']}) + child.stdout.destroy() + let stderr = '' + child.stderr.on('data', (chunk) => (stderr += chunk)) + const code = await new Promise((resolve) => child.on('close', resolve)) + expect(stderr).not.toMatch(/unsettled top-level await/) + expect(code).toBe(0) + }) +}) diff --git a/packages/cli/tsup.config.ts b/packages/cli/tsup.config.ts index 1898192..74fb858 100644 --- a/packages/cli/tsup.config.ts +++ b/packages/cli/tsup.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ dts: true, clean: true, sourcemap: true, - target: 'node20', + target: 'node22', outDir: 'dist', splitting: true, }) diff --git a/packages/mcp/package-lock.json b/packages/mcp/package-lock.json index 7884bea..eeab6cf 100644 --- a/packages/mcp/package-lock.json +++ b/packages/mcp/package-lock.json @@ -23,18 +23,18 @@ "vitest": "^4.1.11" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "../cli": { "name": "@akal/supaforge", - "version": "0.0.40", + "version": "0.0.41", "license": "MIT", "dependencies": { - "@akal/pg-conformance": "~0.0.18", - "@dbdiff/cli": "3.0.0-rc.33", + "@akal/pg-conformance": "~0.0.19", + "@dbdiff/cli": "3.0.0-rc.34", "@modelcontextprotocol/sdk": "^1.32.1", - "@oclif/core": "^4", + "@oclif/core": "^5.1.12", "@supabase/supabase-js": "^2.103.0", "libpg-query": "~18.1.5", "pg": "^8", @@ -52,7 +52,7 @@ "vitest": "^4.1.11" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@akal/supaforge": { diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 3d82f58..72d598e 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -43,6 +43,6 @@ "vitest": "^4.1.11" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } } diff --git a/packages/vscode/README.md b/packages/vscode/README.md index 46579fd..6508cae 100644 --- a/packages/vscode/README.md +++ b/packages/vscode/README.md @@ -35,7 +35,7 @@ Each runs in a terminal, so you see exactly what it does. ## Requirements -Node.js 20 or newer. The extension runs SupaForge with `npx`, at the version +Node.js 22 or newer. The extension runs SupaForge with `npx`, at the version it was released with; set `supaforge.cliVersion` to choose another (e.g. `latest`). diff --git a/packages/vscode/extension.js b/packages/vscode/extension.js index 8300ed5..8a26b91 100644 --- a/packages/vscode/extension.js +++ b/packages/vscode/extension.js @@ -4,7 +4,7 @@ // each workspace folder that has a supaforge.config.json, and commands that // run the CLI in a terminal. Both run `npx @akal/supaforge@`, the // version this extension was released with unless supaforge.cliVersion says -// otherwise, so there is nothing else to install beyond Node.js 20+. +// otherwise, so there is nothing else to install beyond Node.js 22+. 'use strict' const vscode = require('vscode') From 2450f7cfa8bab724a0e436a54c0ff2ecd61c6a1f Mon Sep 17 00:00:00 2001 From: Jasdeep Date: Tue, 10 Nov 2026 19:13:38 +0000 Subject: [PATCH 2/2] test(real-world): GitLab's sequences now sync; only partition index names remain Co-Authored-By: Claude Opus 5.5 --- packages/cli/test/real-world/known-gaps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/test/real-world/known-gaps.json b/packages/cli/test/real-world/known-gaps.json index 9892da2..08cc196 100644 --- a/packages/cli/test/real-world/known-gaps.json +++ b/packages/cli/test/real-world/known-gaps.json @@ -3,7 +3,7 @@ "adventureworks pg17>pg18 drift-prove": "as drift", "adventureworks pg17>sb15 sync": "Supabase installs uuid-ossp in its extensions schema; the source has it in public, so the extension and every default calling uuid_generate_v1() read as changed", "chinook pg17>sb15 sync": "Supabase's own extensions (pg_graphql, supabase_vault, …) and its supabase_realtime publication read as extra on a Supabase target synced from plain PostgreSQL, with no fix — a re-scan can never be clean", - "gitlab pg17>pg17 sync": "DBDiff: partitions' indexes take generated names and lose their storage options; a sequence owned by a column with no default (filled by a trigger) is not created; and a column whose default draws on a sequence it does not own is rewritten to the one it owns", + "gitlab pg17>pg17 sync": "DBDiff: partitions' indexes take generated names and lose their storage options", "pagila pv18>pv18 clone": "clone copies with --no-acl, so the source's GRANT ALL ON SCHEMA public TO PUBLIC is not carried", "pagila pv18>pv18 sync": "DBDiff: on PostgreSQL 18 a partition created with PARTITION OF takes its parent's NOT NULL constraint names, while the source's attached partitions carry their own" }