@command-center/command-center 0.7.1-rc.3 → 0.7.2-rc.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/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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { spawn } from "node:child_process";
3
+ import { execSync, spawn } from "node:child_process";
4
4
  import { existsSync } from "node:fs";
5
5
  import { createRequire } from "node:module";
6
6
  import path from "node:path";
@@ -11,6 +11,11 @@ const packageMetadata = require("../package.json");
11
11
  const PACKAGE_VERSION = packageMetadata.version ?? "0.0.0";
12
12
  const PLATFORM_KEY = `${process.platform}:${process.arch}`;
13
13
 
14
+ // STATUS_ILLEGAL_INSTRUCTION (0xC000001D) as an unsigned 32-bit integer.
15
+ // Windows returns this when a process hits an unsupported CPU instruction
16
+ // (e.g. AVX on a system without AVX support, such as Parallels x86_64 emulation).
17
+ const STATUS_ILLEGAL_INSTRUCTION = 3_221_225_501;
18
+
14
19
  // TAG_PLATFORM_MATRIX 2025.10.14: Keep entries in sync with scripts/build-all.ts outputs.
15
20
  const PLATFORM_PACKAGES = new Map([
16
21
  [
@@ -46,6 +51,15 @@ const PLATFORM_PACKAGES = new Map([
46
51
  {
47
52
  packageName: "@command-center/command-center-win-x64",
48
53
  binaryName: "command-center-win-x64.exe",
54
+ fallbackPackageName: "@command-center/command-center-win-x64-baseline",
55
+ fallbackBinaryName: "command-center-win-x64-baseline.exe",
56
+ },
57
+ ],
58
+ [
59
+ "win32:arm64",
60
+ {
61
+ packageName: "@command-center/command-center-win-arm64",
62
+ binaryName: "command-center-win-arm64.exe",
49
63
  },
50
64
  ],
51
65
  ]);
@@ -55,6 +69,23 @@ function fail(message) {
55
69
  process.exit(1);
56
70
  }
57
71
 
72
+ function resolvePackageRoot(packageName) {
73
+ const packageJsonPath = require.resolve(`${packageName}/package.json`);
74
+ return path.dirname(packageJsonPath);
75
+ }
76
+
77
+ function resolveBinaryInPackage(packageName, binaryName) {
78
+ let packageRoot;
79
+ try {
80
+ packageRoot = resolvePackageRoot(packageName);
81
+ } catch {
82
+ return null;
83
+ }
84
+
85
+ const binaryPath = path.join(packageRoot, "dist", binaryName);
86
+ return existsSync(binaryPath) ? binaryPath : null;
87
+ }
88
+
58
89
  function resolveBinary() {
59
90
  const entry = PLATFORM_PACKAGES.get(PLATFORM_KEY);
60
91
  if (!entry) {
@@ -65,31 +96,51 @@ function resolveBinary() {
65
96
  );
66
97
  }
67
98
 
68
- let packageRoot = "";
69
- try {
70
- const packageJsonPath = require.resolve(
71
- `${entry.packageName}/package.json`,
72
- );
73
- packageRoot = path.dirname(packageJsonPath);
74
- } catch (error) {
99
+ const binaryPath = resolveBinaryInPackage(
100
+ entry.packageName,
101
+ entry.binaryName,
102
+ );
103
+ if (!binaryPath) {
75
104
  fail(
76
105
  `missing optional dependency '${entry.packageName}'.` +
77
106
  "\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)}`,
107
+ "\n • Try reinstalling the CLI or running 'npm install @command-center/command-center' again.",
80
108
  );
81
109
  }
82
110
 
83
- const binaryPath = path.join(packageRoot, "dist", entry.binaryName);
84
- if (!existsSync(binaryPath)) {
85
- fail(
86
- `expected binary '${entry.binaryName}' was not found in ${entry.packageName}.` +
87
- "\n Ensure the optional dependency was published with binaries (run 'bun run build:binary' before publishing)." +
88
- "\n • If you are developing locally, run 'npm run prepare:dist' to refresh optional packages.",
111
+ return { binaryPath, entry };
112
+ }
113
+
114
+ function spawnBinary(binaryPath, argv) {
115
+ return new Promise((resolve) => {
116
+ const child = spawn(binaryPath, argv, { stdio: "inherit" });
117
+
118
+ child.on("error", (error) => {
119
+ resolve({ code: null, signal: null, error });
120
+ });
121
+
122
+ child.on("exit", (code, signal) => {
123
+ resolve({ code, signal, error: null });
124
+ });
125
+ });
126
+ }
127
+
128
+ function installFallbackPackage(packageName) {
129
+ console.error(
130
+ `command-center (wrapper): installing fallback package ${packageName}@${PACKAGE_VERSION}...`,
131
+ );
132
+ try {
133
+ execSync(`npm install -g ${packageName}@${PACKAGE_VERSION}`, {
134
+ stdio: "inherit",
135
+ });
136
+ return true;
137
+ } catch {
138
+ console.error(
139
+ `command-center (wrapper): failed to install ${packageName}. You can install it manually:` +
140
+ `\n npm install -g ${packageName}@${PACKAGE_VERSION}`,
89
141
  );
142
+ return false;
90
143
  }
91
-
92
- return binaryPath;
93
144
  }
94
145
 
95
146
  const argv = process.argv.slice(2);
@@ -103,23 +154,63 @@ if (argv.some((arg) => arg === "--version" || arg === "-v")) {
103
154
  process.exit(0);
104
155
  }
105
156
 
106
- const binaryPath = resolveBinary();
157
+ const { binaryPath, entry } = resolveBinary();
107
158
  printVersionBanner();
108
159
 
109
- const child = spawn(binaryPath, argv, {
110
- stdio: "inherit",
111
- });
160
+ const result = await spawnBinary(binaryPath, argv);
161
+
162
+ if (result.error) {
163
+ fail(`failed to launch bundled binary (${result.error.message}).`);
164
+ }
165
+
166
+ // If the binary crashed with STATUS_ILLEGAL_INSTRUCTION and a fallback exists,
167
+ // the CPU likely doesn't support AVX. Download and run the baseline binary.
168
+ if (result.code === STATUS_ILLEGAL_INSTRUCTION && entry.fallbackPackageName) {
169
+ console.error(
170
+ "command-center (wrapper): binary crashed (CPU does not support AVX instructions).",
171
+ );
172
+
173
+ // Check if fallback is already installed
174
+ let fallbackPath = resolveBinaryInPackage(
175
+ entry.fallbackPackageName,
176
+ entry.fallbackBinaryName,
177
+ );
178
+
179
+ // If not installed, download it
180
+ if (!fallbackPath) {
181
+ const installed = installFallbackPackage(entry.fallbackPackageName);
182
+ if (installed) {
183
+ fallbackPath = resolveBinaryInPackage(
184
+ entry.fallbackPackageName,
185
+ entry.fallbackBinaryName,
186
+ );
187
+ }
188
+ }
189
+
190
+ if (!fallbackPath) {
191
+ fail("failed to resolve fallback binary after installation.");
192
+ }
112
193
 
113
- child.on("error", (error) => {
114
- fail(`failed to launch bundled binary (${error.message}).`);
115
- });
194
+ console.error("command-center (wrapper): retrying with baseline binary...");
195
+ const fallbackResult = await spawnBinary(fallbackPath, argv);
116
196
 
117
- child.on("exit", (code, signal) => {
118
- if (signal) {
197
+ if (fallbackResult.error) {
198
+ fail(`failed to launch fallback binary (${fallbackResult.error.message}).`);
199
+ }
200
+ if (fallbackResult.signal) {
119
201
  console.error(
120
- `command-center (wrapper): process terminated with signal ${signal}.`,
202
+ `command-center (wrapper): process terminated with signal ${fallbackResult.signal}.`,
121
203
  );
122
204
  process.exit(1);
123
205
  }
124
- process.exit(code === null ? 1 : code);
125
- });
206
+ process.exit(fallbackResult.code === null ? 1 : fallbackResult.code);
207
+ }
208
+
209
+ if (result.signal) {
210
+ console.error(
211
+ `command-center (wrapper): process terminated with signal ${result.signal}.`,
212
+ );
213
+ process.exit(1);
214
+ }
215
+
216
+ 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.1-rc.3",
3
+ "version": "0.7.2-rc.0",
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.1-rc.3",
27
- "@command-center/command-center-linux-x64": "0.7.1-rc.3",
28
- "@command-center/command-center-macos-arm64": "0.7.1-rc.3",
29
- "@command-center/command-center-macos-x64": "0.7.1-rc.3",
30
- "@command-center/command-center-win-x64": "0.7.1-rc.3"
26
+ "@command-center/command-center-linux-arm64": "0.7.2-rc.0",
27
+ "@command-center/command-center-linux-x64": "0.7.2-rc.0",
28
+ "@command-center/command-center-macos-arm64": "0.7.2-rc.0",
29
+ "@command-center/command-center-macos-x64": "0.7.2-rc.0",
30
+ "@command-center/command-center-win-arm64": "0.7.2-rc.0",
31
+ "@command-center/command-center-win-x64": "0.7.2-rc.0"
31
32
  },
32
33
  "scripts": {}
33
34
  }