@glock-org/glock 1.0.0
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/bin/glock.js +79 -0
- package/lib/platform.js +234 -0
- package/package.json +27 -0
- package/scripts/postinstall.js +148 -0
package/bin/glock.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Glock CLI launcher
|
|
5
|
+
*
|
|
6
|
+
* This script launches the platform-appropriate Glock binary.
|
|
7
|
+
* The binary is downloaded during npm postinstall.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { spawn } = require('child_process');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
|
|
15
|
+
const platform = os.platform();
|
|
16
|
+
const arch = os.arch();
|
|
17
|
+
|
|
18
|
+
// Map Node.js arch names to our binary names
|
|
19
|
+
const archMap = {
|
|
20
|
+
'x64': 'x64',
|
|
21
|
+
'arm64': 'arm64',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const platformMap = {
|
|
25
|
+
'darwin': 'darwin',
|
|
26
|
+
'linux': 'linux',
|
|
27
|
+
'win32': 'win32',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const mappedPlatform = platformMap[platform];
|
|
31
|
+
const mappedArch = archMap[arch];
|
|
32
|
+
|
|
33
|
+
if (!mappedPlatform || !mappedArch) {
|
|
34
|
+
console.error(`Unsupported platform: ${platform}-${arch}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const binaryName = platform === 'win32' ? 'glock.exe' : 'glock';
|
|
39
|
+
const binaryDir = path.join(__dirname, '..', 'bin', `glock-${mappedPlatform}-${mappedArch}`);
|
|
40
|
+
const binaryPath = path.join(binaryDir, binaryName);
|
|
41
|
+
|
|
42
|
+
// Check if binary exists
|
|
43
|
+
if (!fs.existsSync(binaryPath)) {
|
|
44
|
+
console.error('Glock binary not found. Please reinstall the package.');
|
|
45
|
+
console.error(`Expected binary at: ${binaryPath}`);
|
|
46
|
+
console.error('');
|
|
47
|
+
console.error('Try running: npm install -g glock/glock');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Spawn the binary with all arguments
|
|
52
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
53
|
+
stdio: 'inherit',
|
|
54
|
+
env: {
|
|
55
|
+
...process.env,
|
|
56
|
+
GLOCK_NPM_INSTALL: '1',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
child.on('error', (err) => {
|
|
61
|
+
console.error(`Failed to start Glock: ${err.message}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
child.on('exit', (code, signal) => {
|
|
66
|
+
if (signal) {
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
process.exit(code || 0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Handle signals
|
|
73
|
+
process.on('SIGINT', () => {
|
|
74
|
+
child.kill('SIGINT');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
process.on('SIGTERM', () => {
|
|
78
|
+
child.kill('SIGTERM');
|
|
79
|
+
});
|
package/lib/platform.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform detection for Glock CLI binary downloads.
|
|
3
|
+
*
|
|
4
|
+
* Determines the correct binary to download based on:
|
|
5
|
+
* - Operating system (darwin, linux, win32)
|
|
6
|
+
* - Architecture (x64, arm64)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Supported platforms and architectures
|
|
14
|
+
*/
|
|
15
|
+
const SUPPORTED_PLATFORMS = {
|
|
16
|
+
darwin: ['x64', 'arm64'],
|
|
17
|
+
linux: ['x64', 'arm64'],
|
|
18
|
+
win32: ['x64'],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Binary file names by platform
|
|
23
|
+
*/
|
|
24
|
+
const BINARY_NAMES = {
|
|
25
|
+
darwin: 'glock',
|
|
26
|
+
linux: 'glock',
|
|
27
|
+
win32: 'glock.exe',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the current platform identifier
|
|
32
|
+
* @returns {string} Platform identifier (e.g., 'darwin-arm64')
|
|
33
|
+
*/
|
|
34
|
+
function getPlatformId() {
|
|
35
|
+
const platform = os.platform();
|
|
36
|
+
const arch = os.arch();
|
|
37
|
+
return `${platform}-${arch}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if the current platform is supported
|
|
42
|
+
* @returns {boolean} True if supported
|
|
43
|
+
*/
|
|
44
|
+
function isPlatformSupported() {
|
|
45
|
+
const platform = os.platform();
|
|
46
|
+
const arch = os.arch();
|
|
47
|
+
|
|
48
|
+
const supportedArchs = SUPPORTED_PLATFORMS[platform];
|
|
49
|
+
if (!supportedArchs) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return supportedArchs.includes(arch);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get the binary name for the current platform
|
|
58
|
+
* @returns {string} Binary file name
|
|
59
|
+
*/
|
|
60
|
+
function getBinaryName() {
|
|
61
|
+
const platform = os.platform();
|
|
62
|
+
return BINARY_NAMES[platform] || 'glock';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get the download URL for the binary
|
|
67
|
+
* @param {string} version - Version to download (e.g., '1.0.0')
|
|
68
|
+
* @param {string} baseUrl - Base URL for downloads
|
|
69
|
+
* @returns {string} Full download URL
|
|
70
|
+
*/
|
|
71
|
+
function getDownloadUrl(version, baseUrl = 'https://github.com/glock/glock/releases/download') {
|
|
72
|
+
const platform = os.platform();
|
|
73
|
+
const arch = os.arch();
|
|
74
|
+
const platformId = `${platform}-${arch}`;
|
|
75
|
+
|
|
76
|
+
return `${baseUrl}/v${version}/glock-${platformId}.tar.gz`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the installation directory for the binary
|
|
81
|
+
* @returns {string} Installation directory path
|
|
82
|
+
*/
|
|
83
|
+
function getInstallDir() {
|
|
84
|
+
return path.join(__dirname, '..', 'bin', getPlatformId());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get the full path to the installed binary
|
|
89
|
+
* @returns {string} Full binary path
|
|
90
|
+
*/
|
|
91
|
+
function getBinaryPath() {
|
|
92
|
+
return path.join(getInstallDir(), getBinaryName());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get platform-specific environment variables
|
|
97
|
+
* @returns {Object} Environment variables to set
|
|
98
|
+
*/
|
|
99
|
+
function getPlatformEnv() {
|
|
100
|
+
const env = {
|
|
101
|
+
GLOCK_NPM_INSTALL: '1',
|
|
102
|
+
GLOCK_PLATFORM: getPlatformId(),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Platform-specific additions
|
|
106
|
+
const platform = os.platform();
|
|
107
|
+
|
|
108
|
+
if (platform === 'darwin') {
|
|
109
|
+
// macOS-specific
|
|
110
|
+
env.GLOCK_MACOS_VERSION = os.release();
|
|
111
|
+
} else if (platform === 'linux') {
|
|
112
|
+
// Linux-specific
|
|
113
|
+
env.GLOCK_LINUX_DISTRO = detectLinuxDistro();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return env;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Detect Linux distribution (best effort)
|
|
121
|
+
* @returns {string} Distribution name or 'unknown'
|
|
122
|
+
*/
|
|
123
|
+
function detectLinuxDistro() {
|
|
124
|
+
try {
|
|
125
|
+
const fs = require('fs');
|
|
126
|
+
|
|
127
|
+
// Try /etc/os-release first
|
|
128
|
+
if (fs.existsSync('/etc/os-release')) {
|
|
129
|
+
const content = fs.readFileSync('/etc/os-release', 'utf8');
|
|
130
|
+
const match = content.match(/^ID=(.*)$/m);
|
|
131
|
+
if (match) {
|
|
132
|
+
return match[1].replace(/"/g, '');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Fallback checks
|
|
137
|
+
if (fs.existsSync('/etc/debian_version')) {
|
|
138
|
+
return 'debian';
|
|
139
|
+
}
|
|
140
|
+
if (fs.existsSync('/etc/redhat-release')) {
|
|
141
|
+
return 'redhat';
|
|
142
|
+
}
|
|
143
|
+
if (fs.existsSync('/etc/alpine-release')) {
|
|
144
|
+
return 'alpine';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return 'unknown';
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return 'unknown';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get system information for debugging
|
|
155
|
+
* @returns {Object} System information
|
|
156
|
+
*/
|
|
157
|
+
function getSystemInfo() {
|
|
158
|
+
return {
|
|
159
|
+
platform: os.platform(),
|
|
160
|
+
arch: os.arch(),
|
|
161
|
+
release: os.release(),
|
|
162
|
+
type: os.type(),
|
|
163
|
+
cpus: os.cpus().length,
|
|
164
|
+
memory: Math.round(os.totalmem() / (1024 * 1024 * 1024)) + 'GB',
|
|
165
|
+
node: process.version,
|
|
166
|
+
npm: process.env.npm_config_user_agent || 'unknown',
|
|
167
|
+
supported: isPlatformSupported(),
|
|
168
|
+
platformId: getPlatformId(),
|
|
169
|
+
binaryName: getBinaryName(),
|
|
170
|
+
installDir: getInstallDir(),
|
|
171
|
+
binaryPath: getBinaryPath(),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Validate that the platform can run Glock
|
|
177
|
+
* @throws {Error} If platform is not supported
|
|
178
|
+
*/
|
|
179
|
+
function validatePlatform() {
|
|
180
|
+
if (!isPlatformSupported()) {
|
|
181
|
+
const platform = os.platform();
|
|
182
|
+
const arch = os.arch();
|
|
183
|
+
const supported = Object.entries(SUPPORTED_PLATFORMS)
|
|
184
|
+
.map(([p, archs]) => `${p} (${archs.join(', ')})`)
|
|
185
|
+
.join(', ');
|
|
186
|
+
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Glock does not support ${platform}-${arch}.\n` +
|
|
189
|
+
`Supported platforms: ${supported}\n` +
|
|
190
|
+
`Please open an issue if you need support for this platform.`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Check if running in CI environment
|
|
197
|
+
* @returns {boolean} True if in CI
|
|
198
|
+
*/
|
|
199
|
+
function isCI() {
|
|
200
|
+
return !!(
|
|
201
|
+
process.env.CI ||
|
|
202
|
+
process.env.CONTINUOUS_INTEGRATION ||
|
|
203
|
+
process.env.GITHUB_ACTIONS ||
|
|
204
|
+
process.env.GITLAB_CI ||
|
|
205
|
+
process.env.CIRCLECI ||
|
|
206
|
+
process.env.TRAVIS ||
|
|
207
|
+
process.env.JENKINS_URL
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get appropriate temp directory for downloads
|
|
213
|
+
* @returns {string} Temp directory path
|
|
214
|
+
*/
|
|
215
|
+
function getTempDir() {
|
|
216
|
+
return process.env.GLOCK_TEMP_DIR || os.tmpdir();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = {
|
|
220
|
+
getPlatformId,
|
|
221
|
+
isPlatformSupported,
|
|
222
|
+
getBinaryName,
|
|
223
|
+
getDownloadUrl,
|
|
224
|
+
getInstallDir,
|
|
225
|
+
getBinaryPath,
|
|
226
|
+
getPlatformEnv,
|
|
227
|
+
detectLinuxDistro,
|
|
228
|
+
getSystemInfo,
|
|
229
|
+
validatePlatform,
|
|
230
|
+
isCI,
|
|
231
|
+
getTempDir,
|
|
232
|
+
SUPPORTED_PLATFORMS,
|
|
233
|
+
BINARY_NAMES,
|
|
234
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@glock-org/glock",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Glock - AI Coding Assistant CLI",
|
|
5
|
+
"keywords": ["glock", "ai", "coding", "assistant", "cli"],
|
|
6
|
+
"author": "Glock",
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"private": false,
|
|
9
|
+
"homepage": "https://getglock.dev",
|
|
10
|
+
"bin": {
|
|
11
|
+
"glock": "./bin/glock.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"postinstall": "node scripts/postinstall.js"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin/",
|
|
21
|
+
"lib/",
|
|
22
|
+
"scripts/",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"os": ["darwin", "linux", "win32"],
|
|
26
|
+
"cpu": ["x64", "arm64"]
|
|
27
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Glock postinstall script
|
|
5
|
+
*
|
|
6
|
+
* Downloads the appropriate platform binary after npm install.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const https = require('https');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
|
|
15
|
+
const VERSION = require('../package.json').version;
|
|
16
|
+
const PLATFORM = os.platform();
|
|
17
|
+
const ARCH = os.arch();
|
|
18
|
+
|
|
19
|
+
// Map to our binary naming convention
|
|
20
|
+
const platformMap = {
|
|
21
|
+
'darwin': 'darwin',
|
|
22
|
+
'linux': 'linux',
|
|
23
|
+
'win32': 'win32',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const archMap = {
|
|
27
|
+
'x64': 'x64',
|
|
28
|
+
'arm64': 'arm64',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const mappedPlatform = platformMap[PLATFORM];
|
|
32
|
+
const mappedArch = archMap[ARCH];
|
|
33
|
+
|
|
34
|
+
if (!mappedPlatform || !mappedArch) {
|
|
35
|
+
console.error(`Unsupported platform: ${PLATFORM}-${ARCH}`);
|
|
36
|
+
console.error('Glock supports: darwin-x64, darwin-arm64, linux-x64, linux-arm64, win32-x64');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const BINARY_NAME = PLATFORM === 'win32' ? 'glock.exe' : 'glock';
|
|
41
|
+
const DOWNLOAD_BASE = 'https://glock-releases.s3.amazonaws.com';
|
|
42
|
+
|
|
43
|
+
async function downloadBinary() {
|
|
44
|
+
const url = `${DOWNLOAD_BASE}/v${VERSION}/glock-${mappedPlatform}-${mappedArch}.tar.gz`;
|
|
45
|
+
console.log(`Download URL: ${url}`);
|
|
46
|
+
const binDir = path.join(__dirname, '..', 'bin', `glock-${mappedPlatform}-${mappedArch}`);
|
|
47
|
+
const tarPath = path.join(binDir, 'glock.tar.gz');
|
|
48
|
+
|
|
49
|
+
console.log(`Downloading Glock v${VERSION} for ${mappedPlatform}-${mappedArch}...`);
|
|
50
|
+
|
|
51
|
+
// Create directory
|
|
52
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
53
|
+
|
|
54
|
+
// Download file
|
|
55
|
+
await new Promise((resolve, reject) => {
|
|
56
|
+
const file = fs.createWriteStream(tarPath);
|
|
57
|
+
|
|
58
|
+
const request = (downloadUrl) => {
|
|
59
|
+
https.get(downloadUrl, (response) => {
|
|
60
|
+
// Handle redirects
|
|
61
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
62
|
+
const redirectUrl = response.headers.location;
|
|
63
|
+
if (redirectUrl) {
|
|
64
|
+
request(redirectUrl);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (response.statusCode !== 200) {
|
|
70
|
+
reject(new Error(`Download failed: HTTP ${response.statusCode}`));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
response.pipe(file);
|
|
75
|
+
file.on('finish', () => {
|
|
76
|
+
file.close();
|
|
77
|
+
resolve();
|
|
78
|
+
});
|
|
79
|
+
}).on('error', (err) => {
|
|
80
|
+
fs.unlink(tarPath, () => {});
|
|
81
|
+
reject(err);
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
request(url);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Extract archive
|
|
89
|
+
console.log('Extracting...');
|
|
90
|
+
try {
|
|
91
|
+
execSync(`tar -xzf glock.tar.gz`, { cwd: binDir, stdio: 'pipe' });
|
|
92
|
+
} catch (err) {
|
|
93
|
+
// Try with gzip separately on some systems
|
|
94
|
+
try {
|
|
95
|
+
execSync(`gzip -d glock.tar.gz && tar -xf glock.tar`, { cwd: binDir, stdio: 'pipe' });
|
|
96
|
+
} catch (err2) {
|
|
97
|
+
throw new Error('Failed to extract archive. Please ensure tar is available.');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Clean up archive
|
|
102
|
+
try {
|
|
103
|
+
fs.unlinkSync(tarPath);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
// Ignore cleanup errors
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
fs.unlinkSync(path.join(binDir, 'glock.tar'));
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// Ignore cleanup errors
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Make executable on Unix
|
|
114
|
+
if (PLATFORM !== 'win32') {
|
|
115
|
+
const binaryPath = path.join(binDir, BINARY_NAME);
|
|
116
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log('Glock installed successfully!');
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log('Run `glock` to start an interactive session.');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Only run if not in CI or if explicitly requested
|
|
125
|
+
const skipDownload = process.env.GLOCK_SKIP_BINARY_DOWNLOAD === '1';
|
|
126
|
+
const isCI = process.env.CI === 'true';
|
|
127
|
+
|
|
128
|
+
if (skipDownload) {
|
|
129
|
+
console.log('Skipping binary download (GLOCK_SKIP_BINARY_DOWNLOAD=1)');
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
downloadBinary().catch((err) => {
|
|
134
|
+
console.error('');
|
|
135
|
+
console.error('Failed to download Glock binary:', err.message);
|
|
136
|
+
console.error('');
|
|
137
|
+
console.error('You can try:');
|
|
138
|
+
console.error(' 1. Check your network connection');
|
|
139
|
+
console.error(' 2. Download manually from https://glock-releases.s3.amazonaws.com');
|
|
140
|
+
console.error(' 3. Contact support at https://getglock.dev');
|
|
141
|
+
console.error('');
|
|
142
|
+
|
|
143
|
+
// Don't fail the install - the binary might be added manually
|
|
144
|
+
if (!isCI) {
|
|
145
|
+
process.exit(0);
|
|
146
|
+
}
|
|
147
|
+
process.exit(1);
|
|
148
|
+
});
|