openvegas 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/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # openvegas
2
+
3
+ `openvegas` is a thin npm wrapper around the OpenVegas CLI binary.
4
+
5
+ On install, the package downloads the correct prebuilt binary for your platform from GitHub Releases, verifies its SHA256 checksum, and stores it under `~/.openvegas/bin/<version>/`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g openvegas
11
+ ```
12
+
13
+ ## Supported Platforms
14
+
15
+ - `linux-x64`
16
+ - `darwin-arm64`
17
+ - `win-x64`
18
+
19
+ Intel macOS is not currently shipped as a native binary. Use Rosetta or install from source if needed.
20
+
21
+ ## Upgrade
22
+
23
+ ```bash
24
+ openvegas --upgrade
25
+ ```
26
+
27
+ ## How It Works
28
+
29
+ - npm installs this package
30
+ - the `postinstall` hook downloads the matching binary from GitHub Releases
31
+ - the wrapper verifies the checksum before marking the binary ready
32
+ - future CLI invocations execute the cached binary
33
+
34
+ ## Releases
35
+
36
+ This package is version-matched with the GitHub Release tag. For example, npm package version `0.1.1` expects binary assets under GitHub tag `v0.1.1`.
37
+
38
+ Project repo:
39
+
40
+ - https://github.com/jar0ch0/OpenVegasDeployed
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { execFileSync } = require('node:child_process');
5
+ const fs = require('node:fs');
6
+ const os = require('node:os');
7
+ const path = require('node:path');
8
+
9
+ const pkg = require('../package.json');
10
+ const { downloadBinary } = require('../lib/download.js');
11
+
12
+ // ── Platform detection ──────────────────────────────────────────────────────
13
+
14
+ const PLATFORM_MAP = {
15
+ darwin: 'darwin',
16
+ linux: 'linux',
17
+ win32: 'win',
18
+ };
19
+
20
+ const ARCH_MAP = {
21
+ arm64: 'arm64',
22
+ x64: 'x64',
23
+ };
24
+
25
+ function getTarget() {
26
+ const platform = PLATFORM_MAP[process.platform];
27
+ const arch = ARCH_MAP[process.arch];
28
+ if (!platform || !arch) {
29
+ console.error(
30
+ `[openvegas] Unsupported platform: ${process.platform}/${process.arch}\n` +
31
+ `Supported: linux/x64, darwin/arm64 (Intel Macs: use Rosetta 2), win32/x64\n\n` +
32
+ `To install manually:\n` +
33
+ ` https://github.com/jar0ch0/OpenVegasDeployed/releases`,
34
+ );
35
+ process.exit(1);
36
+ }
37
+ return `${platform}-${arch}`;
38
+ }
39
+
40
+ // ── Cache paths ─────────────────────────────────────────────────────────────
41
+
42
+ function getCacheDir(version) {
43
+ return path.join(os.homedir(), '.openvegas', 'bin', version);
44
+ }
45
+
46
+ function getBinaryPath(version, target) {
47
+ const ext = process.platform === 'win32' ? '.exe' : '';
48
+ return path.join(getCacheDir(version), `openvegas-${target}${ext}`);
49
+ }
50
+
51
+ // ── Old-version cleanup ─────────────────────────────────────────────────────
52
+
53
+ function cleanOldVersions(currentVersion) {
54
+ const binRoot = path.join(os.homedir(), '.openvegas', 'bin');
55
+ if (!fs.existsSync(binRoot)) return;
56
+ for (const entry of fs.readdirSync(binRoot)) {
57
+ if (entry !== currentVersion) {
58
+ const dir = path.join(binRoot, entry);
59
+ try {
60
+ fs.rmSync(dir, { recursive: true, force: true });
61
+ } catch {
62
+ // best-effort
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ // ── Main ────────────────────────────────────────────────────────────────────
69
+
70
+ async function main() {
71
+ const args = process.argv.slice(2);
72
+ const isInstallHook = args.includes('--_install');
73
+ const isUpgrade = args.includes('--upgrade');
74
+ const version = pkg.version;
75
+ const target = getTarget();
76
+ const binaryPath = getBinaryPath(version, target);
77
+
78
+ const needsDownload = isInstallHook || isUpgrade || !fs.existsSync(binaryPath);
79
+
80
+ if (needsDownload) {
81
+ const cacheDir = getCacheDir(version);
82
+ fs.mkdirSync(cacheDir, { recursive: true });
83
+
84
+ try {
85
+ await downloadBinary(version, target, cacheDir);
86
+ cleanOldVersions(version);
87
+ } catch (err) {
88
+ console.error(`\n[openvegas] Download failed: ${err.message}`);
89
+ console.error(
90
+ `\nManual install:\n` +
91
+ ` https://github.com/jar0ch0/OpenVegasDeployed/releases/tag/v${version}`,
92
+ );
93
+ process.exit(1);
94
+ }
95
+ }
96
+
97
+ // postinstall hook — don't exec the binary, just exit after download
98
+ if (isInstallHook) {
99
+ process.exit(0);
100
+ }
101
+
102
+ // Forward all args to the cached binary
103
+ const forwardArgs = args.filter(a => a !== '--upgrade');
104
+ try {
105
+ execFileSync(binaryPath, forwardArgs, { stdio: 'inherit' });
106
+ process.exit(0);
107
+ } catch (err) {
108
+ process.exit(typeof err.status === 'number' ? err.status : 1);
109
+ }
110
+ }
111
+
112
+ main().catch(err => {
113
+ console.error(`[openvegas] Unexpected error: ${err.message}`);
114
+ process.exit(1);
115
+ });
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('node:crypto');
4
+ const fs = require('node:fs');
5
+ const https = require('node:https');
6
+ const path = require('node:path');
7
+
8
+ const GITHUB_BASE = 'https://github.com/jar0ch0/OpenVegasDeployed/releases/download';
9
+
10
+ // ── HTTP download with redirect following ───────────────────────────────────
11
+
12
+ function downloadFile(url, destPath) {
13
+ return new Promise((resolve, reject) => {
14
+ const attempt = (currentUrl, redirectsLeft) => {
15
+ https.get(currentUrl, res => {
16
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
17
+ if (redirectsLeft <= 0) {
18
+ return reject(new Error('Too many redirects'));
19
+ }
20
+ res.resume();
21
+ return attempt(res.headers.location, redirectsLeft - 1);
22
+ }
23
+ if (res.statusCode !== 200) {
24
+ res.resume();
25
+ return reject(new Error(`HTTP ${res.statusCode} fetching ${currentUrl}`));
26
+ }
27
+
28
+ const total = parseInt(res.headers['content-length'] || '0', 10);
29
+ let received = 0;
30
+ let lastPct = -1;
31
+
32
+ const dest = fs.createWriteStream(destPath);
33
+ res.on('data', chunk => {
34
+ received += chunk.length;
35
+ if (total > 0) {
36
+ const pct = Math.floor((received / total) * 100);
37
+ if (pct !== lastPct && pct % 10 === 0) {
38
+ process.stderr.write(`\r ${pct}%`);
39
+ lastPct = pct;
40
+ }
41
+ }
42
+ });
43
+ res.pipe(dest);
44
+ dest.on('finish', () => {
45
+ if (total > 0) process.stderr.write('\r 100%\n');
46
+ resolve();
47
+ });
48
+ dest.on('error', reject);
49
+ res.on('error', reject);
50
+ }).on('error', reject);
51
+ };
52
+
53
+ attempt(url, 10);
54
+ });
55
+ }
56
+
57
+ // ── SHA256 verification ─────────────────────────────────────────────────────
58
+
59
+ function computeSha256(filePath) {
60
+ return new Promise((resolve, reject) => {
61
+ const hash = crypto.createHash('sha256');
62
+ const stream = fs.createReadStream(filePath);
63
+ stream.on('data', chunk => hash.update(chunk));
64
+ stream.on('end', () => resolve(hash.digest('hex')));
65
+ stream.on('error', reject);
66
+ });
67
+ }
68
+
69
+ async function verifySha256(filePath, checksumFilePath) {
70
+ const raw = fs.readFileSync(checksumFilePath, 'utf8').trim();
71
+ // Format: "<hash> <filename>" or "<hash> <filename>" or just "<hash>"
72
+ const expected = raw.split(/\s+/)[0].toLowerCase();
73
+ const actual = await computeSha256(filePath);
74
+ if (actual !== expected) {
75
+ throw new Error(
76
+ `SHA256 mismatch for ${path.basename(filePath)}\n` +
77
+ ` expected: ${expected}\n` +
78
+ ` actual: ${actual}`,
79
+ );
80
+ }
81
+ }
82
+
83
+ // ── Main export ─────────────────────────────────────────────────────────────
84
+
85
+ async function downloadBinary(version, target, cacheDir) {
86
+ const ext = process.platform === 'win32' ? '.exe' : '';
87
+ const binaryName = `openvegas-${target}${ext}`;
88
+ const checksumName = `${binaryName}.sha256`;
89
+
90
+ const binaryUrl = `${GITHUB_BASE}/v${version}/${binaryName}`;
91
+ const checksumUrl = `${GITHUB_BASE}/v${version}/${checksumName}`;
92
+
93
+ const binaryDest = path.join(cacheDir, binaryName);
94
+ const checksumDest = path.join(cacheDir, checksumName);
95
+
96
+ const RETRIES = 2;
97
+ let lastErr;
98
+
99
+ for (let attempt = 0; attempt <= RETRIES; attempt++) {
100
+ if (attempt > 0) {
101
+ const wait = attempt * 1000;
102
+ process.stderr.write(`[openvegas] Retrying in ${wait / 1000}s...\n`);
103
+ await new Promise(r => setTimeout(r, wait));
104
+ }
105
+ try {
106
+ process.stderr.write(`[openvegas] Downloading ${binaryName} (v${version})...\n`);
107
+ await downloadFile(binaryUrl, binaryDest);
108
+
109
+ process.stderr.write(`[openvegas] Downloading checksum...\n`);
110
+ await downloadFile(checksumUrl, checksumDest);
111
+
112
+ process.stderr.write(`[openvegas] Verifying checksum...\n`);
113
+ await verifySha256(binaryDest, checksumDest);
114
+
115
+ if (process.platform !== 'win32') {
116
+ fs.chmodSync(binaryDest, 0o755);
117
+ }
118
+
119
+ process.stderr.write(`[openvegas] Ready.\n`);
120
+ return;
121
+ } catch (err) {
122
+ lastErr = err;
123
+ // Clean up partial files before retry
124
+ for (const f of [binaryDest, checksumDest]) {
125
+ try { fs.unlinkSync(f); } catch { /* ignore */ }
126
+ }
127
+ }
128
+ }
129
+
130
+ throw lastErr;
131
+ }
132
+
133
+ module.exports = { downloadBinary };
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "openvegas",
3
+ "version": "0.1.1",
4
+ "description": "OpenVegas CLI — Terminal Arcade for Developers",
5
+ "keywords": [
6
+ "ai",
7
+ "cli",
8
+ "developer-tools",
9
+ "openvegas",
10
+ "terminal"
11
+ ],
12
+ "type": "commonjs",
13
+ "bin": {
14
+ "openvegas": "bin/openvegas.js"
15
+ },
16
+ "scripts": {
17
+ "postinstall": "node bin/openvegas.js --_install"
18
+ },
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "files": [
23
+ "bin/",
24
+ "lib/"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/jar0ch0/OpenVegasDeployed.git"
29
+ },
30
+ "homepage": "https://github.com/jar0ch0/OpenVegasDeployed#readme",
31
+ "bugs": {
32
+ "url": "https://github.com/jar0ch0/OpenVegasDeployed/issues"
33
+ },
34
+ "license": "MIT"
35
+ }