@kumos/tree-sitter-parsers 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/bin/tree-sitter-parsers-path.js +10 -0
- package/index.js +128 -0
- package/package.json +54 -0
- package/postinstall.js +166 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ivan Porto Carrero
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Breeze Tree-sitter Parsers
|
|
2
|
+
|
|
3
|
+
Pre-compiled Tree-sitter parsers for 163 programming languages, distributed as native binaries via npm.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kumos/tree-sitter-parsers
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The appropriate binary for your platform will be automatically downloaded during installation.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Get the binary path
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
const { binaryPath, metadataPath } = require('@kumos/tree-sitter-parsers');
|
|
19
|
+
|
|
20
|
+
console.log(binaryPath); // Path to the static library
|
|
21
|
+
console.log(metadataPath); // Path to the grammars metadata JSON
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Command-line usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Get the path to the binary
|
|
28
|
+
npx tree-sitter-parsers-path
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Build tools integration
|
|
32
|
+
|
|
33
|
+
The binary path can be used in build scripts:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# In a build script
|
|
37
|
+
PARSER_LIB=$(npx tree-sitter-parsers-path)
|
|
38
|
+
gcc myapp.c $PARSER_LIB -o myapp
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Supported Platforms
|
|
42
|
+
|
|
43
|
+
- Linux x64 (glibc and musl)
|
|
44
|
+
- Linux ARM64 (glibc and musl)
|
|
45
|
+
- macOS x64
|
|
46
|
+
- macOS ARM64
|
|
47
|
+
- Windows x64
|
|
48
|
+
- Windows ARM64
|
|
49
|
+
|
|
50
|
+
## Building from Source
|
|
51
|
+
|
|
52
|
+
### Prerequisites
|
|
53
|
+
|
|
54
|
+
- Node.js 20+
|
|
55
|
+
- Git
|
|
56
|
+
- Zig (for cross-compilation)
|
|
57
|
+
- C/C++ compiler (for native builds)
|
|
58
|
+
|
|
59
|
+
### Build Commands
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Clone the repository
|
|
63
|
+
git clone https://github.com/casualjim/breeze-tree-sitter-parsers.git
|
|
64
|
+
cd breeze-tree-sitter-parsers
|
|
65
|
+
|
|
66
|
+
# Fetch all grammar repositories
|
|
67
|
+
npm run fetch
|
|
68
|
+
|
|
69
|
+
# Build for current platform
|
|
70
|
+
npm run build
|
|
71
|
+
|
|
72
|
+
# Build for all platforms (requires Zig)
|
|
73
|
+
npm run build:all
|
|
74
|
+
|
|
75
|
+
# Create npm packages for distribution
|
|
76
|
+
npm run create-packages
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Architecture
|
|
80
|
+
|
|
81
|
+
This project consists of:
|
|
82
|
+
|
|
83
|
+
1. **Main package** (`@kumos/tree-sitter-parsers`) - Platform detection and binary resolution
|
|
84
|
+
2. **Platform packages** - Platform-specific binaries (e.g., `@kumos/tree-sitter-parsers-darwin-arm64`)
|
|
85
|
+
|
|
86
|
+
The main package uses npm's `optionalDependencies` to install only the relevant platform binary. If the platform package isn't available, it falls back to downloading the binary from GitHub releases.
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
function getPlatformPackage() {
|
|
6
|
+
const platform = os.platform();
|
|
7
|
+
const arch = os.arch();
|
|
8
|
+
|
|
9
|
+
let platformPackage;
|
|
10
|
+
|
|
11
|
+
switch (platform) {
|
|
12
|
+
case 'darwin':
|
|
13
|
+
platformPackage = `@kumos/tree-sitter-parsers-darwin-${arch === 'arm64' ? 'arm64' : 'x64'}`;
|
|
14
|
+
break;
|
|
15
|
+
case 'linux':
|
|
16
|
+
// Check if using musl libc (Alpine Linux, etc.)
|
|
17
|
+
const isMusl = (() => {
|
|
18
|
+
try {
|
|
19
|
+
// First try ldd
|
|
20
|
+
const lddOutput = require('child_process').execSync('ldd --version 2>&1', { encoding: 'utf8' });
|
|
21
|
+
if (lddOutput.includes('musl')) return true;
|
|
22
|
+
} catch {
|
|
23
|
+
// ldd might not exist or fail
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check if /lib/ld-musl* exists (Alpine/musl systems)
|
|
27
|
+
try {
|
|
28
|
+
const files = fs.readdirSync('/lib');
|
|
29
|
+
return files.some(f => f.startsWith('ld-musl'));
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
|
|
35
|
+
const archSuffix = arch === 'arm64' ? 'arm64' : 'x64';
|
|
36
|
+
platformPackage = `@kumos/tree-sitter-parsers-linux-${archSuffix}${isMusl ? '-musl' : ''}`;
|
|
37
|
+
break;
|
|
38
|
+
case 'win32':
|
|
39
|
+
platformPackage = `@kumos/tree-sitter-parsers-win32-${arch === 'arm64' ? 'arm64' : 'x64'}`;
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
throw new Error(`Unsupported platform: ${platform} ${arch}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return platformPackage;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getBinaryPath() {
|
|
49
|
+
const platformPackage = getPlatformPackage();
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
// Try to resolve the platform-specific package
|
|
53
|
+
const packagePath = require.resolve(platformPackage);
|
|
54
|
+
const packageDir = path.dirname(packagePath);
|
|
55
|
+
|
|
56
|
+
// Map platform to expected binary filename
|
|
57
|
+
const platform = os.platform();
|
|
58
|
+
const arch = os.arch();
|
|
59
|
+
let binaryName;
|
|
60
|
+
|
|
61
|
+
switch (platform) {
|
|
62
|
+
case 'darwin':
|
|
63
|
+
binaryName = `libtree-sitter-parsers-all-macos-${arch === 'arm64' ? 'aarch64' : 'x86_64'}.a`;
|
|
64
|
+
break;
|
|
65
|
+
case 'linux':
|
|
66
|
+
const isMusl = platformPackage.includes('musl');
|
|
67
|
+
const archName = arch === 'arm64' ? 'aarch64' : 'x86_64';
|
|
68
|
+
binaryName = `libtree-sitter-parsers-all-linux-${archName}-${isMusl ? 'musl' : 'glibc'}.a`;
|
|
69
|
+
break;
|
|
70
|
+
case 'win32':
|
|
71
|
+
binaryName = `libtree-sitter-parsers-all-windows-${arch === 'arm64' ? 'aarch64' : 'x86_64'}.a`;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const binaryPath = path.join(packageDir, binaryName);
|
|
76
|
+
|
|
77
|
+
if (fs.existsSync(binaryPath)) {
|
|
78
|
+
return binaryPath;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Fallback to downloaded binary location
|
|
82
|
+
const fallbackPath = path.join(__dirname, 'binaries', binaryName);
|
|
83
|
+
if (fs.existsSync(fallbackPath)) {
|
|
84
|
+
return fallbackPath;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
throw new Error(`Binary not found at ${binaryPath} or ${fallbackPath}`);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
// Platform package not installed, check fallback location
|
|
90
|
+
const fallbackDir = path.join(__dirname, 'binaries');
|
|
91
|
+
if (fs.existsSync(fallbackDir)) {
|
|
92
|
+
const files = fs.readdirSync(fallbackDir);
|
|
93
|
+
const binary = files.find(f => f.endsWith('.a'));
|
|
94
|
+
if (binary) {
|
|
95
|
+
return path.join(fallbackDir, binary);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw new Error(`Could not find tree-sitter parsers binary. Platform package ${platformPackage} not installed and no fallback binary found.`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getMetadataPath() {
|
|
104
|
+
const binaryPath = getBinaryPath();
|
|
105
|
+
const dir = path.dirname(binaryPath);
|
|
106
|
+
const binaryName = path.basename(binaryPath, '.a');
|
|
107
|
+
const metadataName = binaryName.replace('libtree-sitter-parsers-all-', 'grammars-') + '.json';
|
|
108
|
+
return path.join(dir, metadataName);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const binaryPath = getBinaryPath();
|
|
112
|
+
const metadataPath = getMetadataPath();
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
binaryPath,
|
|
116
|
+
metadataPath,
|
|
117
|
+
platformPackage: getPlatformPackage(),
|
|
118
|
+
|
|
119
|
+
// Utility function to get all available grammars
|
|
120
|
+
getGrammars() {
|
|
121
|
+
try {
|
|
122
|
+
return JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error('Failed to load grammars metadata:', error);
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "",
|
|
3
|
+
"bin": {
|
|
4
|
+
"tree-sitter-parsers-path": "./bin/tree-sitter-parsers-path.js"
|
|
5
|
+
},
|
|
6
|
+
"description": "Pre-compiled Tree-sitter parsers for 163 programming languages",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"tree-sitter-cli": "^0.25.6"
|
|
9
|
+
},
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=20.0.0"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"index.js",
|
|
15
|
+
"postinstall.js",
|
|
16
|
+
"bin/"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"tree-sitter",
|
|
20
|
+
"parser",
|
|
21
|
+
"syntax",
|
|
22
|
+
"ast"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"main": "index.js",
|
|
26
|
+
"name": "@kumos/tree-sitter-parsers",
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"@kumos/tree-sitter-parsers-darwin-arm64": "0.1.1",
|
|
29
|
+
"@kumos/tree-sitter-parsers-darwin-x64": "0.1.1",
|
|
30
|
+
"@kumos/tree-sitter-parsers-linux-arm64": "0.1.1",
|
|
31
|
+
"@kumos/tree-sitter-parsers-linux-arm64-musl": "0.1.1",
|
|
32
|
+
"@kumos/tree-sitter-parsers-linux-x64": "0.1.1",
|
|
33
|
+
"@kumos/tree-sitter-parsers-linux-x64-musl": "0.1.1",
|
|
34
|
+
"@kumos/tree-sitter-parsers-win32-arm64": "0.1.1",
|
|
35
|
+
"@kumos/tree-sitter-parsers-win32-x64": "0.1.1"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/casualjim/breeze-tree-sitter-parsers.git"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "node build-grammars.js",
|
|
43
|
+
"build:all": "node build-grammars.js --all-platforms",
|
|
44
|
+
"compile": "node build-grammars.js --compile-only",
|
|
45
|
+
"create-packages": "node create-platform-packages.js",
|
|
46
|
+
"fetch": "node build-grammars.js --fetch-only",
|
|
47
|
+
"postinstall": "node postinstall.js",
|
|
48
|
+
"publish-all": "bash publish-packages.sh",
|
|
49
|
+
"test-distribution": "node test-distribution.js",
|
|
50
|
+
"test-distribution:arm64": "node test-distribution.js --arch arm64",
|
|
51
|
+
"test-distribution:x64": "node test-distribution.js --arch x64"
|
|
52
|
+
},
|
|
53
|
+
"version": "0.1.1"
|
|
54
|
+
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const { promisify } = require('util');
|
|
8
|
+
const pipeline = promisify(require('stream').pipeline);
|
|
9
|
+
|
|
10
|
+
// Configuration
|
|
11
|
+
const REPO_OWNER = 'casualjim';
|
|
12
|
+
const REPO_NAME = 'breeze-tree-sitter-parsers';
|
|
13
|
+
const VERSION = require('./package.json').version;
|
|
14
|
+
|
|
15
|
+
async function downloadFile(url, destination) {
|
|
16
|
+
const dir = path.dirname(destination);
|
|
17
|
+
if (!fs.existsSync(dir)) {
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
https.get(url, { headers: { 'User-Agent': 'breeze-tree-sitter-parsers' } }, (response) => {
|
|
23
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
24
|
+
// Follow redirect
|
|
25
|
+
downloadFile(response.headers.location, destination).then(resolve).catch(reject);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (response.statusCode !== 200) {
|
|
30
|
+
reject(new Error(`Failed to download: ${response.statusCode}`));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const file = fs.createWriteStream(destination);
|
|
35
|
+
pipeline(response, file)
|
|
36
|
+
.then(() => resolve())
|
|
37
|
+
.catch(reject);
|
|
38
|
+
}).on('error', reject);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getPlatformBinaryName() {
|
|
43
|
+
const platform = os.platform();
|
|
44
|
+
const arch = os.arch();
|
|
45
|
+
|
|
46
|
+
switch (platform) {
|
|
47
|
+
case 'darwin':
|
|
48
|
+
return `libtree-sitter-parsers-all-macos-${arch === 'arm64' ? 'aarch64' : 'x86_64'}.a`;
|
|
49
|
+
case 'linux':
|
|
50
|
+
// Try to detect musl
|
|
51
|
+
const isMusl = (() => {
|
|
52
|
+
try {
|
|
53
|
+
// First try ldd
|
|
54
|
+
const lddOutput = require('child_process').execSync('ldd --version 2>&1', { encoding: 'utf8' });
|
|
55
|
+
if (lddOutput.includes('musl')) return true;
|
|
56
|
+
} catch {
|
|
57
|
+
// ldd might not exist or fail
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check if /lib/ld-musl* exists (Alpine/musl systems)
|
|
61
|
+
try {
|
|
62
|
+
const fs = require('fs');
|
|
63
|
+
const files = fs.readdirSync('/lib');
|
|
64
|
+
return files.some(f => f.startsWith('ld-musl'));
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
|
|
70
|
+
const archName = arch === 'arm64' ? 'aarch64' : 'x86_64';
|
|
71
|
+
return `libtree-sitter-parsers-all-linux-${archName}-${isMusl ? 'musl' : 'glibc'}.a`;
|
|
72
|
+
case 'win32':
|
|
73
|
+
return `libtree-sitter-parsers-all-windows-${arch === 'arm64' ? 'aarch64' : 'x86_64'}.a`;
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Unsupported platform: ${platform} ${arch}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function getMetadataFileName() {
|
|
80
|
+
const binaryName = getPlatformBinaryName();
|
|
81
|
+
return binaryName.replace('libtree-sitter-parsers-all-', 'grammars-').replace('.a', '.json');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function checkOptionalDependency() {
|
|
85
|
+
try {
|
|
86
|
+
// Simply try to load the main module - if it works, we have what we need
|
|
87
|
+
const { binaryPath, metadataPath } = require('./index.js');
|
|
88
|
+
|
|
89
|
+
// Verify the files actually exist
|
|
90
|
+
if (fs.existsSync(binaryPath) && fs.existsSync(metadataPath)) {
|
|
91
|
+
console.log('Tree-sitter parsers binary found.');
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
console.log(`Binary not found at: ${binaryPath}`);
|
|
95
|
+
console.log(`Metadata not found at: ${metadataPath}`);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
// Binary not found via normal package installation
|
|
98
|
+
console.log('Error loading index.js:', error.message);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log('Binary not found in platform package, will use fallback download.');
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function downloadBinaries() {
|
|
106
|
+
const binaryName = getPlatformBinaryName();
|
|
107
|
+
const metadataName = getMetadataFileName();
|
|
108
|
+
const binariesDir = path.join(__dirname, 'binaries');
|
|
109
|
+
|
|
110
|
+
const binaryPath = path.join(binariesDir, binaryName);
|
|
111
|
+
const metadataPath = path.join(binariesDir, metadataName);
|
|
112
|
+
|
|
113
|
+
// Check if already downloaded
|
|
114
|
+
if (fs.existsSync(binaryPath) && fs.existsSync(metadataPath)) {
|
|
115
|
+
console.log('Binaries already downloaded.');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(`Downloading tree-sitter parsers for your platform...`);
|
|
120
|
+
|
|
121
|
+
// Construct download URLs
|
|
122
|
+
const releaseUrl = `https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/v${VERSION}`;
|
|
123
|
+
const binaryUrl = `${releaseUrl}/${binaryName}`;
|
|
124
|
+
const metadataUrl = `${releaseUrl}/${metadataName}`;
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// Download both files
|
|
128
|
+
console.log(`Downloading ${binaryName}...`);
|
|
129
|
+
await downloadFile(binaryUrl, binaryPath);
|
|
130
|
+
|
|
131
|
+
console.log(`Downloading ${metadataName}...`);
|
|
132
|
+
await downloadFile(metadataUrl, metadataPath);
|
|
133
|
+
|
|
134
|
+
console.log('Download complete!');
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('Failed to download binaries:', error.message);
|
|
137
|
+
console.error('You may need to manually download the binaries from:');
|
|
138
|
+
console.error(` ${binaryUrl}`);
|
|
139
|
+
console.error(` ${metadataUrl}`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function main() {
|
|
145
|
+
// Skip in CI environments or when explicitly disabled
|
|
146
|
+
if (process.env.CI || process.env.BREEZE_SKIP_DOWNLOAD) {
|
|
147
|
+
console.log('Skipping postinstall download.');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check if optional dependency was installed
|
|
152
|
+
const hasOptionalDep = await checkOptionalDependency();
|
|
153
|
+
|
|
154
|
+
if (!hasOptionalDep) {
|
|
155
|
+
console.log('Downloading tree-sitter parsers for your platform...');
|
|
156
|
+
await downloadBinaries();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Only run if called directly
|
|
161
|
+
if (require.main === module) {
|
|
162
|
+
main().catch(error => {
|
|
163
|
+
console.error('Postinstall failed:', error);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
});
|
|
166
|
+
}
|