@renxqoo/renx-code-darwin-arm64 0.0.59
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/README.md +35 -0
- package/bin/renx +0 -0
- package/bin/rg +79 -0
- package/package.json +27 -0
- package/scripts/install-ripgrep.mjs +195 -0
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @renxqoo/renx-code
|
|
2
|
+
|
|
3
|
+
Renx Code terminal AI coding assistant for the command line.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @renxqoo/renx-code
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
renx
|
|
15
|
+
renx --help
|
|
16
|
+
renx --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Supported Platforms
|
|
20
|
+
|
|
21
|
+
- macOS arm64
|
|
22
|
+
- macOS x64
|
|
23
|
+
- Linux arm64
|
|
24
|
+
- Linux x64
|
|
25
|
+
- Windows x64
|
|
26
|
+
|
|
27
|
+
Windows arm64 is not bundled yet because the current Bun compiler target matrix does not provide a native `bun-windows-arm64` executable target.
|
|
28
|
+
|
|
29
|
+
## Runtime Cache
|
|
30
|
+
|
|
31
|
+
The launcher copies installed native binaries into a user-scoped cache before execution. This keeps active Windows processes from locking files inside `node_modules` during upgrades.
|
|
32
|
+
|
|
33
|
+
- Default cache path on Windows: `%LOCALAPPDATA%\Renx\binary-cache`
|
|
34
|
+
- Override cache path: `RENX_BINARY_CACHE_DIR`
|
|
35
|
+
- Disable the cache for debugging: `RENX_DISABLE_BINARY_CACHE=1`
|
package/bin/renx
ADDED
|
Binary file
|
package/bin/rg
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env dotslash
|
|
2
|
+
|
|
3
|
+
{
|
|
4
|
+
"name": "rg",
|
|
5
|
+
"platforms": {
|
|
6
|
+
"macos-aarch64": {
|
|
7
|
+
"size": 1777930,
|
|
8
|
+
"hash": "sha256",
|
|
9
|
+
"digest": "378e973289176ca0c6054054ee7f631a065874a352bf43f0fa60ef079b6ba715",
|
|
10
|
+
"format": "tar.gz",
|
|
11
|
+
"path": "ripgrep-15.1.0-aarch64-apple-darwin/rg",
|
|
12
|
+
"providers": [
|
|
13
|
+
{
|
|
14
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-apple-darwin.tar.gz"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"linux-aarch64": {
|
|
19
|
+
"size": 1869959,
|
|
20
|
+
"hash": "sha256",
|
|
21
|
+
"digest": "2b661c6ef508e902f388e9098d9c4c5aca72c87b55922d94abdba830b4dc885e",
|
|
22
|
+
"format": "tar.gz",
|
|
23
|
+
"path": "ripgrep-15.1.0-aarch64-unknown-linux-gnu/rg",
|
|
24
|
+
"providers": [
|
|
25
|
+
{
|
|
26
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-unknown-linux-gnu.tar.gz"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"macos-x86_64": {
|
|
31
|
+
"size": 1894127,
|
|
32
|
+
"hash": "sha256",
|
|
33
|
+
"digest": "64811cb24e77cac3057d6c40b63ac9becf9082eedd54ca411b475b755d334882",
|
|
34
|
+
"format": "tar.gz",
|
|
35
|
+
"path": "ripgrep-15.1.0-x86_64-apple-darwin/rg",
|
|
36
|
+
"providers": [
|
|
37
|
+
{
|
|
38
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-apple-darwin.tar.gz"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"linux-x86_64": {
|
|
43
|
+
"size": 2263077,
|
|
44
|
+
"hash": "sha256",
|
|
45
|
+
"digest": "1c9297be4a084eea7ecaedf93eb03d058d6faae29bbc57ecdaf5063921491599",
|
|
46
|
+
"format": "tar.gz",
|
|
47
|
+
"path": "ripgrep-15.1.0-x86_64-unknown-linux-musl/rg",
|
|
48
|
+
"providers": [
|
|
49
|
+
{
|
|
50
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-unknown-linux-musl.tar.gz"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"windows-x86_64": {
|
|
55
|
+
"size": 1810687,
|
|
56
|
+
"hash": "sha256",
|
|
57
|
+
"digest": "124510b94b6baa3380d051fdf4650eaa80a302c876d611e9dba0b2e18d87493a",
|
|
58
|
+
"format": "zip",
|
|
59
|
+
"path": "ripgrep-15.1.0-x86_64-pc-windows-msvc/rg.exe",
|
|
60
|
+
"providers": [
|
|
61
|
+
{
|
|
62
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-pc-windows-msvc.zip"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"windows-aarch64": {
|
|
67
|
+
"size": 1675460,
|
|
68
|
+
"hash": "sha256",
|
|
69
|
+
"digest": "00d931fb5237c9696ca49308818edb76d8eb6fc132761cb2a1bd616b2df02f8e",
|
|
70
|
+
"format": "zip",
|
|
71
|
+
"path": "ripgrep-15.1.0-aarch64-pc-windows-msvc/rg.exe",
|
|
72
|
+
"providers": [
|
|
73
|
+
{
|
|
74
|
+
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-pc-windows-msvc.zip"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@renxqoo/renx-code-darwin-arm64",
|
|
3
|
+
"version": "0.0.59",
|
|
4
|
+
"description": "Renx Code terminal AI coding assistant (darwin-arm64)",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"private": false,
|
|
7
|
+
"os": [
|
|
8
|
+
"darwin"
|
|
9
|
+
],
|
|
10
|
+
"cpu": [
|
|
11
|
+
"arm64"
|
|
12
|
+
],
|
|
13
|
+
"bin": {
|
|
14
|
+
"renx": "./bin/renx"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin",
|
|
18
|
+
"scripts",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"postinstall": "node ./scripts/install-ripgrep.mjs"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { createWriteStream } from 'node:fs';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import https from 'node:https';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
15
|
+
const manifestPath = path.join(packageRoot, 'bin', 'rg');
|
|
16
|
+
|
|
17
|
+
const TARGETS = {
|
|
18
|
+
'darwin:arm64': { target: 'aarch64-apple-darwin', platformKey: 'macos-aarch64' },
|
|
19
|
+
'darwin:x64': { target: 'x86_64-apple-darwin', platformKey: 'macos-x86_64' },
|
|
20
|
+
'linux:arm64': { target: 'aarch64-unknown-linux-musl', platformKey: 'linux-aarch64' },
|
|
21
|
+
'linux:x64': { target: 'x86_64-unknown-linux-musl', platformKey: 'linux-x86_64' },
|
|
22
|
+
'win32:arm64': { target: 'aarch64-pc-windows-msvc', platformKey: 'windows-aarch64' },
|
|
23
|
+
'win32:x64': { target: 'x86_64-pc-windows-msvc', platformKey: 'windows-x86_64' },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
if (process.env.RENX_SKIP_RIPGREP_INSTALL === '1') {
|
|
28
|
+
console.log('[renx] skipping bundled ripgrep install (RENX_SKIP_RIPGREP_INSTALL=1)');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const targetInfo = TARGETS[`${process.platform}:${process.arch}`];
|
|
33
|
+
if (!targetInfo) {
|
|
34
|
+
console.warn(
|
|
35
|
+
`[renx] no bundled ripgrep target for ${process.platform}/${process.arch}; falling back to system rg if available`
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const manifest = await loadManifest(manifestPath);
|
|
41
|
+
const platformInfo = manifest.platforms?.[targetInfo.platformKey];
|
|
42
|
+
if (!platformInfo) {
|
|
43
|
+
throw new Error(`ripgrep manifest is missing platform ${targetInfo.platformKey}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const binaryName = process.platform === 'win32' ? 'rg.exe' : 'rg';
|
|
47
|
+
const installDir = path.join(packageRoot, 'vendor', 'ripgrep', targetInfo.target, 'path');
|
|
48
|
+
const binaryPath = path.join(installDir, binaryName);
|
|
49
|
+
if (await fileExists(binaryPath)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await fs.mkdir(installDir, { recursive: true });
|
|
54
|
+
|
|
55
|
+
const provider = platformInfo.providers?.[0];
|
|
56
|
+
const url = provider?.url;
|
|
57
|
+
if (!url) {
|
|
58
|
+
throw new Error(`ripgrep manifest has no provider URL for ${targetInfo.platformKey}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'renx-ripgrep-'));
|
|
62
|
+
try {
|
|
63
|
+
const archivePath = path.join(tempDir, path.basename(new URL(url).pathname));
|
|
64
|
+
console.log(`[renx] downloading ripgrep for ${targetInfo.target}`);
|
|
65
|
+
await downloadFile(url, archivePath);
|
|
66
|
+
await verifyArchive(archivePath, platformInfo);
|
|
67
|
+
|
|
68
|
+
const extractDir = path.join(tempDir, 'extract');
|
|
69
|
+
await fs.mkdir(extractDir, { recursive: true });
|
|
70
|
+
await extractArchive(archivePath, platformInfo.format, extractDir);
|
|
71
|
+
|
|
72
|
+
const memberPath = path.join(extractDir, platformInfo.path);
|
|
73
|
+
await fs.copyFile(memberPath, binaryPath);
|
|
74
|
+
if (process.platform !== 'win32') {
|
|
75
|
+
await fs.chmod(binaryPath, 0o755);
|
|
76
|
+
}
|
|
77
|
+
console.log(`[renx] installed bundled ripgrep to ${binaryPath}`);
|
|
78
|
+
} finally {
|
|
79
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function loadManifest(filePath) {
|
|
84
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
85
|
+
const json = raw.startsWith('#!') ? raw.split('\n').slice(1).join('\n') : raw;
|
|
86
|
+
return JSON.parse(json);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function fileExists(filePath) {
|
|
90
|
+
try {
|
|
91
|
+
await fs.access(filePath);
|
|
92
|
+
return true;
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function downloadFile(url, destination) {
|
|
99
|
+
await new Promise((resolve, reject) => {
|
|
100
|
+
const request = https.get(url, (response) => {
|
|
101
|
+
if (
|
|
102
|
+
response.statusCode &&
|
|
103
|
+
response.statusCode >= 300 &&
|
|
104
|
+
response.statusCode < 400 &&
|
|
105
|
+
response.headers.location
|
|
106
|
+
) {
|
|
107
|
+
response.resume();
|
|
108
|
+
downloadFile(response.headers.location, destination).then(resolve, reject);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (response.statusCode !== 200) {
|
|
113
|
+
reject(new Error(`download failed with status ${response.statusCode ?? 'unknown'}`));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const output = createWriteStream(destination);
|
|
118
|
+
response.pipe(output);
|
|
119
|
+
output.on('finish', () => {
|
|
120
|
+
output.close();
|
|
121
|
+
resolve(undefined);
|
|
122
|
+
});
|
|
123
|
+
output.on('error', reject);
|
|
124
|
+
});
|
|
125
|
+
request.on('error', reject);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function verifyArchive(archivePath, platformInfo) {
|
|
130
|
+
const stats = await fs.stat(archivePath);
|
|
131
|
+
if (typeof platformInfo.size === 'number' && stats.size !== platformInfo.size) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`unexpected ripgrep archive size: expected ${platformInfo.size}, got ${stats.size}`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (platformInfo.hash === 'sha256' && platformInfo.digest) {
|
|
138
|
+
const file = await fs.readFile(archivePath);
|
|
139
|
+
const digest = createHash('sha256').update(file).digest('hex');
|
|
140
|
+
if (digest !== platformInfo.digest) {
|
|
141
|
+
throw new Error('ripgrep archive sha256 digest mismatch');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function extractArchive(archivePath, format, destination) {
|
|
147
|
+
if (format === 'zip') {
|
|
148
|
+
const command = resolvePowerShellExecutable();
|
|
149
|
+
const result = spawnSync(
|
|
150
|
+
command,
|
|
151
|
+
[
|
|
152
|
+
'-NoProfile',
|
|
153
|
+
'-Command',
|
|
154
|
+
`Expand-Archive -LiteralPath '${escapePowerShell(archivePath)}' -DestinationPath '${escapePowerShell(destination)}' -Force`,
|
|
155
|
+
],
|
|
156
|
+
{
|
|
157
|
+
stdio: 'inherit',
|
|
158
|
+
windowsHide: true,
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
if (result.error || result.status !== 0) {
|
|
162
|
+
throw new Error('failed to extract ripgrep zip archive');
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (format === 'tar.gz') {
|
|
168
|
+
const result = spawnSync('tar', ['-xzf', archivePath, '-C', destination], {
|
|
169
|
+
stdio: 'inherit',
|
|
170
|
+
windowsHide: true,
|
|
171
|
+
});
|
|
172
|
+
if (result.error || result.status !== 0) {
|
|
173
|
+
throw new Error('failed to extract ripgrep tar.gz archive');
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
throw new Error(`unsupported ripgrep archive format: ${format}`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function resolvePowerShellExecutable() {
|
|
182
|
+
return process.env.SystemRoot
|
|
183
|
+
? path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe')
|
|
184
|
+
: 'powershell.exe';
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function escapePowerShell(value) {
|
|
188
|
+
return value.replace(/'/g, "''");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
main().catch((error) => {
|
|
192
|
+
console.warn(
|
|
193
|
+
`[renx] bundled ripgrep install skipped: ${error instanceof Error ? error.message : String(error)}`
|
|
194
|
+
);
|
|
195
|
+
});
|