@qoder-ai/qodercli 0.1.0 → 0.1.2
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/qodercli +7 -2
- package/package.json +16 -12
- package/scripts/install.js +96 -25
package/bin/qodercli
CHANGED
|
@@ -11,8 +11,13 @@ const binPath = path.join(BIN_DIR, BINARY_NAME + (process.platform === 'win32' ?
|
|
|
11
11
|
|
|
12
12
|
function showInstallationError() {
|
|
13
13
|
console.error('❌ qodercli binary not found');
|
|
14
|
-
console.error('
|
|
15
|
-
console.error('
|
|
14
|
+
console.error('This usually means the installation process failed or was incomplete.');
|
|
15
|
+
console.error('📋 System Information for debugging:');
|
|
16
|
+
console.error(` Platform: ${process.platform} (${process.arch})`);
|
|
17
|
+
console.error(` Node.js: ${process.version}`);
|
|
18
|
+
console.error(` npm: ${process.env.npm_version || 'unknown'}`);
|
|
19
|
+
console.error(` Binary path: ${binPath}`);
|
|
20
|
+
console.error('');
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
// check if the binary file exists
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoder-ai/qodercli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "qodercli - npm installer",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=14"
|
|
31
31
|
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"adm-zip": "^0.5.10",
|
|
34
|
+
"tar": "^4.4.19"
|
|
35
|
+
},
|
|
32
36
|
"os": [
|
|
33
37
|
"darwin",
|
|
34
38
|
"linux",
|
|
@@ -40,37 +44,37 @@
|
|
|
40
44
|
],
|
|
41
45
|
"preferGlobal": true,
|
|
42
46
|
"binaries": {
|
|
43
|
-
"version": "0.1.
|
|
47
|
+
"version": "0.1.2",
|
|
44
48
|
"files": [
|
|
45
49
|
{
|
|
46
50
|
"os": "linux",
|
|
47
51
|
"arch": "amd64",
|
|
48
|
-
"url": "https://download.qoder.com/qodercli/releases/0.1.
|
|
49
|
-
"sha256": "
|
|
52
|
+
"url": "https://download.qoder.com/qodercli/releases/0.1.2/qodercli_0.1.2_linux_amd64.tar.gz",
|
|
53
|
+
"sha256": "3b45aa7f44105c7eb8ab43f38b708f1544d58bc54af14f168952b2c24530b926"
|
|
50
54
|
},
|
|
51
55
|
{
|
|
52
56
|
"os": "linux",
|
|
53
57
|
"arch": "arm64",
|
|
54
|
-
"url": "https://download.qoder.com/qodercli/releases/0.1.
|
|
55
|
-
"sha256": "
|
|
58
|
+
"url": "https://download.qoder.com/qodercli/releases/0.1.2/qodercli_0.1.2_linux_arm64.tar.gz",
|
|
59
|
+
"sha256": "4a880a9b9c074035b39a7f393ebe5e5e42bb13a8c56d51504edfd9efbaa4c53c"
|
|
56
60
|
},
|
|
57
61
|
{
|
|
58
62
|
"os": "darwin",
|
|
59
63
|
"arch": "amd64",
|
|
60
|
-
"url": "https://download.qoder.com/qodercli/releases/0.1.
|
|
61
|
-
"sha256": "
|
|
64
|
+
"url": "https://download.qoder.com/qodercli/releases/0.1.2/qodercli_0.1.2_darwin_amd64.zip",
|
|
65
|
+
"sha256": "69b94501dedcc33676cd406e2beed311994c36eee7a31057d7ccd93396776a8c"
|
|
62
66
|
},
|
|
63
67
|
{
|
|
64
68
|
"os": "darwin",
|
|
65
69
|
"arch": "arm64",
|
|
66
|
-
"url": "https://download.qoder.com/qodercli/releases/0.1.
|
|
67
|
-
"sha256": "
|
|
70
|
+
"url": "https://download.qoder.com/qodercli/releases/0.1.2/qodercli_0.1.2_darwin_arm64.zip",
|
|
71
|
+
"sha256": "8af8725b843e89d2ee86a3931c57ae490bda45cc0c7cdd6671efd99d84f7c954"
|
|
68
72
|
},
|
|
69
73
|
{
|
|
70
74
|
"os": "windows",
|
|
71
75
|
"arch": "amd64",
|
|
72
|
-
"url": "https://download.qoder.com/qodercli/releases/0.1.
|
|
73
|
-
"sha256": "
|
|
76
|
+
"url": "https://download.qoder.com/qodercli/releases/0.1.2/qodercli_0.1.2_windows_amd64.zip",
|
|
77
|
+
"sha256": "8a8a5f103bc1fa736d64928052d381ea12f6b115a04bf2215f9dc6ba46de169d"
|
|
74
78
|
}
|
|
75
79
|
]
|
|
76
80
|
}
|
package/scripts/install.js
CHANGED
|
@@ -107,7 +107,19 @@ class QoderInstaller {
|
|
|
107
107
|
throw new Error(`Binary file not found after extraction in ${extractDir}`);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
// Try rename first (efficient), fallback to copy+delete if cross-device
|
|
111
|
+
try {
|
|
112
|
+
fs.renameSync(extractedBinary[0], this.binPath);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error.code === 'EXDEV') {
|
|
115
|
+
// Cross-device link not permitted, use copy+delete fallback
|
|
116
|
+
console.log('Cross-device link detected, using copy+delete method...');
|
|
117
|
+
fs.copyFileSync(extractedBinary[0], this.binPath);
|
|
118
|
+
fs.unlinkSync(extractedBinary[0]);
|
|
119
|
+
} else {
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
111
123
|
|
|
112
124
|
// Set executable permission
|
|
113
125
|
if (process.platform !== 'win32') {
|
|
@@ -135,38 +147,89 @@ class QoderInstaller {
|
|
|
135
147
|
|
|
136
148
|
async extractArchive(archivePath, filename, extractDir) {
|
|
137
149
|
if (filename.endsWith('.zip')) {
|
|
138
|
-
// Extract ZIP file
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
// Extract ZIP file using Node.js packages first
|
|
151
|
+
let extracted = false;
|
|
152
|
+
|
|
153
|
+
// Method 1: Use adm-zip package (preferred)
|
|
154
|
+
try {
|
|
155
|
+
const AdmZip = require('adm-zip');
|
|
156
|
+
const zip = new AdmZip(archivePath);
|
|
157
|
+
zip.extractAllTo(extractDir, true);
|
|
158
|
+
extracted = true;
|
|
159
|
+
console.log('ZIP extracted using Node.js adm-zip package');
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.log('adm-zip extraction failed, trying system commands...', error.message);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Method 2: System command fallbacks
|
|
165
|
+
if (!extracted) {
|
|
166
|
+
if (process.platform === 'win32') {
|
|
167
|
+
// Windows: Try PowerShell then 7-Zip
|
|
168
|
+
try {
|
|
169
|
+
execSync(`powershell -command "Expand-Archive -Path '${archivePath}' -DestinationPath '${extractDir}' -Force"`, {
|
|
170
|
+
stdio: 'pipe'
|
|
171
|
+
});
|
|
172
|
+
extracted = true;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
try {
|
|
175
|
+
execSync(`7z x "${archivePath}" -o"${extractDir}" -y`, {
|
|
176
|
+
stdio: 'pipe'
|
|
177
|
+
});
|
|
178
|
+
extracted = true;
|
|
179
|
+
} catch (error2) {
|
|
180
|
+
// Will fail below
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
// Unix: Use unzip command
|
|
185
|
+
try {
|
|
186
|
+
execSync(`unzip -o "${archivePath}" -d "${extractDir}"`, {
|
|
187
|
+
stdio: 'pipe'
|
|
188
|
+
});
|
|
189
|
+
extracted = true;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
// Will fail below
|
|
192
|
+
}
|
|
156
193
|
}
|
|
157
194
|
}
|
|
195
|
+
|
|
196
|
+
if (!extracted) {
|
|
197
|
+
const platform = process.platform === 'win32' ? 'Windows' : 'Unix';
|
|
198
|
+
throw new Error(`ZIP extraction failed on ${platform}. Please ensure extraction tools are available.`);
|
|
199
|
+
}
|
|
158
200
|
} else {
|
|
159
|
-
// Extract tar.gz file
|
|
201
|
+
// Extract tar.gz file using Node.js tar package first
|
|
202
|
+
let extracted = false;
|
|
203
|
+
|
|
204
|
+
// Method 1: Use tar package (preferred)
|
|
160
205
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
206
|
+
const tar = require('tar');
|
|
207
|
+
// tar v4.x uses different API than v6.x
|
|
208
|
+
await tar.extract({
|
|
209
|
+
file: archivePath,
|
|
210
|
+
cwd: extractDir
|
|
163
211
|
});
|
|
212
|
+
extracted = true;
|
|
213
|
+
console.log('tar.gz extracted using Node.js tar package');
|
|
164
214
|
} catch (error) {
|
|
165
|
-
|
|
215
|
+
console.log('Node.js tar extraction failed, trying system tar command...', error.message);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Method 2: System tar command fallback
|
|
219
|
+
if (!extracted) {
|
|
220
|
+
try {
|
|
221
|
+
execSync(`tar -xzf "${archivePath}" -C "${extractDir}"`, {
|
|
222
|
+
stdio: 'pipe'
|
|
223
|
+
});
|
|
224
|
+
extracted = true;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
throw new Error('tar.gz extraction failed. Please ensure tar command is installed.');
|
|
227
|
+
}
|
|
166
228
|
}
|
|
167
229
|
}
|
|
168
230
|
}
|
|
169
231
|
|
|
232
|
+
|
|
170
233
|
calculateSha256(filePath) {
|
|
171
234
|
const fileBuffer = fs.readFileSync(filePath);
|
|
172
235
|
const hashSum = crypto.createHash('sha256');
|
|
@@ -334,8 +397,16 @@ class QoderInstaller {
|
|
|
334
397
|
|
|
335
398
|
// Main program
|
|
336
399
|
if (require.main === module) {
|
|
337
|
-
|
|
338
|
-
|
|
400
|
+
try {
|
|
401
|
+
const installer = new QoderInstaller();
|
|
402
|
+
installer.install();
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error('❌ Failed to initialize installer:', error.message);
|
|
405
|
+
console.error('This might be due to Node.js version compatibility issues.');
|
|
406
|
+
console.error(`Current Node.js version: ${process.version}`);
|
|
407
|
+
console.error('Required Node.js version: >=14');
|
|
408
|
+
process.exit(1);
|
|
409
|
+
}
|
|
339
410
|
}
|
|
340
411
|
|
|
341
412
|
module.exports = QoderInstaller;
|