shellx-cli 0.0.21 → 0.0.23

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/bundle/shellx.js CHANGED
@@ -143076,7 +143076,7 @@ var GIT_COMMIT_INFO, CLI_VERSION;
143076
143076
  var init_git_commit = __esm({
143077
143077
  "packages/core/dist/src/generated/git-commit.js"() {
143078
143078
  "use strict";
143079
- GIT_COMMIT_INFO = "0db37712";
143079
+ GIT_COMMIT_INFO = "c04c6e88";
143080
143080
  CLI_VERSION = "0.15.0-nightly.20251107.b8eeb553";
143081
143081
  }
143082
143082
  });
@@ -233003,7 +233003,7 @@ async function createContentGenerator(config, gcConfig, sessionId2) {
233003
233003
  if (gcConfig.fakeResponses) {
233004
233004
  return FakeContentGenerator.fromFile(gcConfig.fakeResponses);
233005
233005
  }
233006
- const version3 = "0.0.21";
233006
+ const version3 = "0.0.23";
233007
233007
  const userAgent = `GeminiCLI/${version3} (${process.platform}; ${process.arch})`;
233008
233008
  const baseHeaders = {
233009
233009
  "User-Agent": userAgent
@@ -302330,7 +302330,7 @@ async function getClientMetadata() {
302330
302330
  if (!clientMetadataPromise) {
302331
302331
  clientMetadataPromise = (async () => ({
302332
302332
  ideName: "GEMINI_CLI",
302333
- ideVersion: "0.0.21",
302333
+ ideVersion: "0.0.23",
302334
302334
  platform: getPlatform(),
302335
302335
  updateChannel: await getReleaseChannel(__dirname3)
302336
302336
  }))();
@@ -331751,7 +331751,7 @@ var require_dist9 = __commonJS({
331751
331751
  return __awaiter(this, void 0, void 0, function* () {
331752
331752
  var _a5, _b2;
331753
331753
  try {
331754
- this.wsUrl = yield this.authenticateDevice(this.deviceId);
331754
+ this.wsUrl = yield this.authenticateDevice();
331755
331755
  if (!this.wsUrl) {
331756
331756
  this.config.onError(new Event("connection"));
331757
331757
  this.reconnect();
@@ -331805,7 +331805,7 @@ var require_dist9 = __commonJS({
331805
331805
  }
331806
331806
  });
331807
331807
  }
331808
- authenticateDevice(deviceId) {
331808
+ authenticateDevice() {
331809
331809
  return __awaiter(this, void 0, void 0, function* () {
331810
331810
  let fallbackUrl = void 0;
331811
331811
  try {
@@ -331817,7 +331817,7 @@ var require_dist9 = __commonJS({
331817
331817
  if (localResp.ok) {
331818
331818
  const info2 = yield localResp.json();
331819
331819
  if (info2 && (info2.status === "ok" || info2.status === 1) && info2.uuid) {
331820
- if (deviceId === void 0 || deviceId === info2.uuid) {
331820
+ if (this.deviceId === void 0 || this.deviceId === info2.uuid) {
331821
331821
  const localUuid = info2.uuid;
331822
331822
  this.deviceId = localUuid;
331823
331823
  fallbackUrl = `ws://127.0.0.1:9091/api/s/${localUuid}`;
@@ -331828,14 +331828,14 @@ var require_dist9 = __commonJS({
331828
331828
  }
331829
331829
  } catch (e3) {
331830
331830
  }
331831
- if (deviceId === void 0) {
331831
+ if (this.deviceId === void 0) {
331832
331832
  console.warn("\u274C [Auth] \u8BBE\u5907ID\u672A\u8BBE\u7F6E\uFF0C\u672C\u5730\u672A\u8FDE\u63A5USB\uFF0C\u8BF7\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF SHELLX_DEVICE_ID \u6216\u8005 USB\u8FDE\u63A5\u8BBE\u5907");
331833
331833
  return void 0;
331834
331834
  }
331835
331835
  try {
331836
331836
  console.log("\u{1F511} [Auth] \u6B63\u5728\u8BA4\u8BC1\u8BBE\u5907...");
331837
331837
  const featGlobal = this.getFetch();
331838
- const deviceApiUrl = (0, domain_manager_1.buildDeviceApiUrl)(deviceId);
331838
+ const deviceApiUrl = (0, domain_manager_1.buildDeviceApiUrl)(this.deviceId);
331839
331839
  const jsonData = yield featGlobal(deviceApiUrl, {
331840
331840
  method: "GET",
331841
331841
  headers: {
@@ -331846,7 +331846,7 @@ var require_dist9 = __commonJS({
331846
331846
  if (!jsonData || jsonData === null || !jsonData.machine || !jsonData.authenticate) {
331847
331847
  console.error("\u274C [Auth] ShellX.ai\u8BBE\u5907\u672A\u6CE8\u518C\u6216\u8BA4\u8BC1\u4FE1\u606F\u65E0\u6548");
331848
331848
  const wsServerUrl = (0, domain_manager_1.getWsServerUrl)();
331849
- return `wss://${wsServerUrl}/api/s/${deviceId}`;
331849
+ return `wss://${wsServerUrl}/api/s/${this.deviceId}`;
331850
331850
  }
331851
331851
  console.log("\u2705 [Auth] ShellX.ai\u8BBE\u5907\u8BA4\u8BC1\u6210\u529F");
331852
331852
  console.log(`\u{1F4E1} [Auth] \u8BBE\u5907ID: ${jsonData.authenticate}`);
@@ -334164,6 +334164,29 @@ async function killShellX() {
334164
334164
  return false;
334165
334165
  }
334166
334166
  }
334167
+ async function stopShellX() {
334168
+ console.log("Stopping ShellX...");
334169
+ try {
334170
+ const platform13 = os14.platform();
334171
+ const shellxBin = platform13 === "win32" ? path35.join(SHELLX_BIN_DIR, "shellx.exe") : path35.join(SHELLX_BIN_DIR, "shellx");
334172
+ if (!fs36.existsSync(shellxBin)) {
334173
+ console.warn("ShellX binary not found; skipping stop request.");
334174
+ return false;
334175
+ }
334176
+ const subprocess = child_process.spawn(shellxBin, ["--stop"], {
334177
+ detached: true,
334178
+ stdio: "pipe",
334179
+ windowsHide: false,
334180
+ shell: false,
334181
+ cwd: SHELLX_BIN_DIR
334182
+ });
334183
+ subprocess.unref();
334184
+ return true;
334185
+ } catch (error) {
334186
+ console.error("Failed to stop ShellX:", error);
334187
+ return false;
334188
+ }
334189
+ }
334167
334190
  function isShellXInstalled() {
334168
334191
  const platform13 = os14.platform();
334169
334192
  const shellxBin = platform13 === "win32" ? path35.join(SHELLX_BIN_DIR, "shellx.exe") : path35.join(SHELLX_BIN_DIR, "shellx");
@@ -334230,11 +334253,15 @@ function getDeviceIdFromFile() {
334230
334253
  }
334231
334254
  function saveDeviceIdToFile(deviceId) {
334232
334255
  try {
334256
+ if (!deviceId || typeof deviceId !== "string" || deviceId.trim() === "") {
334257
+ console.warn("Invalid device ID provided, skipping save:", deviceId);
334258
+ return false;
334259
+ }
334233
334260
  const dir = path35.dirname(SHELLX_DEVICE_ID_FILE);
334234
334261
  if (!fs36.existsSync(dir)) {
334235
334262
  fs36.mkdirSync(dir, { recursive: true });
334236
334263
  }
334237
- fs36.writeFileSync(SHELLX_DEVICE_ID_FILE, deviceId, "utf8");
334264
+ fs36.writeFileSync(SHELLX_DEVICE_ID_FILE, deviceId.trim(), "utf8");
334238
334265
  return true;
334239
334266
  } catch (error) {
334240
334267
  console.warn("Failed to save device ID to file:", error);
@@ -334858,7 +334885,9 @@ var init_config3 = __esm({
334858
334885
  }
334859
334886
  },
334860
334887
  onOpen: (deviceId2) => {
334861
- saveDeviceIdToFile(deviceId2);
334888
+ if (deviceId2) {
334889
+ saveDeviceIdToFile(deviceId2);
334890
+ }
334862
334891
  this.startConnectionMonitoring();
334863
334892
  try {
334864
334893
  client.getClient().sendMessage({
@@ -415292,7 +415321,7 @@ var WarningMessage = ({ text }) => {
415292
415321
  };
415293
415322
 
415294
415323
  // packages/cli/src/generated/git-commit.ts
415295
- var GIT_COMMIT_INFO2 = "0db37712";
415324
+ var GIT_COMMIT_INFO2 = "c04c6e88";
415296
415325
 
415297
415326
  // packages/cli/src/ui/components/AboutBox.tsx
415298
415327
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
@@ -429032,7 +429061,7 @@ var __filename3 = fileURLToPath10(import.meta.url);
429032
429061
  var __dirname7 = path59.dirname(__filename3);
429033
429062
  async function getCliVersion() {
429034
429063
  const pkgJson = await getPackageJson(__dirname7);
429035
- return "0.0.21";
429064
+ return "0.0.23";
429036
429065
  }
429037
429066
 
429038
429067
  // packages/cli/src/ui/commands/aboutCommand.ts
@@ -436116,6 +436145,62 @@ ${deviceManagementUrl}`
436116
436145
  }
436117
436146
  };
436118
436147
 
436148
+ // packages/cli/src/ui/commands/stopCommand.ts
436149
+ init_dist6();
436150
+ var stopCommand = {
436151
+ name: "stop",
436152
+ altNames: [],
436153
+ description: "Stop ShellX platform tools service",
436154
+ kind: "built-in" /* BUILT_IN */,
436155
+ action: async (context2) => {
436156
+ const { ui: ui2 } = context2;
436157
+ if (ui2.pendingItem) {
436158
+ ui2.addItem(
436159
+ {
436160
+ type: "error" /* ERROR */,
436161
+ text: "Already processing a request, wait for previous request to complete"
436162
+ },
436163
+ Date.now()
436164
+ );
436165
+ return;
436166
+ }
436167
+ ui2.setPendingItem({
436168
+ type: "info" /* INFO */,
436169
+ text: "Stopping ShellX..."
436170
+ });
436171
+ try {
436172
+ const result = await stopShellX();
436173
+ if (result) {
436174
+ ui2.addItem(
436175
+ {
436176
+ type: "info" /* INFO */,
436177
+ text: `\u2705 ShellX stopped successfully`
436178
+ },
436179
+ Date.now()
436180
+ );
436181
+ } else {
436182
+ ui2.addItem(
436183
+ {
436184
+ type: "error" /* ERROR */,
436185
+ text: `\u274C Failed to stop ShellX`
436186
+ },
436187
+ Date.now()
436188
+ );
436189
+ }
436190
+ } catch (error) {
436191
+ ui2.addItem(
436192
+ {
436193
+ type: "error" /* ERROR */,
436194
+ text: `Stop failed: ${error instanceof Error ? error.message : String(error)}`
436195
+ },
436196
+ Date.now()
436197
+ );
436198
+ } finally {
436199
+ ui2.setPendingItem(null);
436200
+ }
436201
+ }
436202
+ };
436203
+
436119
436204
  // packages/cli/src/ui/commands/quitCommand.ts
436120
436205
  var quitCommand = {
436121
436206
  name: "quit",
@@ -436464,6 +436549,7 @@ var BuiltinCommandLoader = class {
436464
436549
  loginCommand,
436465
436550
  installCommand,
436466
436551
  startCommand,
436552
+ stopCommand,
436467
436553
  // shellx.ai add end
436468
436554
  aboutCommand,
436469
436555
  // authCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellx-cli",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },
@@ -75,6 +75,7 @@
75
75
  },
76
76
  "files": [
77
77
  "bundle/",
78
+ "scripts/install-shellx-files.js",
78
79
  "README.md",
79
80
  "LICENSE"
80
81
  ],
@@ -99,6 +100,7 @@
99
100
  "eslint-plugin-license-header": "^0.8.0",
100
101
  "eslint-plugin-react": "^7.37.5",
101
102
  "eslint-plugin-react-hooks": "^5.2.0",
103
+ "eval": "^0.1.8",
102
104
  "glob": "^10.4.5",
103
105
  "globals": "^16.0.0",
104
106
  "google-artifactregistry-auth": "^3.4.0",
@@ -114,6 +116,9 @@
114
116
  "prettier": "^3.5.3",
115
117
  "react-devtools-core": "^6.1.2",
116
118
  "semver": "^7.7.2",
119
+ "shellx-files-arm64": "^0.0.2",
120
+ "shellx-platform-tools": "^0.0.16",
121
+ "simple-git": "^3.28.0",
117
122
  "strip-ansi": "^7.1.2",
118
123
  "tsx": "^4.20.3",
119
124
  "typescript-eslint": "^8.30.1",
@@ -121,11 +126,7 @@
121
126
  "yargs": "^17.7.2"
122
127
  },
123
128
  "dependencies": {
124
- "eval": "^0.1.8",
125
- "latest-version": "^9.0.0",
126
- "shellx-files-arm64": "^0.0.2",
127
- "shellx-platform-tools": "^0.0.16",
128
- "simple-git": "^3.28.0"
129
+ "latest-version": "^9.0.0"
129
130
  },
130
131
  "optionalDependencies": {
131
132
  "@lydell/node-pty": "1.1.0",
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * install-shellx-files.js
4
+ *
5
+ * @功能简介(ENGLISH below):
6
+ * -------------------------------------------
7
+ * 本脚本用于在安装 shellx-cli 时,根据当前操作系统 (platform) 和架构 (arch),
8
+ * 自动从 npm registry 安装对应的 shellx-files 二进制文件包(比如模拟器或者驱动所需的二进制文件)。
9
+ * 另外,如果不是 Android 沙箱环境,还会自动保证 shellx-platform-tools 工具包的可用性。
10
+ * 最后,会安装必需的 eval 包,这个包是必须的,不像平台特定包那样可选。
11
+ *
12
+ * 用于提升 shellx-cli 的自动安装体验和平台兼容性。
13
+ * 失败不会导致整体安装中断,仅会打印告警信息。
14
+ * 支持通过环境变量指定包版本,如 SHELLX_SHELLX_FILES_WIN32_X64_VERSION=1.0.0 或 SHELLX_EVAL_VERSION=1.0.0
15
+ * -------------------------------------------
16
+ *
17
+ * @Function Overview (ENGLISH):
18
+ * -------------------------------------------
19
+ * This script auto-installs platform-specific shellx-files binaries from npm registry during shellx-cli installation.
20
+ * If not running for 'android' sandbox, it ensures shellx-platform-tools package is also available.
21
+ * Finally, it installs the required 'eval' package, which is mandatory unlike the optional platform-specific packages.
22
+ * Any install failure is non-fatal and only triggers a warning, not breaking the main install process.
23
+ * Version can be specified via environment variables like SHELLX_SHELLX_FILES_WIN32_X64_VERSION=1.0.0 or SHELLX_EVAL_VERSION=1.0.0
24
+ * -------------------------------------------
25
+ *
26
+ * 详细流程说明:
27
+ * 1. 检测当前 OS 与 架构,选出可能的 shellx-files 包名候选。
28
+ * 2. 如果有多个候选包,显示交互式选择菜单让用户选择;如果只有一个则自动选择。
29
+ * 3. 检查环境变量中是否有指定版本(格式:SHELLX_{包名大写并下划线替换横线}_VERSION),默认使用 latest。
30
+ * 4. 直接从 npm registry 安装选中的包。
31
+ * 5. 如果未能安装到任何 shellx-files 包,会给出强烈提示,但不会报错退出。
32
+ * 6. 如果当前不是 SANDBOX=android 环境,从 registry 安装 shellx-platform-tools 工具包。
33
+ * 7. 安装必需的 eval 包,直接从 registry 安装,支持版本指定。
34
+ * 8. 打印最后的完成提示。
35
+ *
36
+ * 适用环境: 仅限 node >= v14, shellx-cli 根目录(通过 npm scripts/preinstall 或直接运行)。
37
+ * 可安全多次运行,支持开发与 CI 场景。
38
+ */
39
+
40
+ import { execSync } from 'node:child_process';
41
+ import readline from 'node:readline';
42
+
43
+ /**
44
+ * 封装执行 shell 命令工具,显示日志,出错返回 false 不 throw
45
+ * @param {string} cmd
46
+ * @returns {boolean} 是否执行成功
47
+ */
48
+ function run(cmd) {
49
+ try {
50
+ execSync(cmd, { stdio: 'inherit' });
51
+ return true;
52
+ } catch (e) {
53
+ console.warn(`Command failed: ${cmd}`);
54
+ return false;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * 交互式选择函数,让用户从候选列表中选择要安装的包和版本
60
+ * @param {string[]} candidates 候选包名数组
61
+ * @returns {Promise<{package: string, version: string}|null>} 用户选择的包信息,包含包名和版本,如果取消则返回 null
62
+ */
63
+ function selectPackage(candidates) {
64
+ return new Promise((resolve) => {
65
+ if (candidates.length === 0) {
66
+ resolve(null);
67
+ return;
68
+ }
69
+
70
+ if (candidates.length === 1) {
71
+ // 只有一个选项,直接返回,默认使用最新版本
72
+ const selectedPkg = candidates[0];
73
+ const version = process.env[`SHELLX_${selectedPkg.toUpperCase().replace(/-/g, '_')}_VERSION`] || 'latest';
74
+ console.log(`[shellx-files] Only one candidate available: ${selectedPkg}@${version}`);
75
+ resolve({ package: selectedPkg, version });
76
+ return;
77
+ }
78
+
79
+ const rl = readline.createInterface({
80
+ input: process.stdin,
81
+ output: process.stdout
82
+ });
83
+
84
+ console.log('\n[shellx-files] Multiple platform candidates available:');
85
+ candidates.forEach((pkg, index) => {
86
+ const envVersion = process.env[`SHELLX_${pkg.toUpperCase().replace(/-/g, '_')}_VERSION`];
87
+ const versionHint = envVersion ? `@${envVersion}` : '@latest';
88
+ console.log(` ${index + 1}. ${pkg}${versionHint}`);
89
+ });
90
+ console.log(' 0. Skip installation');
91
+
92
+ rl.question('\nSelect a package to install (number) or press Enter to auto-select first available: ', (answer) => {
93
+ rl.close();
94
+
95
+ const choice = parseInt(answer.trim(), 10);
96
+
97
+ if (isNaN(choice) || choice === '' || choice === undefined) {
98
+ // 按Enter键或无效输入,使用第一个可用的
99
+ const selectedPkg = candidates[0];
100
+ const version = process.env[`SHELLX_${selectedPkg.toUpperCase().replace(/-/g, '_')}_VERSION`] || 'latest';
101
+ console.log(`[shellx-files] Auto-selecting first available package: ${selectedPkg}@${version}`);
102
+ resolve({ package: selectedPkg, version });
103
+ } else if (choice === 0) {
104
+ // 跳过安装
105
+ console.log('[shellx-files] Skipping shellx-files installation.');
106
+ resolve(null);
107
+ } else if (choice >= 1 && choice <= candidates.length) {
108
+ // 选择指定包
109
+ const selectedPkg = candidates[choice - 1];
110
+ const version = process.env[`SHELLX_${selectedPkg.toUpperCase().replace(/-/g, '_')}_VERSION`] || 'latest';
111
+ console.log(`[shellx-files] Selected: ${selectedPkg}@${version}`);
112
+ resolve({ package: selectedPkg, version });
113
+ } else {
114
+ // 无效选择,使用第一个可用的
115
+ const selectedPkg = candidates[0];
116
+ const version = process.env[`SHELLX_${selectedPkg.toUpperCase().replace(/-/g, '_')}_VERSION`] || 'latest';
117
+ console.log(`[shellx-files] Invalid choice, auto-selecting first available package: ${selectedPkg}@${version}`);
118
+ resolve({ package: selectedPkg, version });
119
+ }
120
+ });
121
+ });
122
+ }
123
+
124
+ // platform 值: 'darwin' | 'linux' | 'win32',但 Node.js process.platform 实际上不包含 'android'
125
+ // 如果在 Android Termux、Node.js 环境,这里会取到 'linux'
126
+ const platform = process.platform;
127
+ // arch 值: 'x64' | 'arm64' | 其他,在 Android 设备常为 'arm64'
128
+ const arch = process.arch;
129
+
130
+ /**
131
+ * 不同平台和架构对应的 shellx-files 包候选矩阵,优先级从前到后。
132
+ * 可根据实际支持覆盖扩展。
133
+ */
134
+ const candidateMap = {
135
+ darwin: {
136
+ arm64: ['shellx-files-arm64'],
137
+ x64: ['shellx-files-arm64'],
138
+ },
139
+ linux: {
140
+ arm64: ['shellx-files-arm64'],
141
+ x64: ['shellx-files-linux-x64', 'shellx-files-arm64'],
142
+ },
143
+ win32: {
144
+ arm64: ['shellx-files-win32-arm64', 'shellx-files-arm64'],
145
+ x64: ['shellx-files-win32-x64'],
146
+ },
147
+ };
148
+
149
+ /**
150
+ * 决定候选架构 key(只区分最主流的两种;特殊架构可自行补充)
151
+ */
152
+ const archKey = arch === 'x64' ? 'x64' : arch === 'arm64' ? 'arm64' : arch;
153
+
154
+ // 主函数包装,使脚本支持 async/await
155
+ async function main() {
156
+ // 检测当前 OS 与 架构,选出可能的 shellx-files 包名候选。
157
+ const archKey = arch === 'x64' ? 'x64' : arch === 'arm64' ? 'arm64' : arch;
158
+ const platformCandidates = ['shellx-files-arm64'];
159
+ // (candidateMap[platform] && candidateMap[platform][archKey]) || ['shellx-files-arm64'];
160
+
161
+ /**
162
+ * 安装过程核心:
163
+ * 让用户选择要安装的包和版本,然后尝试安装选中的包。
164
+ */
165
+ let installed = false;
166
+ const selectedPkgInfo = await selectPackage(platformCandidates);
167
+ if (selectedPkgInfo) {
168
+ const { package: selectedPkg, version } = selectedPkgInfo;
169
+ // 直接从 registry 安装,非致命
170
+ const installCmd = version === 'latest'
171
+ ? `npm install --no-audit --no-fund ${selectedPkg}`
172
+ : `npm install --no-audit --no-fund ${selectedPkg}@${version}`;
173
+ console.log(`[shellx-files] Attempting to install registry package ${selectedPkg}@${version}`);
174
+ installed = run(installCmd);
175
+ }
176
+
177
+ /**
178
+ * 如果所有候选都没装上,告警但不 throw
179
+ */
180
+ if (!installed && selectedPkgInfo) {
181
+ const { package: selectedPkg, version } = selectedPkgInfo;
182
+ console.warn(
183
+ `[shellx-files] Failed to install selected package ${selectedPkg}@${version} for ${platform}-${arch}.` +
184
+ ' If you need platform binaries, please publish the appropriate package or add it to the workspace.'
185
+ );
186
+ }
187
+
188
+ /**
189
+ * 检查 shellx-platform-tools 工具包,如果不是 Android 沙箱都要自动装好,直接从 registry 安装。
190
+ */
191
+ const sandbox = process.env['SANDBOX'];
192
+ if (sandbox !== 'android') {
193
+ // 直接从 registry 安装,不存在也不会中断
194
+ console.log('[shellx-files] Attempting to install shellx-platform-tools from registry (if available)');
195
+ run('npm install --no-audit --no-fund shellx-platform-tools || true');
196
+ }
197
+
198
+ /**
199
+ * 安装必须的 eval 包,直接从 registry 安装。
200
+ * 这个包是必需的,不像平台特定包那样可选。
201
+ */
202
+ const evalPkg = 'eval';
203
+ const evalVersion = process.env['SHELLX_EVAL_VERSION'] || 'latest';
204
+ // 直接从 registry 安装
205
+ const evalInstallCmd = evalVersion === 'latest'
206
+ ? `npm install --no-audit --no-fund ${evalPkg}`
207
+ : `npm install --no-audit --no-fund ${evalPkg}@${evalVersion}`;
208
+ console.log(`[shellx-files] Attempting to install eval package from registry (${evalVersion})`);
209
+ const evalInstalled = run(evalInstallCmd);
210
+ if (!evalInstalled) {
211
+ console.warn(`[shellx-files] Failed to install required eval package. This may affect functionality.`);
212
+ }
213
+
214
+ console.log('[shellx-files] install-shellx-files finished (non-fatal failures are allowed).');
215
+ }
216
+
217
+ // 运行主函数
218
+ main().catch((error) => {
219
+ console.error('[shellx-files] Unexpected error:', error);
220
+ process.exit(1);
221
+ });
222
+