@command-center/command-center 0.7.2 → 0.7.3-rc1
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 +3 -0
- package/bin/command-center.js +191 -30
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Binary distribution of UpToSpeed Command Center, a desktop-friendly interface fo
|
|
|
9
9
|
- Linux arm64
|
|
10
10
|
- Linux x64
|
|
11
11
|
- Windows x64
|
|
12
|
+
- Windows arm64
|
|
12
13
|
|
|
13
14
|
If your platform is missing, please open an issue so we can add another target.
|
|
14
15
|
|
|
@@ -25,6 +26,7 @@ This command places a `command-center` executable on your `$PATH`. During instal
|
|
|
25
26
|
- `@command-center/command-center-linux-arm64`
|
|
26
27
|
- `@command-center/command-center-linux-x64`
|
|
27
28
|
- `@command-center/command-center-win-x64`
|
|
29
|
+
- `@command-center/command-center-win-arm64`
|
|
28
30
|
|
|
29
31
|
Each optional package ships exactly one prebuilt binary. The wrapper resolves the right package at runtime and forwards all CLI arguments to its binary.
|
|
30
32
|
|
|
@@ -69,3 +71,4 @@ directly from the printed path.
|
|
|
69
71
|
- **“Unsupported platform”** – The wrapper could not map your `process.platform`/`process.arch` combination. Please file an issue with your OS and architecture.
|
|
70
72
|
- **“Expected binary … was not found”** – Reinstall the package. If you are developing locally, run `npm run prepare:dist` from the repository root to refresh the optional binary packages.
|
|
71
73
|
- **Permission errors** – On POSIX systems, ensure the binaries remain executable (`chmod +x node_modules/@command-center/command-center-*/dist/command-center-*`).
|
|
74
|
+
- **AVX crash on Windows** – If the Windows x64 binary crashes immediately (e.g. in Parallels or on older CPUs without AVX), the wrapper automatically installs and runs `@command-center/command-center-win-x64-baseline`, a build without AVX instructions.
|
package/bin/command-center.js
CHANGED
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// Thin Node.js wrapper around the precompiled Command Center binary.
|
|
4
|
+
//
|
|
5
|
+
// This script resolves the correct platform-specific binary from npm optional
|
|
6
|
+
// dependencies and spawns it, forwarding all CLI arguments and stdio.
|
|
7
|
+
//
|
|
8
|
+
// COMMENT_AVX_Fallback (Windows x64 only), 2026.03.04
|
|
9
|
+
// --------------------------------
|
|
10
|
+
// Parallels Desktop x86_64 emulation on Apple Silicon does not support AVX.
|
|
11
|
+
// When run: will exit with STATUS_ILLEGAL_INSTRUCTION.
|
|
12
|
+
// Solution: Have another binary that is compiled without AVX instructions (baseline),
|
|
13
|
+
// download it on demand.
|
|
14
|
+
|
|
15
|
+
// #######################################
|
|
16
|
+
// Imports
|
|
17
|
+
// #######################################
|
|
18
|
+
|
|
19
|
+
import { execSync, spawn } from "node:child_process";
|
|
4
20
|
import { existsSync } from "node:fs";
|
|
5
21
|
import { createRequire } from "node:module";
|
|
6
22
|
import path from "node:path";
|
|
7
23
|
|
|
24
|
+
// #######################################
|
|
25
|
+
// Constants
|
|
26
|
+
// #######################################
|
|
27
|
+
|
|
8
28
|
const require = createRequire(import.meta.url);
|
|
9
29
|
const packageMetadata = require("../package.json");
|
|
10
30
|
|
|
11
31
|
const PACKAGE_VERSION = packageMetadata.version ?? "0.0.0";
|
|
12
32
|
const PLATFORM_KEY = `${process.platform}:${process.arch}`;
|
|
13
33
|
|
|
34
|
+
// STATUS_ILLEGAL_INSTRUCTION (0xC000001D) as an unsigned 32-bit integer.
|
|
35
|
+
// Windows returns this when a process hits an unsupported CPU instruction
|
|
36
|
+
// (e.g. AVX on a system without AVX support, such as Parallels x86_64 emulation).
|
|
37
|
+
const STATUS_ILLEGAL_INSTRUCTION = 3_221_225_501;
|
|
38
|
+
|
|
14
39
|
// TAG_PLATFORM_MATRIX 2025.10.14: Keep entries in sync with scripts/build-all.ts outputs.
|
|
15
40
|
const PLATFORM_PACKAGES = new Map([
|
|
16
41
|
[
|
|
@@ -46,15 +71,51 @@ const PLATFORM_PACKAGES = new Map([
|
|
|
46
71
|
{
|
|
47
72
|
packageName: "@command-center/command-center-win-x64",
|
|
48
73
|
binaryName: "command-center-win-x64.exe",
|
|
74
|
+
// On-demand fallback: only downloaded if the primary binary crashes with
|
|
75
|
+
// STATUS_ILLEGAL_INSTRUCTION (no AVX support). See file header for details.
|
|
76
|
+
fallbackPackageName: "@command-center/command-center-win-x64-baseline",
|
|
77
|
+
fallbackBinaryName: "command-center-win-x64-baseline.exe",
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"win32:arm64",
|
|
82
|
+
{
|
|
83
|
+
packageName: "@command-center/command-center-win-arm64",
|
|
84
|
+
binaryName: "command-center-win-arm64.exe",
|
|
49
85
|
},
|
|
50
86
|
],
|
|
51
87
|
]);
|
|
52
88
|
|
|
89
|
+
// #######################################
|
|
90
|
+
// Utility Functions
|
|
91
|
+
// #######################################
|
|
92
|
+
|
|
53
93
|
function fail(message) {
|
|
54
94
|
console.error(`command-center (wrapper): ${message}`);
|
|
55
95
|
process.exit(1);
|
|
56
96
|
}
|
|
57
97
|
|
|
98
|
+
// #######################################
|
|
99
|
+
// Binary Resolution
|
|
100
|
+
// #######################################
|
|
101
|
+
|
|
102
|
+
function resolvePackageRoot(packageName) {
|
|
103
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`);
|
|
104
|
+
return path.dirname(packageJsonPath);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveBinaryInPackage(packageName, binaryName) {
|
|
108
|
+
let packageRoot;
|
|
109
|
+
try {
|
|
110
|
+
packageRoot = resolvePackageRoot(packageName);
|
|
111
|
+
} catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const binaryPath = path.join(packageRoot, "dist", binaryName);
|
|
116
|
+
return existsSync(binaryPath) ? binaryPath : null;
|
|
117
|
+
}
|
|
118
|
+
|
|
58
119
|
function resolveBinary() {
|
|
59
120
|
const entry = PLATFORM_PACKAGES.get(PLATFORM_KEY);
|
|
60
121
|
if (!entry) {
|
|
@@ -65,61 +126,161 @@ function resolveBinary() {
|
|
|
65
126
|
);
|
|
66
127
|
}
|
|
67
128
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
packageRoot = path.dirname(packageJsonPath);
|
|
74
|
-
} catch (error) {
|
|
129
|
+
const binaryPath = resolveBinaryInPackage(
|
|
130
|
+
entry.packageName,
|
|
131
|
+
entry.binaryName,
|
|
132
|
+
);
|
|
133
|
+
if (!binaryPath) {
|
|
75
134
|
fail(
|
|
76
135
|
`missing optional dependency '${entry.packageName}'.` +
|
|
77
136
|
"\n • npm should install it automatically on supported platforms." +
|
|
78
|
-
"\n • Try reinstalling the CLI or running 'npm install @command-center/command-center' again."
|
|
79
|
-
`\n • Underlying error: ${error instanceof Error ? error.message : String(error)}`,
|
|
137
|
+
"\n • Try reinstalling the CLI or running 'npm install @command-center/command-center' again.",
|
|
80
138
|
);
|
|
81
139
|
}
|
|
82
140
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
141
|
+
return { binaryPath, entry };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// #######################################
|
|
145
|
+
// Process Spawning
|
|
146
|
+
// #######################################
|
|
147
|
+
|
|
148
|
+
function spawnBinary(binaryPath, argv) {
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
const child = spawn(binaryPath, argv, { stdio: "inherit" });
|
|
151
|
+
|
|
152
|
+
child.on("error", (error) => {
|
|
153
|
+
resolve({ code: null, signal: null, error });
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
child.on("exit", (code, signal) => {
|
|
157
|
+
resolve({ code, signal, error: null });
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// #######################################
|
|
163
|
+
// AVX Fallback
|
|
164
|
+
// #######################################
|
|
165
|
+
|
|
166
|
+
// Downloads the baseline binary package on demand via `npm install -g`.
|
|
167
|
+
// This only runs once per machine — after installation, subsequent launches
|
|
168
|
+
// find the package locally and skip this step.
|
|
169
|
+
function installFallbackPackage(packageName) {
|
|
170
|
+
console.error(
|
|
171
|
+
`command-center (wrapper): installing fallback package ${packageName}@${PACKAGE_VERSION}...`,
|
|
172
|
+
);
|
|
173
|
+
try {
|
|
174
|
+
execSync(`npm install -g ${packageName}@${PACKAGE_VERSION}`, {
|
|
175
|
+
stdio: "inherit",
|
|
176
|
+
});
|
|
177
|
+
return true;
|
|
178
|
+
} catch {
|
|
179
|
+
console.error(
|
|
180
|
+
`command-center (wrapper): failed to install ${packageName}. You can install it manually:` +
|
|
181
|
+
`\n npm install -g ${packageName}@${PACKAGE_VERSION}`,
|
|
89
182
|
);
|
|
183
|
+
return false;
|
|
90
184
|
}
|
|
91
|
-
|
|
92
|
-
return binaryPath;
|
|
93
185
|
}
|
|
94
186
|
|
|
187
|
+
// #######################################
|
|
188
|
+
// Main
|
|
189
|
+
// #######################################
|
|
190
|
+
|
|
95
191
|
const argv = process.argv.slice(2);
|
|
96
192
|
|
|
97
193
|
const printVersionBanner = () => {
|
|
98
194
|
console.log(`command-center ${PACKAGE_VERSION}`);
|
|
99
195
|
};
|
|
100
196
|
|
|
197
|
+
// ##############################
|
|
198
|
+
// Handle --version flag
|
|
199
|
+
// ##############################
|
|
200
|
+
|
|
101
201
|
if (argv.some((arg) => arg === "--version" || arg === "-v")) {
|
|
102
202
|
printVersionBanner();
|
|
103
203
|
process.exit(0);
|
|
104
204
|
}
|
|
105
205
|
|
|
106
|
-
|
|
206
|
+
// ##############################
|
|
207
|
+
// Resolve and spawn primary binary
|
|
208
|
+
// ##############################
|
|
209
|
+
|
|
210
|
+
const { binaryPath, entry } = resolveBinary();
|
|
107
211
|
printVersionBanner();
|
|
108
212
|
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
213
|
+
const result = await spawnBinary(binaryPath, argv);
|
|
214
|
+
|
|
215
|
+
if (result.error) {
|
|
216
|
+
fail(`failed to launch bundled binary (${result.error.message}).`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ##############################
|
|
220
|
+
// AVX fallback for Windows
|
|
221
|
+
// ##############################
|
|
222
|
+
|
|
223
|
+
// The AVX binary crashes immediately on CPUs/emulators without AVX support.
|
|
224
|
+
// Node's `spawn` reports the Windows NTSTATUS code as an unsigned 32-bit exit
|
|
225
|
+
// code (3221225501), not the signed representation (-1073741795).
|
|
226
|
+
// When we see this specific exit code AND the platform entry has a fallback
|
|
227
|
+
// configured, we install (if needed) and launch the baseline binary instead.
|
|
228
|
+
if (result.code === STATUS_ILLEGAL_INSTRUCTION && entry.fallbackPackageName) {
|
|
229
|
+
console.error(
|
|
230
|
+
"command-center (wrapper): binary crashed (CPU does not support AVX instructions).",
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
// ####################
|
|
234
|
+
// Resolve or install fallback binary
|
|
235
|
+
// ####################
|
|
112
236
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
237
|
+
let fallbackPath = resolveBinaryInPackage(
|
|
238
|
+
entry.fallbackPackageName,
|
|
239
|
+
entry.fallbackBinaryName,
|
|
240
|
+
);
|
|
116
241
|
|
|
117
|
-
|
|
118
|
-
|
|
242
|
+
if (!fallbackPath) {
|
|
243
|
+
const installed = installFallbackPackage(entry.fallbackPackageName);
|
|
244
|
+
if (installed) {
|
|
245
|
+
fallbackPath = resolveBinaryInPackage(
|
|
246
|
+
entry.fallbackPackageName,
|
|
247
|
+
entry.fallbackBinaryName,
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!fallbackPath) {
|
|
253
|
+
fail("failed to resolve fallback binary after installation.");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ####################
|
|
257
|
+
// Spawn fallback binary
|
|
258
|
+
// ####################
|
|
259
|
+
|
|
260
|
+
console.error("command-center (wrapper): retrying with baseline binary...");
|
|
261
|
+
const fallbackResult = await spawnBinary(fallbackPath, argv);
|
|
262
|
+
|
|
263
|
+
if (fallbackResult.error) {
|
|
264
|
+
fail(`failed to launch fallback binary (${fallbackResult.error.message}).`);
|
|
265
|
+
}
|
|
266
|
+
if (fallbackResult.signal) {
|
|
119
267
|
console.error(
|
|
120
|
-
`command-center (wrapper): process terminated with signal ${signal}.`,
|
|
268
|
+
`command-center (wrapper): process terminated with signal ${fallbackResult.signal}.`,
|
|
121
269
|
);
|
|
122
270
|
process.exit(1);
|
|
123
271
|
}
|
|
124
|
-
process.exit(code === null ? 1 : code);
|
|
125
|
-
}
|
|
272
|
+
process.exit(fallbackResult.code === null ? 1 : fallbackResult.code);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// ##############################
|
|
276
|
+
// Exit with primary binary result
|
|
277
|
+
// ##############################
|
|
278
|
+
|
|
279
|
+
if (result.signal) {
|
|
280
|
+
console.error(
|
|
281
|
+
`command-center (wrapper): process terminated with signal ${result.signal}.`,
|
|
282
|
+
);
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
process.exit(result.code === null ? 1 : result.code);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@command-center/command-center",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-rc1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Binary distribution of UpToSpeed Command Center",
|
|
6
6
|
"bin": {
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@command-center/command-center-linux-arm64": "0.7.
|
|
27
|
-
"@command-center/command-center-linux-x64": "0.7.
|
|
28
|
-
"@command-center/command-center-macos-arm64": "0.7.
|
|
29
|
-
"@command-center/command-center-macos-x64": "0.7.
|
|
30
|
-
"@command-center/command-center-win-
|
|
26
|
+
"@command-center/command-center-linux-arm64": "0.7.3-rc1",
|
|
27
|
+
"@command-center/command-center-linux-x64": "0.7.3-rc1",
|
|
28
|
+
"@command-center/command-center-macos-arm64": "0.7.3-rc1",
|
|
29
|
+
"@command-center/command-center-macos-x64": "0.7.3-rc1",
|
|
30
|
+
"@command-center/command-center-win-arm64": "0.7.3-rc1",
|
|
31
|
+
"@command-center/command-center-win-x64": "0.7.3-rc1"
|
|
31
32
|
},
|
|
32
33
|
"scripts": {}
|
|
33
34
|
}
|