diff --git a/.changeset/broad-node-runtime-support.md b/.changeset/broad-node-runtime-support.md new file mode 100644 index 0000000000..886a96ecc6 --- /dev/null +++ b/.changeset/broad-node-runtime-support.md @@ -0,0 +1,23 @@ +--- +"@codegraphy-dev/core": major +"@codegraphy-dev/extension": minor +"@codegraphy-dev/extension-plugin-api": major +"@codegraphy-dev/graph-renderer": minor +"@codegraphy-dev/plugin-api": major +"@codegraphy-dev/plugin-godot": major +"@codegraphy-dev/plugin-markdown": major +"@codegraphy-dev/plugin-particles": minor +"@codegraphy-dev/plugin-svelte": minor +"@codegraphy-dev/plugin-typescript": major +"@codegraphy-dev/plugin-unity": minor +"@codegraphy-dev/plugin-vue": minor +"@codegraphy-dev/tldraw": minor +--- + +Node.js 20 is no longer supported. Upgrade to Node.js `^22.14.0 || >=23.6.0` before +updating CodeGraphy Core, interfaces, APIs, or plugins. Newer Node.js releases +remain supported because these packages do not set a maximum version. + +The VS Code extension now requires VS Code 1.101 or newer. Extension users do +not need to install Node.js separately because VS Code supplies the Extension +host runtime. diff --git a/.changeset/clean-tree-sitter-runtime.md b/.changeset/clean-tree-sitter-runtime.md new file mode 100644 index 0000000000..f1c8a43c31 --- /dev/null +++ b/.changeset/clean-tree-sitter-runtime.md @@ -0,0 +1,9 @@ +--- +"@codegraphy-dev/core": patch +"@codegraphy-dev/extension": patch +"@codegraphy-dev/tldraw": patch +--- + +Use Tree-sitter's upstream prebuilt runtime on Node.js `^22.14.0 || >=23.6.0`. +Language analysis is unchanged, and CodeGraphy no longer needs its temporary +native-build patch. diff --git a/.changeset/slim-vsix-runtime.md b/.changeset/slim-vsix-runtime.md new file mode 100644 index 0000000000..0de4e454c2 --- /dev/null +++ b/.changeset/slim-vsix-runtime.md @@ -0,0 +1,7 @@ +--- +"@codegraphy-dev/extension": patch +--- + +Reduce the platform-specific extension install size by approximately 85% +without removing supported languages, built-in plugins, Graph View assets, or +native runtime capabilities. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c1d536a86..67be2d3795 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -68,7 +68,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -124,7 +124,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -161,7 +161,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -202,7 +202,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -377,7 +377,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -467,7 +467,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -515,7 +515,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies @@ -559,7 +559,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: 'pnpm' - name: Install dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b6835a823c..a5354d9cad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: pnpm registry-url: https://registry.npmjs.org @@ -101,7 +101,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22.22.0 + node-version: 'lts/*' cache: pnpm registry-url: https://registry.npmjs.org diff --git a/.node-version b/.node-version deleted file mode 100644 index 85e502778f..0000000000 --- a/.node-version +++ /dev/null @@ -1 +0,0 @@ -22.22.0 diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 85e502778f..0000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -22.22.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74263f86c5..4a29d97088 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,16 +6,15 @@ CodeGraphy accepts focused changes through pull requests against `main`. ### Prerequisites -- Node.js 20 through 22; use the repository-pinned Node 22 runtime +- Node.js `^22.14.0 || >=23.6.0`; use an active LTS release - pnpm 10+ -- VS Code 1.85+ +- VS Code 1.101+ ### Getting started 1. Fork and clone the repository. 2. Install dependencies: ```bash - nvm use pnpm install ``` 3. Build the project: @@ -111,7 +110,7 @@ pnpm --filter @codegraphy-dev/extension exec playwright install chromium # Brow pnpm --filter @codegraphy-dev/extension exec vitest run --config vitest.config.ts tests/path/to/file.test.ts ``` -The repo pins Node in [`.nvmrc`](./.nvmrc) and [`.node-version`](./.node-version). Use that exact runtime before running release or quality-tool commands. +Use an active Node.js LTS release for repository development, release, and quality-tool commands. Published packages require Node.js `^22.14.0 || >=23.6.0` and do not set a maximum version. ## Reporting bugs diff --git a/README.md b/README.md index badd8b30f2..bfef1bfbe8 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,19 @@ CodeGraphy indexes a folder and projects its files and declarations into Nodes. 3. Open CodeGraphy from the Activity Bar. 4. Select **Index Workspace** to add semantic Relationships to the initial file graph. +CodeGraphy requires VS Code 1.101 or newer. Extension users do not need to +install Node.js separately because VS Code provides the Extension host runtime. +If you use an older VS Code release, update VS Code before you update +CodeGraphy. + The extension publishes native runtime targets for Linux x64, macOS Apple Silicon, and Windows x64. It bundles Core plus baseline analysis for JavaScript, TypeScript, TSX, Python, Go, Haskell, Java, Kotlin, Lua, PHP, Ruby, Rust, Swift, Dart, C#, C, C++, Objective-C, Scala, and Pascal. Markdown analysis ships as a bundled plugin that starts enabled in new workspaces. ### CLI and Plugins -The terminal CLI supports Node.js 20 through 22. Node 22 LTS is recommended. +The CLI, plugins, and interface packages require Node.js `^22.14.0 || >=23.6.0`. +Node.js 20 is not supported. Upgrade Node.js before you update these npm +packages. An active LTS release is recommended, and CodeGraphy does not set a +maximum Node.js version. ```bash npm install -g @codegraphy-dev/core @@ -102,8 +110,8 @@ codegraphy -C /path/to/workspace index ### tldraw Offline -The first tldraw interface supports macOS and Node.js 20 through 22. Node.js 22 -LTS is recommended. Install the +The first tldraw interface supports macOS and Node.js `^22.14.0 || >=23.6.0`. An active +LTS release is recommended. Install the [tldraw offline desktop app](https://www.tldraw.com/), Core, and the interface. Then run the launcher from the workspace to index: diff --git a/apps/web/package.json b/apps/web/package.json index 5987dab2c2..154727a236 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -5,7 +5,7 @@ "private": true, "type": "module", "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "scripts": { "dev": "next dev", diff --git a/docs/PLUGINS.md b/docs/PLUGINS.md index 70af132352..4a5021d89b 100644 --- a/docs/PLUGINS.md +++ b/docs/PLUGINS.md @@ -8,6 +8,10 @@ has a small API for the behavior that it owns. - [`@codegraphy-dev/extension-plugin-api`](../packages/extension-plugin-api/README.md) extends the VS Code extension and Graph View. +Core, Core plugins, Extension plugins, and interface packages require Node.js +`^22.14.0 || >=23.6.0`. Node.js 20 is not supported. Upgrade Node.js before you +update these npm packages. CodeGraphy does not set a maximum Node.js version. + ## The basic model There are three separate steps: @@ -231,7 +235,7 @@ Keep one package-owned `build` command. A small Core plugin can use: ```json { "scripts": { - "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/plugin.js" + "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/plugin.js" } } ``` diff --git a/docs/RELEASING.md b/docs/RELEASING.md index e3ea24f72b..ba90eeebc7 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -17,7 +17,7 @@ The root package version stays pinned as monorepo workspace metadata. `scripts/r ## Prepare a Release -Use a clean checkout of `main` with the repository-pinned Node and pnpm versions. +Use a clean checkout of `main` with an active Node.js LTS release and the repository-pinned pnpm version. ```bash pnpm install --frozen-lockfile diff --git a/docs/quality/README.md b/docs/quality/README.md index 0e50d8c00f..13f903aced 100644 --- a/docs/quality/README.md +++ b/docs/quality/README.md @@ -52,7 +52,7 @@ Implementation now lives in the external `@poleski/quality-tools` package. Extension-specific architecture and lifecycle notes live in `packages/extension/docs/`. -Run these commands with the repository-pinned Node runtime from [`.nvmrc`](../../.nvmrc). `@poleski/quality-tools` uses `path.matchesGlob` and requires Node 20 or newer. +Run these commands with an active Node.js LTS release. `@poleski/quality-tools` requires Node 22.22.0 or newer. ## Workflow diff --git a/examples/example-javascript/package.json b/examples/example-javascript/package.json index 9f7644dcea..73dd318277 100644 --- a/examples/example-javascript/package.json +++ b/examples/example-javascript/package.json @@ -1,5 +1,8 @@ { "name": "codegraphy-javascript-example", "private": true, + "engines": { + "node": "^22.14.0 || >=23.6.0" + }, "type": "module" } diff --git a/examples/example-svelte/package.json b/examples/example-svelte/package.json index 7349dcf3c5..1cf7e560c8 100644 --- a/examples/example-svelte/package.json +++ b/examples/example-svelte/package.json @@ -1,6 +1,9 @@ { "name": "codegraphy-svelte-example", "private": true, + "engines": { + "node": "^22.14.0 || >=23.6.0" + }, "version": "0.0.0", "type": "module", "scripts": { diff --git a/examples/example-typescript/package.json b/examples/example-typescript/package.json index ae270ada43..1567cc7649 100644 --- a/examples/example-typescript/package.json +++ b/examples/example-typescript/package.json @@ -1,6 +1,9 @@ { "name": "codegraphy-typescript-example", "private": true, + "engines": { + "node": "^22.14.0 || >=23.6.0" + }, "scripts": { "start": "tsx src/index.ts", "build": "tsc --noEmit" diff --git a/examples/example-vue/package.json b/examples/example-vue/package.json index d342140615..0d25f43339 100644 --- a/examples/example-vue/package.json +++ b/examples/example-vue/package.json @@ -1,6 +1,9 @@ { "name": "codegraphy-vue-example", "private": true, + "engines": { + "node": "^22.14.0 || >=23.6.0" + }, "version": "0.0.0", "type": "module", "scripts": { diff --git a/package.json b/package.json index bf7e466b72..53d82599f6 100644 --- a/package.json +++ b/package.json @@ -51,29 +51,44 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20", - "vscode": "^1.85.0" + "node": "^22.14.0 || >=23.6.0", + "vscode": "^1.101.0" }, "files": [ - "dist/**", + "dist/extension.js", + "dist/node_modules/**", + "dist/webview/index.css", + "dist/webview/index.js", + "dist/webview/index.wasm", "assets/**", - "packages/plugin-godot/assets/**", - "packages/plugin-godot/dist/**", + "packages/plugin-godot/assets/godot.svg", + "packages/plugin-godot/dist/extension.js", + "packages/plugin-godot/dist/plugin.js", + "packages/plugin-godot/LICENSE", "packages/plugin-godot/package.json", - "packages/plugin-markdown/dist/**", + "packages/plugin-markdown/dist/plugin.js", + "packages/plugin-markdown/LICENSE", "packages/plugin-markdown/package.json", - "packages/plugin-particles/dist/**", + "packages/plugin-particles/dist/plugin.js", + "packages/plugin-particles/dist/node_modules/**", + "packages/plugin-particles/dist/webview.js", + "packages/plugin-particles/LICENSE", "packages/plugin-particles/package.json", - "packages/plugin-svelte/dist/**", + "packages/plugin-svelte/dist/plugin.js", + "packages/plugin-svelte/LICENSE", "packages/plugin-svelte/package.json", - "packages/plugin-typescript/dist/**", + "packages/plugin-typescript/dist/plugin.js", + "packages/plugin-typescript/LICENSE", "packages/plugin-typescript/package.json", - "packages/plugin-unity/assets/**", - "packages/plugin-unity/dist/**", + "packages/plugin-unity/assets/NOTICE.md", + "packages/plugin-unity/assets/unity.svg", + "packages/plugin-unity/dist/extension.js", + "packages/plugin-unity/dist/plugin.js", + "packages/plugin-unity/LICENSE", "packages/plugin-unity/package.json", - "packages/plugin-vue/dist/**", + "packages/plugin-vue/dist/plugin.js", + "packages/plugin-vue/LICENSE", "packages/plugin-vue/package.json", - "docs/**", "README.md", "CONTRIBUTING.md", "LICENSE" @@ -224,7 +239,7 @@ "@next/eslint-plugin-next": "^16.2.9", "@poleski/quality-tools": "0.2.1", "@types/node": "^20.11.0", - "@types/vscode": "^1.85.0", + "@types/vscode": "^1.101.0", "@vitest/coverage-istanbul": "^3.2.4", "@vscode/vsce": "^3.7.1", "esbuild": "^0.25.0", diff --git a/packages/core/README.md b/packages/core/README.md index eae862bbc1..855da38ddc 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -4,7 +4,7 @@ Shared CodeGraphy engine package for workspace indexing, Graph Cache access, plu This package is the headless core used by the VS Code extension and CLI. -The published CLI currently supports Node.js 20 through 22; Node 22 LTS is recommended. Node 23 and newer require an upstream Tree-sitter native build that is not yet available to npm consumers. +The published CLI supports Node.js `^22.14.0 || >=23.6.0`. An active Long-Term Support release is recommended. The VS Code extension bundles this package for extension runtime behavior. Users install `@codegraphy-dev/core` globally only when they want terminal workflows such as Indexing, diagnostics, graph queries, Graph Scope and filter configuration, plugin registration, or workspace plugin enablement. diff --git a/packages/core/package.json b/packages/core/package.json index f196f97c61..07d7358461 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -28,7 +28,7 @@ } }, "engines": { - "node": ">=20 <23" + "node": "^22.14.0 || >=23.6.0" }, "publishConfig": { "access": "public" @@ -54,7 +54,7 @@ "@tree-sitter-grammars/tree-sitter-lua": "0.4.1", "libsql": "0.5.29", "minimatch": "^10.2.5", - "tree-sitter": "^0.25.0", + "tree-sitter": "^0.25.1", "tree-sitter-c": "0.24.1", "tree-sitter-c-sharp": "0.23.1", "tree-sitter-cpp": "0.23.4", diff --git a/packages/core/src/cli/doctor/command.ts b/packages/core/src/cli/doctor/command.ts index ab2b0f6c1b..75e3b9662a 100644 --- a/packages/core/src/cli/doctor/command.ts +++ b/packages/core/src/cli/doctor/command.ts @@ -16,6 +16,21 @@ import { inspectWorkspaceAnalysisDatabase } from '../../graphCache/database/stor import { readCodeGraphyWorkspaceMeta } from '../../workspace/meta'; import { createDoctorCacheCheck } from './cacheCheck/model'; +export const SUPPORTED_NODE_RUNTIME_RANGE = '^22.14.0 || >=23.6.0'; + +export function isSupportedNodeRuntime(version: string): boolean { + const stableVersion = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version); + if (!stableVersion) { + return false; + } + + const major = Number(stableVersion[1]); + const minor = Number(stableVersion[2]); + return (major === 22 && minor >= 14) + || (major === 23 && minor >= 6) + || major >= 24; +} + function readSettingsCheck(workspaceRoot: string): Record { const settingsPath = getWorkspaceSettingsPath(workspaceRoot); if (!fs.existsSync(settingsPath)) { @@ -42,8 +57,7 @@ function readSettingsCheck(workspaceRoot: string): Record { export function runDoctorCommand(command: CliCommand): CommandExecutionResult { const workspaceRoot = resolveCodeGraphyWorkspacePath(command.workspacePath, process.cwd()); - const runtimeMajor = Number(process.versions.node.split('.')[0]); - const runtimeOk = runtimeMajor >= 20 && runtimeMajor < 23; + const runtimeOk = isSupportedNodeRuntime(process.versions.node); const settingsCheck = readSettingsCheck(workspaceRoot); const settings = settingsCheck.ok ? readCodeGraphyWorkspaceSettingsOrInitial(workspaceRoot) @@ -60,8 +74,10 @@ export function runDoctorCommand(command: CliCommand): CommandExecutionResult { runtime: { ok: runtimeOk, version: process.version, - supported: '>=20 <23', - ...(runtimeOk ? {} : { action: 'Use Node.js 20, 21, or 22.' }), + supported: SUPPORTED_NODE_RUNTIME_RANGE, + ...(runtimeOk ? {} : { + action: `Use a Node.js version matching ${SUPPORTED_NODE_RUNTIME_RANGE}.`, + }), }, settings: settingsCheck, cache: createDoctorCacheCheck({ diff --git a/packages/core/tests/cli/doctor/command.test.ts b/packages/core/tests/cli/doctor/command.test.ts index e3231b9fdd..2b72015ae5 100644 --- a/packages/core/tests/cli/doctor/command.test.ts +++ b/packages/core/tests/cli/doctor/command.test.ts @@ -6,6 +6,31 @@ import { describe, expect, it, vi } from 'vitest'; import { runCli } from '../../../src/cli/run'; import { requestCodeGraphyIndexWorkspace } from '../../../src/workspace/requestIndexing'; import { getWorkspaceAnalysisDatabasePath } from '../../../src/graphCache/database/storage'; +import { + isSupportedNodeRuntime, + SUPPORTED_NODE_RUNTIME_RANGE, +} from '../../../src/cli/doctor/command'; + +describe('isSupportedNodeRuntime', () => { + it.each([ + ['22.13.99', false], + ['22.14.0', true], + ['22.99.99', true], + ['23.5.99', false], + ['23.6.0', true], + ['24.0.0', true], + ['25.0.0', true], + ['22.14', false], + ['23.6.0-rc.1', false], + ['not-a-version', false], + ])('reports whether stable Node.js %s satisfies the runtime contract', (version, expected) => { + expect(isSupportedNodeRuntime(version)).toBe(expected); + }); + + it('publishes the same range used by package manifests', () => { + expect(SUPPORTED_NODE_RUNTIME_RANGE).toBe('^22.14.0 || >=23.6.0'); + }); +}); describe('cli doctor', () => { it('reports index metadata and normalized graph record counts', async () => { @@ -166,7 +191,7 @@ describe('cli doctor', () => { details: { healthy: false, checks: { - runtime: { supported: expect.any(String) }, + runtime: { ok: true, supported: '^22.14.0 || >=23.6.0' }, settings: { ok: false, action: 'Run `codegraphy index` to create workspace settings.' }, cache: { ok: false, state: 'missing', action: 'Run `codegraphy index`.' }, plugins: { ok: true, warnings: [] }, diff --git a/packages/extension-plugin-api/README.md b/packages/extension-plugin-api/README.md index 03b3cc7322..91c23314c5 100644 --- a/packages/extension-plugin-api/README.md +++ b/packages/extension-plugin-api/README.md @@ -20,6 +20,9 @@ runtimes separate and let each host load its own descriptor. ## Install +Installing this package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not +supported. + ```bash npm install -D @codegraphy-dev/extension-plugin-api ``` diff --git a/packages/extension-plugin-api/package.json b/packages/extension-plugin-api/package.json index e052679db3..ac640fccea 100644 --- a/packages/extension-plugin-api/package.json +++ b/packages/extension-plugin-api/package.json @@ -3,7 +3,7 @@ "version": "1.1.0", "description": "Type definitions for plugins hosted by the CodeGraphy VS Code extension", "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "repository": { "type": "git", diff --git a/packages/extension/docs/README.md b/packages/extension/docs/README.md index 8a47afaafd..906dd6046b 100644 --- a/packages/extension/docs/README.md +++ b/packages/extension/docs/README.md @@ -18,7 +18,10 @@ Current extension behavior to keep in mind while reading the package docs: - The extension loads workspace-local CSS Snippets listed under `cssSnippets` in `.codegraphy/settings.json`. They can style stable `data-codegraphy-*` hooks without rebuilding a VS Code theme. - the language plugins in `packages/plugin-*` are now mostly for ecosystem filters and optional semantic enrichment rather than baseline file coloring -The published CLI supports Node 20 through 22. Local tooling and CI use the repository-pinned Node runtime. +The Marketplace extension requires VS Code 1.101 or newer and uses the Node.js +runtime supplied by VS Code. Extension users do not install Node.js separately. +The published CLI and npm packages require Node.js `^22.14.0 || >=23.6.0`. Local +tooling and CI use an active Node.js LTS release. The source tree is split by runtime boundary: diff --git a/packages/extension/package.json b/packages/extension/package.json index 2f6a7cd3ce..4a8d72abcc 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -5,7 +5,7 @@ "description": "CodeGraphy VS Code extension core", "license": "MIT", "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "scripts": { "build": "pnpm run build:extension && pnpm run build:webview", @@ -64,7 +64,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "tailwind-merge": "^3.4.0", - "tree-sitter": "^0.25.0", + "tree-sitter": "^0.25.1", "tree-sitter-c": "0.24.1", "tree-sitter-c-sharp": "0.23.1", "tree-sitter-cpp": "0.23.4", diff --git a/packages/extension/scripts/buildExtension.ts b/packages/extension/scripts/buildExtension.ts index a3f0971389..92e3db6f62 100644 --- a/packages/extension/scripts/buildExtension.ts +++ b/packages/extension/scripts/buildExtension.ts @@ -16,6 +16,7 @@ const buildOptions: esbuild.BuildOptions = { external: [...EXTENSION_EXTERNAL_PACKAGE_NAMES], format: 'cjs', platform: 'node', + target: 'node22', }; function syncRuntimePackages(): void { diff --git a/packages/extension/scripts/externalPackages.ts b/packages/extension/scripts/externalPackages.ts index 82f3bd6133..1022b23470 100644 --- a/packages/extension/scripts/externalPackages.ts +++ b/packages/extension/scripts/externalPackages.ts @@ -1,12 +1,16 @@ -import { EXTENSION_RUNTIME_PACKAGE_NAMES } from './runtimePackages'; +import { EXTENSION_RUNTIME_PACKAGE_NAMES } from './runtimeStaging/model'; export { copyRuntimePackage, EXTENSION_RUNTIME_PACKAGE_NAMES, + EXTENSION_RUNTIME_TARGETS, + getExtensionRuntimePackageNames, getVendoredPackageRootPath, + resolveExtensionRuntimeTarget, resolveRuntimePackageRootPath, syncExtensionRuntimePackages, -} from './runtimePackages'; + syncParticlesRuntimePackages, +} from './runtimeStaging/model'; export const EXTENSION_EXTERNAL_PACKAGE_NAMES = [ 'vscode', diff --git a/packages/extension/scripts/runtimePackages.ts b/packages/extension/scripts/runtimePackages.ts deleted file mode 100644 index 857834481d..0000000000 --- a/packages/extension/scripts/runtimePackages.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as fs from 'node:fs'; -import * as path from 'node:path'; -import { createRequire } from 'node:module'; -import { currentTarget } from '@neon-rs/load'; -import { familySync, GLIBC, MUSL } from 'detect-libc'; - -const require = createRequire(import.meta.url); - -export const EXTENSION_RUNTIME_PACKAGE_NAMES = [ - 'libsql', - '@neon-rs/load', - 'detect-libc', - 'esbuild', - getLibsqlNativePackageName(), - 'material-icon-theme', - 'node-gyp-build', - 'tree-sitter', - 'tree-sitter-c', - 'tree-sitter-cpp', - 'tree-sitter-c-sharp', - '@driftlog/tree-sitter-dart', - 'tree-sitter-go', - 'tree-sitter-haskell', - 'tree-sitter-java', - 'tree-sitter-javascript', - '@tree-sitter-grammars/tree-sitter-kotlin', - '@tree-sitter-grammars/tree-sitter-lua', - 'tree-sitter-objc', - 'tree-sitter-php', - 'tree-sitter-python', - 'tree-sitter-ruby', - 'tree-sitter-rust', - 'tree-sitter-scala', - 'tree-sitter-swift', - 'tree-sitter-typescript', -] as const; - -export function getLibsqlNativePackageName(): string { - let target = currentTarget(); - if (familySync() === GLIBC) { - if (target === 'linux-x64-musl') target = 'linux-x64-gnu'; - if (target === 'linux-arm64-musl') target = 'linux-arm64-gnu'; - } else if (familySync() === MUSL && target === 'linux-arm-gnueabihf') { - target = 'linux-arm-musleabihf'; - } - - return `@libsql/${target}`; -} - -function resolvePackageEntryPath(packageName: string): string { - return require.resolve(packageName); -} - -export function resolveRuntimePackageRootPath( - packageName: string, - resolveEntryPath: (packageName: string) => string = resolvePackageEntryPath, -): string { - let currentPath = path.dirname(resolveEntryPath(packageName)); - - while (!fs.existsSync(path.join(currentPath, 'package.json'))) { - const parentPath = path.dirname(currentPath); - if (parentPath === currentPath) { - throw new Error(`Unable to find package root for ${packageName}`); - } - currentPath = parentPath; - } - - return currentPath; -} - -export function getVendoredPackageRootPath( - outputFilePath: string, - packageName: string, -): string { - return path.join(path.dirname(outputFilePath), 'node_modules', ...packageName.split('/')); -} - -function toPackageRelativeEntrypoint(entrypoint: string): string { - return entrypoint.endsWith('/') - ? `${entrypoint}index.js` - : `${entrypoint}/index.js`; -} - -function normalizeVendoredPackageEntrypoint(packageRootPath: string): void { - const manifestPath = path.join(packageRootPath, 'package.json'); - const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { - main?: unknown; - [key: string]: unknown; - }; - if (typeof manifest.main !== 'string' || path.extname(manifest.main) !== '') { - return; - } - - const normalizedMain = toPackageRelativeEntrypoint(manifest.main); - if (!fs.existsSync(path.join(packageRootPath, normalizedMain))) { - return; - } - - fs.writeFileSync( - manifestPath, - `${JSON.stringify({ ...manifest, main: normalizedMain }, null, 2)}\n`, - ); -} - -export function copyRuntimePackage( - outputFilePath: string, - packageName: string, - resolvePackageRootPath: (packageName: string) => string = resolveRuntimePackageRootPath, -): string { - const sourcePath = resolvePackageRootPath(packageName); - const targetPath = getVendoredPackageRootPath(outputFilePath, packageName); - - fs.mkdirSync(path.dirname(targetPath), { recursive: true }); - fs.cpSync(sourcePath, targetPath, { - recursive: true, - force: true, - dereference: true, - }); - normalizeVendoredPackageEntrypoint(targetPath); - - return targetPath; -} - -export function syncExtensionRuntimePackages( - outputFilePath: string, - packageNames: readonly string[] = EXTENSION_RUNTIME_PACKAGE_NAMES, -): string[] { - return packageNames.map(packageName => copyRuntimePackage(outputFilePath, packageName)); -} diff --git a/packages/extension/scripts/runtimeStaging/model.ts b/packages/extension/scripts/runtimeStaging/model.ts new file mode 100644 index 0000000000..9396f3399c --- /dev/null +++ b/packages/extension/scripts/runtimeStaging/model.ts @@ -0,0 +1,435 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); + +export const EXTENSION_RUNTIME_TARGETS = [ + 'linux-x64', + 'darwin-arm64', + 'win32-x64', +] as const; + +export type ExtensionRuntimeTarget = typeof EXTENSION_RUNTIME_TARGETS[number]; + +type RuntimeTargetConfig = { + platform: NodeJS.Platform; + arch: string; + libsqlPackageName: string; + esbuildPackageName: string; + parcelWatcherPackageName: string; + nativePrebuildDirectory: string; +}; + +export const RUNTIME_TARGET_CONFIG = { + 'linux-x64': { + platform: 'linux', + arch: 'x64', + libsqlPackageName: '@libsql/linux-x64-gnu', + esbuildPackageName: '@esbuild/linux-x64', + parcelWatcherPackageName: '@parcel/watcher-linux-x64-glibc', + nativePrebuildDirectory: 'linux-x64', + }, + 'darwin-arm64': { + platform: 'darwin', + arch: 'arm64', + libsqlPackageName: '@libsql/darwin-arm64', + esbuildPackageName: '@esbuild/darwin-arm64', + parcelWatcherPackageName: '@parcel/watcher-darwin-arm64', + nativePrebuildDirectory: 'darwin-arm64', + }, + 'win32-x64': { + platform: 'win32', + arch: 'x64', + libsqlPackageName: '@libsql/win32-x64-msvc', + esbuildPackageName: '@esbuild/win32-x64', + parcelWatcherPackageName: '@parcel/watcher-win32-x64', + nativePrebuildDirectory: 'win32-x64', + }, +} satisfies Record; + +type RuntimeTargetOptions = { + environment?: Partial>; + platform?: NodeJS.Platform; + arch?: string; +}; + +function isExtensionRuntimeTarget(value: string): value is ExtensionRuntimeTarget { + return EXTENSION_RUNTIME_TARGETS.includes(value as ExtensionRuntimeTarget); +} + +export function resolveExtensionRuntimeTarget({ + environment = process.env, + platform = process.platform, + arch = process.arch, +}: RuntimeTargetOptions = {}): ExtensionRuntimeTarget { + const requestedTargets = environment.CODEGRAPHY_VSIX_TARGETS + ?.split(',') + .map(target => target.trim()) + .filter(Boolean); + + if (requestedTargets && requestedTargets.length !== 1) { + throw new Error('Extension runtime staging requires exactly one VSIX target.'); + } + + const hostTarget = EXTENSION_RUNTIME_TARGETS.find((target) => { + const config = RUNTIME_TARGET_CONFIG[target]; + return config.platform === platform && config.arch === arch; + }); + if (!hostTarget) { + throw new Error( + `Unsupported extension runtime host: ${platform}-${arch}. ` + + `Supported targets are ${EXTENSION_RUNTIME_TARGETS.join(', ')}.`, + ); + } + + const requestedTarget = requestedTargets?.[0]; + if (!requestedTarget) { + return hostTarget; + } + if (!isExtensionRuntimeTarget(requestedTarget)) { + throw new Error( + `Unsupported extension runtime target: ${requestedTarget}. ` + + `Supported targets are ${EXTENSION_RUNTIME_TARGETS.join(', ')}.`, + ); + } + if (requestedTarget !== hostTarget) { + throw new Error( + `Cannot stage ${requestedTarget} native files on ${hostTarget}. ` + + 'Build the VSIX on its matching host.', + ); + } + + return requestedTarget; +} + +const TREE_SITTER_GRAMMAR_PACKAGE_NAMES = [ + 'tree-sitter-c', + 'tree-sitter-cpp', + 'tree-sitter-c-sharp', + '@driftlog/tree-sitter-dart', + 'tree-sitter-go', + 'tree-sitter-haskell', + 'tree-sitter-java', + 'tree-sitter-javascript', + '@tree-sitter-grammars/tree-sitter-kotlin', + '@tree-sitter-grammars/tree-sitter-lua', + 'tree-sitter-objc', + 'tree-sitter-php', + 'tree-sitter-python', + 'tree-sitter-ruby', + 'tree-sitter-rust', + 'tree-sitter-scala', + 'tree-sitter-swift', + 'tree-sitter-typescript', +] as const; + +export const EXTENSION_RUNTIME_PACKAGE_NAMES = [ + 'libsql', + '@neon-rs/load', + 'detect-libc', + 'material-icon-theme', + 'node-gyp-build', + 'tree-sitter', + ...TREE_SITTER_GRAMMAR_PACKAGE_NAMES, +] as const; + +export type RuntimePackagePlan = { + packageName: string; + relativeFilePaths: string[]; + resolvePackageRootPath?: (packageName: string) => string; +}; + +function resolvePackageEntryPath(packageName: string): string { + return require.resolve(packageName); +} + +export function resolveRuntimePackageRootPath( + packageName: string, + resolveEntryPath: (packageName: string) => string = resolvePackageEntryPath, +): string { + let currentPath = path.dirname(resolveEntryPath(packageName)); + + while (!fs.existsSync(path.join(currentPath, 'package.json'))) { + const parentPath = path.dirname(currentPath); + if (parentPath === currentPath) { + throw new Error(`Unable to find package root for ${packageName}`); + } + currentPath = parentPath; + } + + return currentPath; +} + +function resolveEsbuildBinaryPackageRootPath(packageName: string): string { + const manifestPath = require.resolve(`${packageName}/package.json`, { + paths: [require.resolve('esbuild')], + }); + return path.dirname(manifestPath); +} + +function resolveParcelWatcherBinaryPackageRootPath(packageName: string): string { + const requireFromCore = createRequire(require.resolve('@codegraphy-dev/core')); + const watcherEntryPath = requireFromCore.resolve('@parcel/watcher'); + const manifestPath = requireFromCore.resolve(`${packageName}/package.json`, { + paths: [path.dirname(watcherEntryPath)], + }); + return path.dirname(manifestPath); +} + +function listRelativeFiles( + packageRootPath: string, + relativeDirectoryPath: string, +): string[] { + const directoryPath = path.join(packageRootPath, relativeDirectoryPath); + if (!fs.existsSync(directoryPath)) { + return []; + } + + return fs.readdirSync(directoryPath, { recursive: true, withFileTypes: true }) + .filter(entry => entry.isFile()) + .map(entry => path.relative(packageRootPath, path.join(entry.parentPath, entry.name)) + .split(path.sep) + .join('/')); +} + +function legalFilePaths(packageRootPath: string): string[] { + return fs.readdirSync(packageRootPath, { withFileTypes: true }) + .filter(entry => entry.isFile() && /^(?:licen[cs]e|notice)(?:\.|$)/i.test(entry.name)) + .map(entry => entry.name); +} + +function staticPackagePlan( + packageName: string, + relativeFilePaths: readonly string[], + resolvePackageRootPath?: (packageName: string) => string, +): RuntimePackagePlan { + const packageRootPath = (resolvePackageRootPath ?? resolveRuntimePackageRootPath)(packageName); + return { + packageName, + relativeFilePaths: [...relativeFilePaths, ...legalFilePaths(packageRootPath)], + ...(resolvePackageRootPath ? { resolvePackageRootPath } : {}), + }; +} + +function treeSitterGrammarPlan( + packageName: string, + nativePrebuildDirectory: string, +): RuntimePackagePlan { + const packageRootPath = resolveRuntimePackageRootPath(packageName); + const bindingFilePaths = listRelativeFiles(packageRootPath, 'bindings/node') + .filter(filePath => filePath.endsWith('.js') && !filePath.endsWith('_test.js')); + const nodeTypeFilePaths = listRelativeFiles(packageRootPath, '') + .filter(filePath => filePath.endsWith('src/node-types.json')); + const prebuildFilePaths = listRelativeFiles( + packageRootPath, + path.join('prebuilds', nativePrebuildDirectory), + ).filter(filePath => filePath.endsWith('.node')); + const builtFilePaths = packageName === '@driftlog/tree-sitter-dart' + ? listRelativeFiles(packageRootPath, path.join('build', 'Release')) + .filter(filePath => filePath.endsWith('.node')) + : []; + const rootEntrypointFilePaths = packageName === '@driftlog/tree-sitter-dart' + ? ['index.js'] + : []; + const nativeFilePaths = [...prebuildFilePaths, ...builtFilePaths]; + + if (nativeFilePaths.length === 0) { + throw new Error(`No ${nativePrebuildDirectory} native binding found for ${packageName}.`); + } + + return staticPackagePlan(packageName, [ + 'package.json', + ...rootEntrypointFilePaths, + ...bindingFilePaths, + ...nodeTypeFilePaths, + ...nativeFilePaths, + ]); +} + +export function getExtensionRuntimePackageNames( + target: ExtensionRuntimeTarget, +): string[] { + const config = RUNTIME_TARGET_CONFIG[target]; + return [ + ...EXTENSION_RUNTIME_PACKAGE_NAMES, + config.libsqlPackageName, + config.esbuildPackageName, + config.parcelWatcherPackageName, + ]; +} + +function createEsbuildRuntimePackagePlans( + target: ExtensionRuntimeTarget, +): RuntimePackagePlan[] { + const config = RUNTIME_TARGET_CONFIG[target]; + return [ + staticPackagePlan('esbuild', [ + 'package.json', + 'lib/main.js', + ]), + staticPackagePlan(config.esbuildPackageName, [ + 'package.json', + config.platform === 'win32' ? 'esbuild.exe' : 'bin/esbuild', + ], resolveEsbuildBinaryPackageRootPath), + ]; +} + +export function createRuntimePackagePlans( + target: ExtensionRuntimeTarget, +): RuntimePackagePlan[] { + const config = RUNTIME_TARGET_CONFIG[target]; + const materialIconThemeRoot = resolveRuntimePackageRootPath('material-icon-theme'); + + return [ + staticPackagePlan('libsql', [ + 'package.json', + 'index.js', + 'auth.js', + 'promise.js', + 'sqlite-error.js', + ]), + staticPackagePlan('@neon-rs/load', ['package.json', 'dist/index.js']), + staticPackagePlan('detect-libc', [ + 'package.json', + 'lib/detect-libc.js', + 'lib/filesystem.js', + 'lib/process.js', + ]), + staticPackagePlan(config.libsqlPackageName, ['package.json', 'index.node']), + staticPackagePlan( + config.parcelWatcherPackageName, + ['package.json', 'watcher.node'], + resolveParcelWatcherBinaryPackageRootPath, + ), + staticPackagePlan('material-icon-theme', [ + 'package.json', + 'dist/material-icons.json', + ...listRelativeFiles(materialIconThemeRoot, 'icons'), + ]), + staticPackagePlan('node-gyp-build', [ + 'package.json', + 'index.js', + 'node-gyp-build.js', + ]), + staticPackagePlan('tree-sitter', [ + 'package.json', + 'index.js', + path.join( + 'prebuilds', + config.nativePrebuildDirectory, + 'tree-sitter.node', + ), + ]), + ...TREE_SITTER_GRAMMAR_PACKAGE_NAMES.map(packageName => treeSitterGrammarPlan( + packageName, + config.nativePrebuildDirectory, + )), + ]; +} + +export function getVendoredPackageRootPath( + outputFilePath: string, + packageName: string, +): string { + return path.join(path.dirname(outputFilePath), 'node_modules', ...packageName.split('/')); +} + +function toPackageRelativeEntrypoint(entrypoint: string): string { + return entrypoint.endsWith('/') + ? `${entrypoint}index.js` + : `${entrypoint}/index.js`; +} + +function normalizeVendoredPackageEntrypoint(packageRootPath: string): void { + const manifestPath = path.join(packageRootPath, 'package.json'); + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { + main?: unknown; + [key: string]: unknown; + }; + if (typeof manifest.main !== 'string' || path.extname(manifest.main) !== '') { + return; + } + + const normalizedMain = toPackageRelativeEntrypoint(manifest.main); + if (!fs.existsSync(path.join(packageRootPath, normalizedMain))) { + return; + } + + fs.writeFileSync( + manifestPath, + `${JSON.stringify({ ...manifest, main: normalizedMain }, null, 2)}\n`, + ); +} + +export function copyRuntimePackage( + outputFilePath: string, + packageName: string, + relativeFilePaths: readonly string[], + resolvePackageRootPath: (packageName: string) => string = resolveRuntimePackageRootPath, +): string { + const sourcePath = resolvePackageRootPath(packageName); + const targetPath = getVendoredPackageRootPath(outputFilePath, packageName); + + fs.rmSync(targetPath, { recursive: true, force: true }); + + for (const relativeFilePath of [...new Set(relativeFilePaths)]) { + const sourceFilePath = path.join(sourcePath, relativeFilePath); + if (!fs.existsSync(sourceFilePath) || !fs.statSync(sourceFilePath).isFile()) { + throw new Error(`Runtime package file is not a file: ${packageName}/${relativeFilePath}`); + } + + const targetFilePath = path.join(targetPath, relativeFilePath); + fs.mkdirSync(path.dirname(targetFilePath), { recursive: true }); + fs.cpSync(sourceFilePath, targetFilePath, { force: true }); + } + + normalizeVendoredPackageEntrypoint(targetPath); + return targetPath; +} + +function copyRuntimePackagePlans( + outputFilePath: string, + plans: readonly RuntimePackagePlan[], +): string[] { + fs.rmSync(path.join(path.dirname(outputFilePath), 'node_modules'), { + recursive: true, + force: true, + }); + + return plans.map(plan => copyRuntimePackage( + outputFilePath, + plan.packageName, + plan.relativeFilePaths, + plan.resolvePackageRootPath, + )); +} + +export function syncParticlesRuntimePackages( + particlesPluginOutputFilePath: string, + target: ExtensionRuntimeTarget = resolveExtensionRuntimeTarget(), +): string[] { + return copyRuntimePackagePlans( + particlesPluginOutputFilePath, + createEsbuildRuntimePackagePlans(target), + ); +} + +export function syncExtensionRuntimePackages( + outputFilePath: string, + target: ExtensionRuntimeTarget = resolveExtensionRuntimeTarget(), +): string[] { + const stageRootPath = path.dirname(path.dirname(outputFilePath)); + const particlesPluginOutputFilePath = path.join( + stageRootPath, + 'packages', + 'plugin-particles', + 'dist', + 'plugin.js', + ); + + return [ + ...copyRuntimePackagePlans(outputFilePath, createRuntimePackagePlans(target)), + ...syncParticlesRuntimePackages(particlesPluginOutputFilePath, target), + ]; +} diff --git a/packages/extension/scripts/validateNativeRuntime.mjs b/packages/extension/scripts/validateNativeRuntime.mjs index 834a4f4cc9..243d725036 100644 --- a/packages/extension/scripts/validateNativeRuntime.mjs +++ b/packages/extension/scripts/validateNativeRuntime.mjs @@ -2,11 +2,42 @@ import fs from 'node:fs'; import { createRequire } from 'node:module'; import os from 'node:os'; import path from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { fileURLToPath, pathToFileURL } from 'node:url'; const require = createRequire(import.meta.url); const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../..'); -const vendoredSQLitePath = path.join(repoRoot, 'dist', 'node_modules', 'libsql'); +const vendoredRuntimeRoot = path.join(repoRoot, 'dist', 'node_modules'); +const vendoredRequire = createRequire(path.join(vendoredRuntimeRoot, 'runtime-check.js')); +const vendoredSQLitePath = path.join(vendoredRuntimeRoot, 'libsql'); + +const treeSitterLanguageModules = [ + { label: 'C', packageName: 'tree-sitter-c' }, + { label: 'C++', packageName: 'tree-sitter-cpp' }, + { label: 'C#', packageName: 'tree-sitter-c-sharp' }, + { label: 'Dart', packageName: '@driftlog/tree-sitter-dart' }, + { label: 'Go', packageName: 'tree-sitter-go' }, + { label: 'Haskell', packageName: 'tree-sitter-haskell' }, + { label: 'Java', packageName: 'tree-sitter-java' }, + { label: 'JavaScript', packageName: 'tree-sitter-javascript' }, + { label: 'Kotlin', packageName: '@tree-sitter-grammars/tree-sitter-kotlin' }, + { + label: 'Lua', + packageName: '@tree-sitter-grammars/tree-sitter-lua/bindings/node/index.js', + }, + { label: 'Objective-C', packageName: 'tree-sitter-objc' }, + { label: 'PHP', packageName: 'tree-sitter-php', exportName: 'php' }, + { label: 'Python', packageName: 'tree-sitter-python' }, + { label: 'Ruby', packageName: 'tree-sitter-ruby' }, + { label: 'Rust', packageName: 'tree-sitter-rust' }, + { label: 'Scala', packageName: 'tree-sitter-scala' }, + { label: 'Swift', packageName: 'tree-sitter-swift' }, + { label: 'TSX', packageName: 'tree-sitter-typescript', exportName: 'tsx' }, + { + label: 'TypeScript', + packageName: 'tree-sitter-typescript', + exportName: 'typescript', + }, +]; try { const Database = require(vendoredSQLitePath); @@ -75,3 +106,78 @@ try { } console.log(`Loaded vendored SQLite native runtime from ${vendoredSQLitePath}`); + +try { + const watcherPackageName = process.platform === 'linux' + ? '@parcel/watcher-linux-x64-glibc' + : process.platform === 'darwin' + ? '@parcel/watcher-darwin-arm64' + : '@parcel/watcher-win32-x64'; + const watcher = vendoredRequire(watcherPackageName); + if ( + typeof watcher.subscribe !== 'function' + || typeof watcher.unsubscribe !== 'function' + ) { + throw new Error('Parcel watcher binding does not expose subscribe and unsubscribe.'); + } +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Unable to load the vendored Parcel watcher runtime: ${message}`); +} + +try { + const Parser = vendoredRequire('tree-sitter'); + + for (const languageModule of treeSitterLanguageModules) { + const modulePath = vendoredRequire.resolve(languageModule.packageName); + const importedModule = await import(pathToFileURL(modulePath).href); + const moduleValue = importedModule.default ?? importedModule; + const language = languageModule.exportName + ? moduleValue[languageModule.exportName] ?? importedModule[languageModule.exportName] + : moduleValue; + const parser = new Parser(); + parser.setLanguage(language); + const tree = parser.parse('const value = 1'); + if (!tree.rootNode) { + throw new Error(`${languageModule.label} did not return a syntax tree.`); + } + } +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Unable to load vendored Tree-sitter runtimes: ${message}`); +} + +try { + const esbuild = vendoredRequire('esbuild'); + const result = esbuild.transformSync('const value: number = 1', { loader: 'ts' }); + if (!result.code.includes('const value = 1')) { + throw new Error('TypeScript transform returned unexpected output.'); + } +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Unable to run the vendored esbuild runtime: ${message}`); +} + +try { + const materialThemeRoot = path.join(vendoredRuntimeRoot, 'material-icon-theme'); + const manifestPath = path.join(materialThemeRoot, 'dist', 'material-icons.json'); + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + const iconDefinition = Object.values(manifest.iconDefinitions ?? {})[0]; + const iconPath = iconDefinition?.iconPath; + if (typeof iconPath !== 'string') { + throw new Error('Material icon manifest has no icon definitions.'); + } + + const resolvedIconPath = path.resolve(path.dirname(manifestPath), iconPath); + if (!fs.existsSync(resolvedIconPath)) { + throw new Error(`Material icon is missing at ${resolvedIconPath}.`); + } +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Unable to load the vendored Material icon theme: ${message}`); +} + +console.log( + `Loaded ${treeSitterLanguageModules.length} vendored Tree-sitter languages, ` + + 'esbuild, and the Material icon theme.', +); diff --git a/packages/extension/src/e2e/fixtures/package-graph-view-plugin/package.json b/packages/extension/src/e2e/fixtures/package-graph-view-plugin/package.json index ee69f4a02f..f685a792ea 100644 --- a/packages/extension/src/e2e/fixtures/package-graph-view-plugin/package.json +++ b/packages/extension/src/e2e/fixtures/package-graph-view-plugin/package.json @@ -1,6 +1,9 @@ { "name": "@codegraphy/e2e-graph-view-plugin", "version": "1.0.0", + "engines": { + "node": "^22.14.0 || >=23.6.0" + }, "type": "module", "exports": "./plugin.js", "codegraphy": { diff --git a/packages/extension/tests/extension/build/runtimePackages.test.ts b/packages/extension/tests/extension/build/runtimeStaging/model.test.ts similarity index 53% rename from packages/extension/tests/extension/build/runtimePackages.test.ts rename to packages/extension/tests/extension/build/runtimeStaging/model.test.ts index 4637aebbb8..feb507b7a2 100644 --- a/packages/extension/tests/extension/build/runtimePackages.test.ts +++ b/packages/extension/tests/extension/build/runtimeStaging/model.test.ts @@ -1,41 +1,40 @@ +import { execFileSync } from 'node:child_process'; import * as fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { buildSync } from 'esbuild'; import { copyRuntimePackage, EXTENSION_EXTERNAL_PACKAGE_NAMES, - EXTENSION_RUNTIME_PACKAGE_NAMES, getVendoredPackageRootPath, - resolveRuntimePackageRootPath, - syncExtensionRuntimePackages, -} from '../../../scripts/externalPackages'; + resolveExtensionRuntimeTarget, + syncParticlesRuntimePackages, +} from '../../../../scripts/externalPackages'; const EXTENSION_PACKAGE_ROOT = path.resolve( path.dirname(fileURLToPath(import.meta.url)), - '../../..', + '../../../..', ); describe('runtime package build support', () => { - it('resolves the installed SQLite package root', () => { - const packageRootPath = resolveRuntimePackageRootPath('libsql'); - - expect(path.basename(packageRootPath)).toBe('libsql'); - expect(fs.existsSync(path.join(packageRootPath, 'package.json'))).toBe(true); - }); - - it('copies a scoped runtime package into dist/node_modules', () => { + it('copies only selected runtime files and clears stale package output', () => { const tempDirectoryPath = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraphy-runtime-build-')); const outputFilePath = path.join(tempDirectoryPath, 'dist', 'extension.js'); const sourcePackageRootPath = path.join(tempDirectoryPath, 'vendor', 'libsql'); const sourcePackageJsonPath = path.join(sourcePackageRootPath, 'package.json'); + const targetPackageRootPath = getVendoredPackageRootPath(outputFilePath, 'libsql'); fs.mkdirSync(sourcePackageRootPath, { recursive: true }); fs.writeFileSync(sourcePackageJsonPath, '{"name":"libsql"}'); + fs.writeFileSync(path.join(sourcePackageRootPath, 'README.md'), 'not runtime'); + fs.mkdirSync(targetPackageRootPath, { recursive: true }); + fs.writeFileSync(path.join(targetPackageRootPath, 'stale.node'), 'stale'); const copiedPackageRootPath = copyRuntimePackage( outputFilePath, 'libsql', + ['package.json'], () => sourcePackageRootPath, ); @@ -43,6 +42,8 @@ describe('runtime package build support', () => { expect(fs.readFileSync(path.join(copiedPackageRootPath, 'package.json'), 'utf8')).toBe( '{"name":"libsql"}', ); + expect(fs.existsSync(path.join(copiedPackageRootPath, 'README.md'))).toBe(false); + expect(fs.existsSync(path.join(copiedPackageRootPath, 'stale.node'))).toBe(false); }); it('normalizes copied package entrypoints that point at extensionless directories', () => { @@ -66,6 +67,7 @@ describe('runtime package build support', () => { const copiedPackageRootPath = copyRuntimePackage( outputFilePath, '@tree-sitter-grammars/tree-sitter-lua', + ['package.json', 'bindings/node/index.js'], () => sourcePackageRootPath, ); const copiedPackageJson = JSON.parse( @@ -75,56 +77,63 @@ describe('runtime package build support', () => { expect(copiedPackageJson.main).toBe('bindings/node/index.js'); }); - it('syncs every requested runtime package', () => { - const tempDirectoryPath = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraphy-runtime-sync-')); - const outputFilePath = path.join(tempDirectoryPath, 'dist', 'extension.js'); - const copiedPackages: string[] = []; - - const targetPaths = syncExtensionRuntimePackages(outputFilePath, ['tree-sitter'],); - copiedPackages.push(...targetPaths); + it('initializes packaged Particles custom effects from its staged runtime', () => { + const stageRootPath = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraphy-particles-package-')); + const packagedPluginRootPath = path.join(stageRootPath, 'packages', 'plugin-particles'); + const packagedPluginEntryPath = path.join(packagedPluginRootPath, 'dist', 'plugin.js'); + const workspaceRootPath = path.join(stageRootPath, 'workspace'); + const effectSourcePath = path.join( + workspaceRootPath, + '.codegraphy', + 'particles', + 'custom-effect.ts', + ); - expect(copiedPackages).toEqual([ - getVendoredPackageRootPath(outputFilePath, 'tree-sitter'), - ]); - expect(fs.existsSync(path.join(copiedPackages[0], 'package.json'))).toBe(true); - }); + buildSync({ + entryPoints: [path.join( + EXTENSION_PACKAGE_ROOT, + '..', + 'plugin-particles', + 'src', + 'plugin.ts', + )], + outfile: packagedPluginEntryPath, + bundle: true, + external: ['esbuild'], + format: 'esm', + platform: 'node', + target: 'node22', + }); + fs.copyFileSync( + path.join(EXTENSION_PACKAGE_ROOT, '..', 'plugin-particles', 'package.json'), + path.join(packagedPluginRootPath, 'package.json'), + ); + fs.mkdirSync(path.dirname(effectSourcePath), { recursive: true }); + fs.writeFileSync(effectSourcePath, 'export default function customEffect() {}\n'); - it('vendors every Tree-sitter grammar needed by the core runtime', () => { - expect(EXTENSION_RUNTIME_PACKAGE_NAMES).toEqual( - expect.arrayContaining([ - 'libsql', - '@neon-rs/load', - 'detect-libc', - 'esbuild', - expect.stringMatching(/^@libsql\//), - 'material-icon-theme', - 'tree-sitter', - 'tree-sitter-c', - 'tree-sitter-cpp', - 'tree-sitter-c-sharp', - '@driftlog/tree-sitter-dart', - 'tree-sitter-go', - 'tree-sitter-haskell', - 'tree-sitter-java', - 'tree-sitter-javascript', - '@tree-sitter-grammars/tree-sitter-kotlin', - '@tree-sitter-grammars/tree-sitter-lua', - 'tree-sitter-objc', - 'tree-sitter-php', - 'tree-sitter-python', - 'tree-sitter-ruby', - 'tree-sitter-rust', - 'tree-sitter-scala', - 'tree-sitter-swift', - 'tree-sitter-typescript', - ]), + syncParticlesRuntimePackages( + packagedPluginEntryPath, + resolveExtensionRuntimeTarget(), ); - }); + expect(fs.existsSync(path.join(stageRootPath, 'dist', 'node_modules', 'esbuild'))).toBe(false); + expect(fs.existsSync( + path.join(packagedPluginRootPath, 'dist', 'node_modules', 'esbuild'), + )).toBe(true); + + execFileSync(process.execPath, [ + '--input-type=module', + '--eval', + ` + const packagedModule = await import(${JSON.stringify(pathToFileURL(packagedPluginEntryPath).href)}); + const plugin = packagedModule.default(); + await plugin.initialize(${JSON.stringify(workspaceRootPath)}); + `, + ]); - it('resolves every vendored runtime package from the extension package', () => { - for (const packageName of EXTENSION_RUNTIME_PACKAGE_NAMES) { - expect(() => resolveRuntimePackageRootPath(packageName)).not.toThrow(); - } + expect(fs.readFileSync( + path.join(workspaceRootPath, '.codegraphy', 'cache', 'particles', 'custom-effect.js'), + 'utf8', + )).toContain('customEffect'); }); it('bundles core packages while externalizing only VS Code and native runtime packages', () => { diff --git a/packages/extension/tests/playwrightVscodeConfig.test.ts b/packages/extension/tests/playwrightVscodeConfig.test.ts index 584bff8d22..1da1c34980 100644 --- a/packages/extension/tests/playwrightVscodeConfig.test.ts +++ b/packages/extension/tests/playwrightVscodeConfig.test.ts @@ -109,7 +109,8 @@ describe('VS Code Playwright config', () => { ); expect(vsixJob).toContain('CODEGRAPHY_VSCODE_TEST_VERSION: 1.125.1'); - expect(smokeScript).toContain('version: vscodeVersion'); + expect(smokeScript).toContain('downloadAndUnzipVSCode(vscodeVersion)'); + expect(smokeScript).toContain('vscodeExecutablePath,'); }); it('pins the CI VS Code host version into the Playwright Turbo hash', () => { diff --git a/packages/graph-renderer/README.md b/packages/graph-renderer/README.md index ede8066124..e8e8c46c82 100644 --- a/packages/graph-renderer/README.md +++ b/packages/graph-renderer/README.md @@ -10,6 +10,10 @@ The package owns graph rendering and graph physics only. Your application owns i ## Install +Installing this package requires Node.js `^22.14.0 || >=23.6.0`. The renderer still +runs in a browser with WebAssembly and WebGPU; the Node.js requirement applies +to package installation and tooling. + ```bash pnpm add @codegraphy-dev/graph-renderer ``` diff --git a/packages/graph-renderer/package.json b/packages/graph-renderer/package.json index 40bb1c2c29..dc1cbf7975 100644 --- a/packages/graph-renderer/package.json +++ b/packages/graph-renderer/package.json @@ -27,7 +27,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", diff --git a/packages/plugin-api/README.md b/packages/plugin-api/README.md index 77d4e7368f..31ac52c938 100644 --- a/packages/plugin-api/README.md +++ b/packages/plugin-api/README.md @@ -8,6 +8,9 @@ VS Code Extension and Graph View behavior. ## Install +Installing this package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not +supported. + ```bash npm install -D @codegraphy-dev/plugin-api ``` diff --git a/packages/plugin-api/package.json b/packages/plugin-api/package.json index ee70dbc9ef..b7c9ff45fc 100644 --- a/packages/plugin-api/package.json +++ b/packages/plugin-api/package.json @@ -3,7 +3,7 @@ "version": "7.0.0", "description": "Type definitions for CodeGraphy plugins", "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "repository": { "type": "git", diff --git a/packages/plugin-godot/README.md b/packages/plugin-godot/README.md index 7d816d4682..34969ccac6 100644 --- a/packages/plugin-godot/README.md +++ b/packages/plugin-godot/README.md @@ -12,6 +12,8 @@ colors, shapes, and icons. The CLI loads only the Core entry. ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + Install `@codegraphy-dev/core` first if the `codegraphy` CLI is not already available. ```bash diff --git a/packages/plugin-godot/package.json b/packages/plugin-godot/package.json index 18d2445de3..f3e90b3f46 100644 --- a/packages/plugin-godot/package.json +++ b/packages/plugin-godot/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", @@ -42,7 +42,7 @@ "LICENSE" ], "scripts": { - "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts src/extension.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outdir=dist", + "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts src/extension.ts --bundle --platform=node --format=esm --target=node22 --sourcemap --outdir=dist", "test": "vitest run", "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"__tests__/**/*.ts\"", "typecheck": "tsc --noEmit -p tsconfig.json" diff --git a/packages/plugin-markdown/README.md b/packages/plugin-markdown/README.md index 80730d87f1..387b72d9b7 100644 --- a/packages/plugin-markdown/README.md +++ b/packages/plugin-markdown/README.md @@ -4,6 +4,10 @@ Headless CodeGraphy plugin for Markdown and Obsidian-style wikilinks. This package exposes the Markdown plugin runtime used by `@codegraphy-dev/core`. It detects wikilinks such as `[[Note]]`, `[[folder/Note|Alias]]`, and `![[Embed]]`, then emits Relationship Graph references between workspace files. +Installing this package separately requires Node.js `^22.14.0 || >=23.6.0`. Node.js +20 is not supported. The VS Code extension already includes and manages this +plugin, so extension users do not install it separately. + ## CodeGraphy Metadata The package declares `package.json#codegraphy` metadata so CodeGraphy can register and validate the plugin without importing runtime code. Runtime loading happens during explicit Indexing. diff --git a/packages/plugin-markdown/package.json b/packages/plugin-markdown/package.json index 89e518749b..ef15386431 100644 --- a/packages/plugin-markdown/package.json +++ b/packages/plugin-markdown/package.json @@ -13,7 +13,7 @@ } }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "publishConfig": { "access": "public" @@ -25,7 +25,7 @@ "LICENSE" ], "scripts": { - "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outfile=dist/plugin.js", + "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node22 --sourcemap --outfile=dist/plugin.js", "lint": "eslint src", "test": "vitest run", "typecheck": "tsc --noEmit -p tsconfig.json" diff --git a/packages/plugin-particles/README.md b/packages/plugin-particles/README.md index bda5342ca4..ad99571348 100644 --- a/packages/plugin-particles/README.md +++ b/packages/plugin-particles/README.md @@ -6,6 +6,8 @@ The built-in presets are Synapse, Rain, Constellations, Perlin Flow, Leaves, Spa ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + ```bash npm install -g @codegraphy-dev/plugin-particles codegraphy plugins register @codegraphy-dev/plugin-particles diff --git a/packages/plugin-particles/build.mjs b/packages/plugin-particles/build.mjs index f36085a720..d9b30a4423 100644 --- a/packages/plugin-particles/build.mjs +++ b/packages/plugin-particles/build.mjs @@ -19,7 +19,7 @@ await Promise.all([ format: 'esm', platform: 'node', sourcemap: true, - target: 'node20', + target: 'node22', }), build({ entryPoints: { diff --git a/packages/plugin-particles/package.json b/packages/plugin-particles/package.json index b83c967caf..cf4a45aabd 100644 --- a/packages/plugin-particles/package.json +++ b/packages/plugin-particles/package.json @@ -25,7 +25,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20.20.0 <23" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", diff --git a/packages/plugin-svelte/README.md b/packages/plugin-svelte/README.md index be885412a6..dccf58ae81 100644 --- a/packages/plugin-svelte/README.md +++ b/packages/plugin-svelte/README.md @@ -7,6 +7,8 @@ Adds Svelte component script import analysis to [CodeGraphy](https://marketplace ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + Install `@codegraphy-dev/core` first if the `codegraphy` CLI is not already available. ```bash diff --git a/packages/plugin-svelte/build.mjs b/packages/plugin-svelte/build.mjs index 549c0d4b9c..2066ed8e59 100644 --- a/packages/plugin-svelte/build.mjs +++ b/packages/plugin-svelte/build.mjs @@ -27,5 +27,5 @@ await build({ format: 'esm', platform: 'node', sourcemap: true, - target: 'node20', + target: 'node22', }); diff --git a/packages/plugin-svelte/package.json b/packages/plugin-svelte/package.json index 2b91c039f7..421e622660 100644 --- a/packages/plugin-svelte/package.json +++ b/packages/plugin-svelte/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", diff --git a/packages/plugin-typescript/README.md b/packages/plugin-typescript/README.md index 589f8ec2c8..c39c2b729e 100644 --- a/packages/plugin-typescript/README.md +++ b/packages/plugin-typescript/README.md @@ -7,6 +7,8 @@ Adds TypeScript project-aware alias import relationships and TypeScript/JavaScri ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + Install `@codegraphy-dev/core` first if the `codegraphy` CLI is not already available. ```bash diff --git a/packages/plugin-typescript/build.mjs b/packages/plugin-typescript/build.mjs index 549c0d4b9c..2066ed8e59 100644 --- a/packages/plugin-typescript/build.mjs +++ b/packages/plugin-typescript/build.mjs @@ -27,5 +27,5 @@ await build({ format: 'esm', platform: 'node', sourcemap: true, - target: 'node20', + target: 'node22', }); diff --git a/packages/plugin-typescript/package.json b/packages/plugin-typescript/package.json index 1035e6c2fb..3ae3a8415a 100644 --- a/packages/plugin-typescript/package.json +++ b/packages/plugin-typescript/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", diff --git a/packages/plugin-unity/README.md b/packages/plugin-unity/README.md index beda5795b1..6c1de89bc0 100644 --- a/packages/plugin-unity/README.md +++ b/packages/plugin-unity/README.md @@ -12,6 +12,8 @@ colors, shapes, and icons. The CLI loads only the Core entry. ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + Install `@codegraphy-dev/core` first if the `codegraphy` CLI is not already available. ```bash diff --git a/packages/plugin-unity/package.json b/packages/plugin-unity/package.json index 218184b2e5..f843367480 100644 --- a/packages/plugin-unity/package.json +++ b/packages/plugin-unity/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", @@ -41,7 +41,7 @@ "LICENSE" ], "scripts": { - "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts src/extension.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outdir=dist", + "build": "tsc -p tsconfig.build.json && esbuild src/plugin.ts src/extension.ts --bundle --platform=node --format=esm --target=node22 --sourcemap --outdir=dist", "test": "vitest run", "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"__tests__/**/*.ts\"", "typecheck": "tsc --noEmit -p tsconfig.json" diff --git a/packages/plugin-vue/README.md b/packages/plugin-vue/README.md index 7c6169a6b6..468785f8e0 100644 --- a/packages/plugin-vue/README.md +++ b/packages/plugin-vue/README.md @@ -7,6 +7,8 @@ Adds Vue Single-File Component script import analysis to [CodeGraphy](https://ma ## Install +This package requires Node.js `^22.14.0 || >=23.6.0`. Node.js 20 is not supported. + Install `@codegraphy-dev/core` first if the `codegraphy` CLI is not already available. ```bash diff --git a/packages/plugin-vue/build.mjs b/packages/plugin-vue/build.mjs index 58ec49ac6a..5170c1aaeb 100644 --- a/packages/plugin-vue/build.mjs +++ b/packages/plugin-vue/build.mjs @@ -43,5 +43,5 @@ await build({ }, }], sourcemap: true, - target: 'node20', + target: 'node22', }); diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json index bcbfd63e5c..0791499b3b 100644 --- a/packages/plugin-vue/package.json +++ b/packages/plugin-vue/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/joesobo/CodeGraphyV4/issues" }, "engines": { - "node": ">=20" + "node": "^22.14.0 || >=23.6.0" }, "keywords": [ "codegraphy", diff --git a/packages/tldraw/README.md b/packages/tldraw/README.md index d3978e0576..b28a46730d 100644 --- a/packages/tldraw/README.md +++ b/packages/tldraw/README.md @@ -9,7 +9,7 @@ force physics inside the saved `.tldraw` document. ## Requirements - macOS -- Node.js 20 through 22. Node.js 22 LTS is recommended. +- Node.js `^22.14.0 || >=23.6.0`. An active LTS release is recommended. - [tldraw offline](https://offline.tldraw.com/) installed in `/Applications` The first launcher release supports macOS because it opens documents through diff --git a/packages/tldraw/package.json b/packages/tldraw/package.json index efd2ff43ff..3131438bab 100644 --- a/packages/tldraw/package.json +++ b/packages/tldraw/package.json @@ -24,7 +24,7 @@ "codegraphy-tldraw": "./dist/codegraphy-tldraw.js" }, "engines": { - "node": ">=20 <23" + "node": "^22.14.0 || >=23.6.0" }, "os": [ "darwin" diff --git a/packages/tldraw/scripts/build.ts b/packages/tldraw/scripts/build.ts index 8eded8ca5c..2f38317a47 100644 --- a/packages/tldraw/scripts/build.ts +++ b/packages/tldraw/scripts/build.ts @@ -44,7 +44,7 @@ await Promise.all([ bundle: true, platform: 'node', format: 'esm', - target: 'node20', + target: 'node22', sourcemap: true, external, banner: { js: '#!/usr/bin/env node' }, diff --git a/patches/README.md b/patches/README.md deleted file mode 100644 index 34fb93f880..0000000000 --- a/patches/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Dependency Patches - -## `tree-sitter@0.25.0` - -CodeGraphy carries a temporary pnpm patch for `tree-sitter@0.25.0` so the native Node binding builds with C++20 on Node 23 and newer. - -Upstream has already merged the equivalent fix in tree-sitter/node-tree-sitter#258, but the fixed npm release is not currently published. The follow-up issue is: - -https://github.com/tree-sitter/node-tree-sitter/issues/276 - -Remove this patch once `tree-sitter` publishes a release that includes the Node 23+ C++20 build fix, then replace it with a normal dependency update. - -This pnpm patch only applies inside this workspace; npm does not propagate a package publisher's pnpm patches to consumers. Until the upstream release is available, `@codegraphy-dev/core` therefore declares Node 20 through 22 as its supported CLI range. diff --git a/patches/tree-sitter@0.25.0.patch b/patches/tree-sitter@0.25.0.patch deleted file mode 100644 index 3e658b0cd2..0000000000 --- a/patches/tree-sitter@0.25.0.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/binding.gyp b/binding.gyp -index bb40aa7e8d41644ba690761e9064fc1d0f2dcd6b..1e1641b2e3d6733642ea0ff06cd88b3b3023fd6c 100644 ---- a/binding.gyp -+++ b/binding.gyp -@@ -25,13 +25,13 @@ - "NAPI_VERSION=<(napi_build_version)", - ], - "cflags_cc": [ -- "-std=c++17" -+ "-std=c++20" - ], - "conditions": [ - ["OS=='mac'", { - "xcode_settings": { - "GCC_SYMBOLS_PRIVATE_EXTERN": "YES", # -fvisibility=hidden -- "CLANG_CXX_LANGUAGE_STANDARD": "c++17", -+ "CLANG_CXX_LANGUAGE_STANDARD": "c++20", - "MACOSX_DEPLOYMENT_TARGET": "10.9", - }, - }], -@@ -39,7 +39,7 @@ - "msvs_settings": { - "VCCLCompilerTool": { - "AdditionalOptions": [ -- "/std:c++17", -+ "/std:c++20", - ], - "RuntimeLibrary": 0, - }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5cbcd1faab..a3e88479f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,11 +16,6 @@ overrides: packageExtensionsChecksum: sha256-XUHXilG696aPT8nrf3+inq4J0SEpv/Bjg7CPUKMFDu0= -patchedDependencies: - tree-sitter@0.25.0: - hash: 581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb - path: patches/tree-sitter@0.25.0.patch - importers: .: @@ -44,7 +39,7 @@ importers: specifier: ^20.11.0 version: 20.19.37 '@types/vscode': - specifier: ^1.85.0 + specifier: ^1.101.0 version: 1.110.0 '@vitest/coverage-istanbul': specifier: ^3.2.4 @@ -208,16 +203,16 @@ importers: version: link:../plugin-markdown '@driftlog/tree-sitter-dart': specifier: 1.0.4 - version: 1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.1) '@parcel/watcher': specifier: 2.6.0 version: 2.6.0 '@tree-sitter-grammars/tree-sitter-kotlin': specifier: 1.1.0 - version: 1.1.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 1.1.0(tree-sitter@0.25.1) '@tree-sitter-grammars/tree-sitter-lua': specifier: 0.4.1 - version: 0.4.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.4.1(tree-sitter@0.25.1) libsql: specifier: 0.5.29 version: 0.5.29 @@ -225,53 +220,53 @@ importers: specifier: ^10.2.5 version: 10.2.5 tree-sitter: - specifier: ^0.25.0 - version: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + specifier: ^0.25.1 + version: 0.25.1 tree-sitter-c: specifier: 0.24.1 - version: 0.24.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.1(tree-sitter@0.25.1) tree-sitter-c-sharp: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-cpp: specifier: 0.23.4 - version: 0.23.4(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.4(tree-sitter@0.25.1) tree-sitter-go: specifier: 0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-haskell: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-java: specifier: 0.23.5 - version: 0.23.5(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.5(tree-sitter@0.25.1) tree-sitter-javascript: specifier: ^0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-objc: specifier: 3.0.2 - version: 3.0.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 3.0.2(tree-sitter@0.25.1) tree-sitter-php: specifier: 0.24.2 - version: 0.24.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.2(tree-sitter@0.25.1) tree-sitter-python: specifier: 0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-ruby: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-rust: specifier: 0.24.0 - version: 0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.0(tree-sitter@0.25.1) tree-sitter-scala: specifier: 0.24.0 - version: 0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.0(tree-sitter@0.25.1) tree-sitter-swift: specifier: 0.7.1 - version: 0.7.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.7.1(tree-sitter@0.25.1) tree-sitter-typescript: specifier: ^0.23.2 - version: 0.23.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.2(tree-sitter@0.25.1) zod: specifier: ^4.3.6 version: 4.3.6 @@ -292,7 +287,7 @@ importers: version: link:../plugin-api '@driftlog/tree-sitter-dart': specifier: 1.0.4 - version: 1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.1) '@floating-ui/react': specifier: ^0.27.19 version: 0.27.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -337,10 +332,10 @@ importers: version: 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tree-sitter-grammars/tree-sitter-kotlin': specifier: 1.1.0 - version: 1.1.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 1.1.0(tree-sitter@0.25.1) '@tree-sitter-grammars/tree-sitter-lua': specifier: 0.4.1 - version: 0.4.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.4.1(tree-sitter@0.25.1) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -381,53 +376,53 @@ importers: specifier: ^3.4.0 version: 3.5.0 tree-sitter: - specifier: ^0.25.0 - version: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + specifier: ^0.25.1 + version: 0.25.1 tree-sitter-c: specifier: 0.24.1 - version: 0.24.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.1(tree-sitter@0.25.1) tree-sitter-c-sharp: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-cpp: specifier: 0.23.4 - version: 0.23.4(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.4(tree-sitter@0.25.1) tree-sitter-go: specifier: 0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-haskell: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-java: specifier: 0.23.5 - version: 0.23.5(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.5(tree-sitter@0.25.1) tree-sitter-javascript: specifier: ^0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-objc: specifier: 3.0.2 - version: 3.0.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 3.0.2(tree-sitter@0.25.1) tree-sitter-php: specifier: 0.24.2 - version: 0.24.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.2(tree-sitter@0.25.1) tree-sitter-python: specifier: 0.25.0 - version: 0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.25.0(tree-sitter@0.25.1) tree-sitter-ruby: specifier: 0.23.1 - version: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.1(tree-sitter@0.25.1) tree-sitter-rust: specifier: 0.24.0 - version: 0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.0(tree-sitter@0.25.1) tree-sitter-scala: specifier: 0.24.0 - version: 0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.24.0(tree-sitter@0.25.1) tree-sitter-swift: specifier: 0.7.1 - version: 0.7.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.7.1(tree-sitter@0.25.1) tree-sitter-typescript: specifier: ^0.23.2 - version: 0.23.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + version: 0.23.2(tree-sitter@0.25.1) zod: specifier: ^4.3.6 version: 4.3.6 @@ -7400,8 +7395,8 @@ packages: tree-sitter: optional: true - tree-sitter@0.25.0: - resolution: {integrity: sha512-PGZZzFW63eElZJDe/b/R/LbsjDDYJa5UEjLZJB59RQsMX+fo0j54fqBPn1MGKav/QNa0JR0zBiVaikYDWCj5KQ==} + tree-sitter@0.25.1: + resolution: {integrity: sha512-mrcEdkYtHfrK1A6fs3O6FxkBo0Qig5XUXqHhxUOQu0bmPo00QF4XaSx4edpazdHwxnSCjlGKGgIqWdaN4dvTLA==} ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} @@ -8444,12 +8439,12 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@driftlog/tree-sitter-dart@1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb))': + '@driftlog/tree-sitter-dart@1.0.4(node-addon-api@8.7.0)(tree-sitter@0.25.1)': dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 '@emnapi/core@1.10.0': dependencies: @@ -10974,20 +10969,20 @@ snapshots: dependencies: '@tldraw/utils': 5.2.5 - '@tree-sitter-grammars/tree-sitter-kotlin@1.1.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb))': + '@tree-sitter-grammars/tree-sitter-kotlin@1.1.0(tree-sitter@0.25.1)': dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 npm-check-updates: 17.1.18 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - '@tree-sitter-grammars/tree-sitter-lua@0.4.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb))': + '@tree-sitter-grammars/tree-sitter-lua@0.4.1(tree-sitter@0.25.1)': dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 '@turbo/darwin-64@2.10.6': optional: true @@ -14893,132 +14888,132 @@ snapshots: tree-kill@1.2.2: {} - tree-sitter-c-sharp@0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-c-sharp@0.23.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-c@0.23.6(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-c@0.23.6(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-c@0.24.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-c@0.24.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 tree-sitter-cli@0.23.2: {} - tree-sitter-cpp@0.23.4(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-cpp@0.23.4(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 - tree-sitter-c: 0.23.6(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + tree-sitter-c: 0.23.6(tree-sitter@0.25.1) optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-go@0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-go@0.25.0(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-haskell@0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-haskell@0.23.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-java@0.23.5(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-java@0.23.5(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-javascript@0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-javascript@0.23.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-javascript@0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-javascript@0.25.0(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-objc@3.0.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-objc@3.0.2(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 - tree-sitter-c: 0.23.6(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + tree-sitter-c: 0.23.6(tree-sitter@0.25.1) optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-php@0.24.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-php@0.24.2(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-python@0.25.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-python@0.25.0(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-ruby@0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-ruby@0.23.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-rust@0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-rust@0.24.0(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-scala@0.24.0(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-scala@0.24.0(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter-swift@0.7.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-swift@0.7.1(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 tree-sitter-cli: 0.23.2 which: 2.0.2 - tree-sitter-typescript@0.23.2(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)): + tree-sitter-typescript@0.23.2(tree-sitter@0.25.1): dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 - tree-sitter-javascript: 0.23.1(tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb)) + tree-sitter-javascript: 0.23.1(tree-sitter@0.25.1) optionalDependencies: - tree-sitter: 0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb) + tree-sitter: 0.25.1 - tree-sitter@0.25.0(patch_hash=581e1c376edeabe3d25b64ea7bac59e14cc731627b17b97acccf0cce1dd051cb): + tree-sitter@0.25.1: dependencies: node-addon-api: 8.7.0 node-gyp-build: 4.8.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 67c255f4a8..2c3a59fa8c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -68,5 +68,3 @@ packageExtensions: "react-force-graph-3d@*": dependencies: "@types/react": "^18.2.48" -patchedDependencies: - tree-sitter@0.25.0: patches/tree-sitter@0.25.0.patch diff --git a/scripts/release-core.mjs b/scripts/release-core.mjs index 5e8e6f14ed..558b1e8b1f 100644 --- a/scripts/release-core.mjs +++ b/scripts/release-core.mjs @@ -64,11 +64,12 @@ export function collectCoreReleaseBuildFilters(rootManifest, baseDir = repoRoot) const filters = ['@codegraphy-dev/extension...']; for (const entry of collectCoreReleaseEntries(rootManifest)) { - if (!/^packages\/[^/]+\/dist$/.test(entry)) { + const packageDirectory = entry.match(/^(packages\/[^/]+)(?:\/|$)/)?.[1]; + if (!packageDirectory) { continue; } - const packageManifestPath = path.join(baseDir, path.dirname(entry), 'package.json'); + const packageManifestPath = path.join(baseDir, packageDirectory, 'package.json'); if (!existsSync(packageManifestPath)) { continue; } diff --git a/scripts/smoke-installed-vsix.mjs b/scripts/smoke-installed-vsix.mjs index 6f57bf2369..2ce5dcba32 100644 --- a/scripts/smoke-installed-vsix.mjs +++ b/scripts/smoke-installed-vsix.mjs @@ -17,7 +17,11 @@ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..' const requireFromExtension = createRequire( path.join(repoRoot, 'packages', 'extension', 'package.json'), ); -const { runTests, runVSCodeCommand } = requireFromExtension('@vscode/test-electron'); +const { + downloadAndUnzipVSCode, + resolveCliArgsFromVSCodeExecutablePath, + runTests, +} = requireFromExtension('@vscode/test-electron'); const vscodeVersion = process.env.CODEGRAPHY_VSCODE_TEST_VERSION ?? '1.125.1'; const hostTargetByPlatform = { @@ -98,18 +102,32 @@ async function smokeInstalledVsix({ target, vsixPath }) { prepareScenarioWorkspacePlugins(scenario, repoRoot, workspacePath, pluginCacheHomeDir, false); await writeHarnessExtension(harnessPath); - await runVSCodeCommand([ + const downloadedExecutablePath = await downloadAndUnzipVSCode(vscodeVersion); + const vscodeExecutablePath = resolveCurrentVsCodeExecutablePath(downloadedExecutablePath); + const [cliPath, ...cliArgs] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath); + const installResult = spawnSync(cliPath, [ + ...cliArgs, ...profileArgs, '--install-extension', vsixPath, '--force', - ], { version: vscodeVersion }); + ], { + encoding: 'utf8', + shell: process.platform === 'win32', + }); + if (installResult.status !== 0) { + throw new Error( + `Unable to install ${path.basename(vsixPath)}.\n` + + `${installResult.stdout}${installResult.stderr}`, + ); + } await runTests({ - version: vscodeVersion, extensionDevelopmentPath: harnessPath, extensionTestsPath, + vscodeExecutablePath, extensionTestsEnv: { + ELECTRON_RUN_AS_NODE: undefined, CODEGRAPHY_E2E_SCENARIO: 'typescript', CODEGRAPHY_E2E_GREP: 'extension activates without error|all commands are registered|manual graph indexing creates scenario edges', }, @@ -134,6 +152,21 @@ async function smokeInstalledVsix({ target, vsixPath }) { } } +function resolveCurrentVsCodeExecutablePath(downloadedExecutablePath) { + if (existsSync(downloadedExecutablePath)) { + return downloadedExecutablePath; + } + + if (process.platform === 'darwin' && path.basename(downloadedExecutablePath) === 'Electron') { + const currentExecutablePath = path.join(path.dirname(downloadedExecutablePath), 'Code'); + if (existsSync(currentExecutablePath)) { + return currentExecutablePath; + } + } + + throw new Error(`Downloaded VS Code executable is missing at ${downloadedExecutablePath}.`); +} + function buildScenarioWorkspacePluginPackages(scenario) { for (const relativePath of scenario.workspacePluginPackageRelativePaths) { const packageRoot = path.resolve(repoRoot, relativePath); @@ -226,7 +259,7 @@ async function writeHarnessExtension(harnessPath) { publisher: 'codegraphy', version: '0.0.0', engines: { - vscode: '^1.85.0', + vscode: '^1.101.0', }, activationEvents: [], main: './extension.js', diff --git a/scripts/validate-vsix-native-artifacts.mjs b/scripts/validate-vsix-native-artifacts.mjs index b4d181fd6a..bea24def55 100644 --- a/scripts/validate-vsix-native-artifacts.mjs +++ b/scripts/validate-vsix-native-artifacts.mjs @@ -17,10 +17,43 @@ const libsqlNativeBinaryPathByTarget = { 'win32-x64': 'extension/dist/node_modules/@libsql/win32-x64-msvc/index.node', }; +const treeSitterNativeBinaryPathByTarget = { + 'linux-x64': 'extension/dist/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node', + 'darwin-arm64': 'extension/dist/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node', + 'win32-x64': 'extension/dist/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node', +}; + +const parcelWatcherNativeBinaryPathByTarget = { + 'linux-x64': 'extension/dist/node_modules/@parcel/watcher-linux-x64-glibc/watcher.node', + 'darwin-arm64': 'extension/dist/node_modules/@parcel/watcher-darwin-arm64/watcher.node', + 'win32-x64': 'extension/dist/node_modules/@parcel/watcher-win32-x64/watcher.node', +}; + +const particlesEsbuildNativeBinaryPathByTarget = { + 'linux-x64': 'extension/packages/plugin-particles/dist/node_modules/@esbuild/linux-x64/bin/esbuild', + 'darwin-arm64': 'extension/packages/plugin-particles/dist/node_modules/@esbuild/darwin-arm64/bin/esbuild', + 'win32-x64': 'extension/packages/plugin-particles/dist/node_modules/@esbuild/win32-x64/esbuild.exe', +}; + +const rootEsbuildNativePackagePathByTarget = { + 'linux-x64': 'extension/dist/node_modules/@esbuild/linux-x64/', + 'darwin-arm64': 'extension/dist/node_modules/@esbuild/darwin-arm64/', + 'win32-x64': 'extension/dist/node_modules/@esbuild/win32-x64/', +}; + function nativeBinaryPathsForTarget(target) { return [ libsqlNativeBinaryPathByTarget[target], - 'extension/dist/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node', + treeSitterNativeBinaryPathByTarget[target], + parcelWatcherNativeBinaryPathByTarget[target], + particlesEsbuildNativeBinaryPathByTarget[target], + ]; +} + +function forbiddenRootEsbuildPathPrefixesForTarget(target) { + return [ + 'extension/dist/node_modules/esbuild/', + rootEsbuildNativePackagePathByTarget[target], ]; } @@ -115,6 +148,21 @@ function findVsixForTarget({ artifactsDir, version, target }) { .at(0); } +function listVsixPaths(vsixPath) { + const result = spawnSync('unzip', ['-Z1', vsixPath], { + encoding: 'utf8', + maxBuffer: 64 * 1024 * 1024, + stdio: ['ignore', 'pipe', 'pipe'], + }); + + if (result.status !== 0) { + const errorMessage = result.error ? `${result.error.message}\n` : ''; + throw new Error(`Unable to list ${vsixPath}.\n${errorMessage}${result.stderr}`); + } + + return result.stdout.split('\n').filter(Boolean); +} + function extractNativeBinaryFromVsix(vsixPath, nativeBinaryPath) { const result = spawnSync('unzip', ['-p', vsixPath, nativeBinaryPath], { encoding: 'buffer', @@ -154,6 +202,16 @@ export function validateVsixNativeArtifacts({ throw new Error(`Missing VSIX artifact for ${target} in ${artifactsDir}.`); } + const vsixPaths = listVsixPaths(vsixPath); + for (const forbiddenPrefix of forbiddenRootEsbuildPathPrefixesForTarget(target)) { + const oldRootEsbuildPath = vsixPaths.find(entry => entry.startsWith(forbiddenPrefix)); + if (oldRootEsbuildPath) { + throw new Error( + `${path.basename(vsixPath)} must not contain old root esbuild path ${oldRootEsbuildPath}.`, + ); + } + } + for (const nativeBinaryPath of nativeBinaryPathsForTarget(target)) { const binary = extractNativeBinaryFromVsix(vsixPath, nativeBinaryPath); const actualKind = identifyNativeBinary(binary); diff --git a/tests/release/corePackage.test.mjs b/tests/release/corePackage.test.mjs index 81a290acb1..cb9322da1b 100644 --- a/tests/release/corePackage.test.mjs +++ b/tests/release/corePackage.test.mjs @@ -31,7 +31,7 @@ test('Core package declares the Node range supported by its native dependencies' fs.readFileSync(path.join(repoRoot, 'packages', 'core', 'package.json'), 'utf8'), ); - assert.equal(manifest.engines.node, '>=20 <23'); + assert.equal(manifest.engines.node, '^22.14.0 || >=23.6.0'); }); test('Core publishes dependency-free Graph Scope defaults as a focused subpath', () => { diff --git a/tests/release/nodeRuntime.test.mjs b/tests/release/nodeRuntime.test.mjs new file mode 100644 index 0000000000..6fef2e788c --- /dev/null +++ b/tests/release/nodeRuntime.test.mjs @@ -0,0 +1,39 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import test from 'node:test'; + +const NODE_RUNTIME_RANGE = '^22.14.0 || >=23.6.0'; +const MANIFEST_PATHS = [ + 'package.json', + 'apps/web/package.json', + 'examples/example-javascript/package.json', + 'examples/example-svelte/package.json', + 'examples/example-typescript/package.json', + 'examples/example-vue/package.json', + 'packages/core/package.json', + 'packages/extension/package.json', + 'packages/extension-plugin-api/package.json', + 'packages/extension/src/e2e/fixtures/package-graph-view-plugin/package.json', + 'packages/graph-renderer/package.json', + 'packages/plugin-api/package.json', + 'packages/plugin-godot/package.json', + 'packages/plugin-markdown/package.json', + 'packages/plugin-particles/package.json', + 'packages/plugin-svelte/package.json', + 'packages/plugin-typescript/package.json', + 'packages/plugin-unity/package.json', + 'packages/plugin-vue/package.json', + 'packages/tldraw/package.json', +]; + +function readManifest(relativePath) { + return JSON.parse(fs.readFileSync(path.join(process.cwd(), relativePath), 'utf8')); +} + +test('first-party manifests declare the Node-API 10 compatible runtime range', () => { + for (const manifestPath of MANIFEST_PATHS) { + const manifest = readManifest(manifestPath); + assert.equal(manifest.engines?.node, NODE_RUNTIME_RANGE, manifestPath); + } +}); diff --git a/tests/release/pluginApiCompatibility.test.mjs b/tests/release/pluginApiCompatibility.test.mjs index cdd791cb14..4f87bf52d6 100644 --- a/tests/release/pluginApiCompatibility.test.mjs +++ b/tests/release/pluginApiCompatibility.test.mjs @@ -67,7 +67,11 @@ test('public plugin API packages include publish and support metadata', () => { for (const packageName of ['plugin-api', 'extension-plugin-api']) { const packageManifest = readJson(`packages/${packageName}/package.json`); - assert.equal(packageManifest.engines?.node, '>=20', `${packageName} Node.js engine`); + assert.equal( + packageManifest.engines?.node, + '^22.14.0 || >=23.6.0', + `${packageName} Node.js engine`, + ); assert.equal( packageManifest.repository?.url, 'https://github.com/joesobo/CodeGraphyV4.git', diff --git a/tests/release/releaseCore.test.mjs b/tests/release/releaseCore.test.mjs index 97172dcfbc..fa77837889 100644 --- a/tests/release/releaseCore.test.mjs +++ b/tests/release/releaseCore.test.mjs @@ -12,11 +12,11 @@ test('core extension release includes built-in Extension plugin icon assets', () ); assert.ok( - releaseCore.collectCoreReleaseEntries(rootManifest).includes('packages/plugin-unity/assets'), + releaseCore.collectCoreReleaseEntries(rootManifest).includes('packages/plugin-unity/assets/unity.svg'), 'Unity plugin icon assets must be staged so plugin legend and graph node image URLs resolve in packaged webviews.', ); assert.ok( - releaseCore.collectCoreReleaseEntries(rootManifest).includes('packages/plugin-godot/assets'), + releaseCore.collectCoreReleaseEntries(rootManifest).includes('packages/plugin-godot/assets/godot.svg'), 'Godot plugin icon assets must be staged so plugin legend and graph node image URLs resolve in packaged webviews.', ); }); @@ -27,23 +27,27 @@ test('core extension release includes every bundled plugin runtime and package d ); const entries = releaseCore.collectCoreReleaseEntries(rootManifest); - for (const plugin of [ - 'godot', - 'markdown', - 'particles', - 'svelte', - 'typescript', - 'unity', - 'vue', - ]) { + const runtimeFilesByPlugin = { + godot: ['plugin.js', 'extension.js'], + markdown: ['plugin.js'], + particles: ['plugin.js', 'webview.js'], + svelte: ['plugin.js'], + typescript: ['plugin.js'], + unity: ['plugin.js', 'extension.js'], + vue: ['plugin.js'], + }; + + for (const [plugin, runtimeFiles] of Object.entries(runtimeFilesByPlugin)) { assert.ok( entries.includes(`packages/plugin-${plugin}/package.json`), `${plugin} package manifest must be staged so the host-neutral loader can discover it.`, ); - assert.ok( - entries.includes(`packages/plugin-${plugin}/dist`), - `${plugin} runtime must be staged so packaged extensions can load it.`, - ); + for (const runtimeFile of runtimeFiles) { + assert.ok( + entries.includes(`packages/plugin-${plugin}/dist/${runtimeFile}`), + `${plugin} runtime must be staged so packaged extensions can load it.`, + ); + } } }); @@ -123,7 +127,7 @@ test('release preparation builds bundled workspace plugin packages before stagin JSON.stringify({ files: [ 'dist/**', - 'packages/plugin-example/dist/**', + 'packages/plugin-example/dist/plugin.js', ], }), ); diff --git a/tests/release/vsixNativeArtifacts.test.mjs b/tests/release/vsixNativeArtifacts.test.mjs index 9ec9bb449d..87f27ea88d 100644 --- a/tests/release/vsixNativeArtifacts.test.mjs +++ b/tests/release/vsixNativeArtifacts.test.mjs @@ -66,34 +66,95 @@ test('rejects a linux x64 VSIX with a macOS Apple Silicon Tree-sitter binding', assert.throws( () => validateVsixNativeArtifacts({ artifactsDir, version }), - /linux-x64\.vsix contains Mach-O arm64 at extension\/dist\/node_modules\/tree-sitter\/build\/Release\/tree_sitter_runtime_binding\.node; expected ELF x86-64\./, + /linux-x64\.vsix contains Mach-O arm64 at extension\/dist\/node_modules\/tree-sitter\/prebuilds\/linux-x64\/tree-sitter\.node; expected ELF x86-64\./, ); }); -test('validates only the requested VSIX artifact targets', () => { +test('validates target-specific plugin-local esbuild executables for every VSIX target', () => { const tempDir = mkdtempSync(path.join(tmpdir(), 'codegraphy-vsix-native-artifacts-target-')); const artifactsDir = path.join(tempDir, 'artifacts'); const version = '5.8.0'; + for (const target of ['linux-x64', 'darwin-arm64', 'win32-x64']) { + writeVsixFixture({ + artifactsDir, + version, + target, + sqliteBinary: nativeBinaryForTarget(target), + treeSitterBinary: nativeBinaryForTarget(target), + parcelWatcherBinary: nativeBinaryForTarget(target), + pluginEsbuildBinary: nativeBinaryForTarget(target), + }); + } + + assert.doesNotThrow( + () => validateVsixNativeArtifacts({ artifactsDir, version }), + ); +}); + +test('rejects a VSIX with the wrong plugin-local esbuild executable', () => { + const tempDir = mkdtempSync(path.join(tmpdir(), 'codegraphy-vsix-native-artifacts-esbuild-')); + const artifactsDir = path.join(tempDir, 'artifacts'); + const version = '5.8.0'; + writeVsixFixture({ artifactsDir, version, target: 'linux-x64', sqliteBinary: createElfX64Binary(), treeSitterBinary: createElfX64Binary(), + parcelWatcherBinary: createElfX64Binary(), + pluginEsbuildBinary: createMachOArm64Binary(), }); - assert.doesNotThrow( + assert.throws( () => validateVsixNativeArtifacts({ artifactsDir, version, targets: ['linux-x64'] }), + /plugin-particles\/dist\/node_modules\/@esbuild\/linux-x64\/bin\/esbuild; expected ELF x86-64\./, ); }); +test('rejects old root esbuild wrapper and native package paths', () => { + const version = '5.8.0'; + + for (const [oldRootEsbuildPath, forbiddenPrefix] of [ + [ + 'extension/dist/node_modules/esbuild/lib/main.js', + 'extension/dist/node_modules/esbuild/', + ], + [ + 'extension/dist/node_modules/@esbuild/linux-x64/bin/esbuild', + 'extension/dist/node_modules/@esbuild/linux-x64/', + ], + ]) { + const tempDir = mkdtempSync(path.join(tmpdir(), 'codegraphy-vsix-root-esbuild-')); + const artifactsDir = path.join(tempDir, 'artifacts'); + writeVsixFixture({ + artifactsDir, + version, + target: 'linux-x64', + sqliteBinary: createElfX64Binary(), + treeSitterBinary: createElfX64Binary(), + parcelWatcherBinary: createElfX64Binary(), + pluginEsbuildBinary: createElfX64Binary(), + oldRootEsbuildPath, + }); + + assert.throws( + () => validateVsixNativeArtifacts({ artifactsDir, version, targets: ['linux-x64'] }), + new RegExp(`must not contain old root esbuild path ${forbiddenPrefix}`), + ); + } +}); + function writeVsixFixture({ artifactsDir, version, target, sqliteBinary, treeSitterBinary, + parcelWatcherBinary, + pluginEsbuildBinary, + oldRootEsbuildPath, }) { const fixtureRoot = mkdtempSync(path.join(tmpdir(), `codegraphy-vsix-${target}-`)); writeFixtureBinary( @@ -103,9 +164,22 @@ function writeVsixFixture({ ); writeFixtureBinary( fixtureRoot, - 'extension/dist/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node', + treeSitterNativeBinaryPath(target), treeSitterBinary, ); + writeFixtureBinary( + fixtureRoot, + parcelWatcherNativeBinaryPath(target), + parcelWatcherBinary ?? nativeBinaryForTarget(target), + ); + writeFixtureBinary( + fixtureRoot, + pluginEsbuildNativeBinaryPath(target), + pluginEsbuildBinary ?? nativeBinaryForTarget(target), + ); + if (oldRootEsbuildPath) { + writeFixtureBinary(fixtureRoot, oldRootEsbuildPath, nativeBinaryForTarget(target)); + } mkdirSync(artifactsDir, { recursive: true }); const vsixPath = path.join(artifactsDir, `codegraphy.codegraphy-${version}-${target}.vsix`); @@ -128,6 +202,39 @@ function libsqlNativeBinaryPath(target) { return `extension/dist/node_modules/@libsql/${packageByTarget[target]}/index.node`; } +function treeSitterNativeBinaryPath(target) { + const prebuildByTarget = { + 'linux-x64': 'linux-x64', + 'darwin-arm64': 'darwin-arm64', + 'win32-x64': 'win32-x64', + }; + return `extension/dist/node_modules/tree-sitter/prebuilds/${prebuildByTarget[target]}/tree-sitter.node`; +} + +function parcelWatcherNativeBinaryPath(target) { + const packageByTarget = { + 'linux-x64': 'watcher-linux-x64-glibc', + 'darwin-arm64': 'watcher-darwin-arm64', + 'win32-x64': 'watcher-win32-x64', + }; + return `extension/dist/node_modules/@parcel/${packageByTarget[target]}/watcher.node`; +} + +function pluginEsbuildNativeBinaryPath(target) { + const executablePathByTarget = { + 'linux-x64': '@esbuild/linux-x64/bin/esbuild', + 'darwin-arm64': '@esbuild/darwin-arm64/bin/esbuild', + 'win32-x64': '@esbuild/win32-x64/esbuild.exe', + }; + return `extension/packages/plugin-particles/dist/node_modules/${executablePathByTarget[target]}`; +} + +function nativeBinaryForTarget(target) { + if (target === 'linux-x64') return createElfX64Binary(); + if (target === 'darwin-arm64') return createMachOArm64Binary(); + return createPe32PlusX64Binary(); +} + function writeFixtureBinary(rootDir, relativePath, binary) { const filePath = path.join(rootDir, relativePath); mkdirSync(path.dirname(filePath), { recursive: true });