easytouch-windows 2.0.3 → 2.0.5

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
@@ -7,7 +7,6 @@
7
7
  目前支持以下操作系统的 x64 和 ARM64 两种 CPU 架构:
8
8
 
9
9
  - [x] Windows
10
-
11
10
  - [x] Linux
12
11
  - [x] MACOS(目前缺少设备验证功能)
13
12
 
@@ -35,34 +34,40 @@
35
34
 
36
35
  ### 安装
37
36
 
38
- 推荐安装带自动平台选择能力的启动包;如果你只想安装当前系统,也可以直接安装对应平台包:
37
+ 推荐安装带初始化 helper 的聚合包;如果你只想安装当前系统,也可以直接安装对应平台包:
39
38
 
40
39
  ```bash
41
- # 推荐:自动匹配当前平台
40
+ # 推荐:聚合包,执行 easytouch init 生成 et
42
41
  npm i -g @whuanle/easytouch
43
42
 
44
- # Windows
43
+ # 只安装当前系统的平台包
45
44
  npm i -g easytouch-windows
46
-
47
- # Linux
48
45
  npm i -g easytouch-linux
49
-
50
- # macOS
51
46
  npm i -g easytouch-macos
52
47
  ```
53
48
 
49
+ `@whuanle/easytouch` 会在包内直接附带 Windows、Linux、macOS 的 x64 和 arm64 原生二进制。执行 `easytouch init` 后,会按当前主机平台和 CPU 架构复制出真正可直接调用的 `et` 文件。
54
50
 
51
+ 初始化命令:
55
52
 
56
- `@whuanle/easytouch` 会在当前主机上调用对应的平台包;平台包内部同时包含 x64 和 arm64 二进制,安装后会根据当前 CPU 架构自动选择对应程序文件。
53
+ ```bash
54
+ # 聚合包
55
+ easytouch init
57
56
 
58
- 如果是 Windows,安装后在 `AppData/Roaming/npm` 目录会发现名为 `et` 的文件。
57
+ # 只安装当前系统的平台包时
58
+ easytouch-windows init
59
+ easytouch-linux init
60
+ easytouch-macos init
61
+ ```
59
62
 
60
- ![image-20260405194137861](images/image-20260405194137861.png)
63
+ `init` 默认会把原生文件写回安装包目录,并同步刷新 `et` 命令入口。
61
64
 
62
65
 
63
66
 
64
67
  ### 使用示例
65
68
 
69
+ 以下示例假设你已经通过 `init` 生成好了原生 `et`:
70
+
66
71
  截取屏幕。
67
72
 
68
73
  ```
@@ -107,99 +112,56 @@ npx skills add https://github.com/whuanle/EasyTouch
107
112
 
108
113
 
109
114
 
110
- **本地安装后(推荐)**
115
+ **全局安装后(推荐)**
111
116
 
112
- 先执行:
117
+ 如果你已经全局安装了聚合包,可以直接使用 helper 命令生成原生 `et`:
113
118
 
114
119
  ```bash
115
- npm i @whuanle/easytouch
116
- npx @whuanle/easytouch init
117
- ```
118
-
119
- 如果安装的是 `@whuanle/easytouch`,这一步会先自动安装当前系统对应的平台包,再复制出原生 `et` 文件。
120
-
121
- 如果你已经在项目里安装了依赖,也可以直接执行 `node ./node_modules/@whuanle/easytouch/init.js`,但这只适用于本地安装目录。
122
-
123
- 执行后会生成:
124
-
125
- - Windows:`./node_modules/@whuanle/easytouch/et.exe`
126
- - Linux / macOS:`./node_modules/@whuanle/easytouch/et`
127
-
128
- 然后在 MCP 配置里直接指向这个原生文件:
129
-
130
- ```json
131
- {
132
- "mcpServers": {
133
- "easytouch": {
134
- "command": "<你的项目路径>/node_modules/@whuanle/easytouch/et",
135
- "args": ["mcp-stdio"]
136
- }
137
- }
138
- }
120
+ npm i -g @whuanle/easytouch
121
+ easytouch init
139
122
  ```
140
123
 
141
- > Windows 请把文件名写成 `et.exe`。Linux / macOS 写 `et`。
124
+ 默认会把 `et` 生成到全局安装目录下的包目录里,并同步刷新全局 `et` 命令。
142
125
 
143
- **全局安装后**
126
+ 默认路径通常是:
144
127
 
145
- 如果你已经全局安装并且宿主能正确处理 PATH,也仍然可以直接使用全局 `et`。首次运行时,如果平台包还没装好,启动器也会自动补装当前平台包:
128
+ - Windows:`<npm root -g>/@whuanle/easytouch/et.exe`
129
+ - Linux / macOS:`<npm root -g>/@whuanle/easytouch/et`
146
130
 
147
- ```bash
148
- npm i -g @whuanle/easytouch
149
- et init
150
- ```
131
+ 全局命令入口通常是:
151
132
 
152
- 生成完原生文件后,MCP 仍然可以直接使用全局 `et`:
133
+ - Windows:`<npm prefix -g>/et.cmd`
134
+ - Linux / macOS:`<npm prefix -g>/bin/et`
153
135
 
154
- ```json
155
- {
156
- "mcpServers": {
157
- "easytouch": {
158
- "command": "et",
159
- "args": ["mcp-stdio"]
160
- }
161
- }
162
- }
163
- ```
164
-
165
- 如果你只是想手工执行脚本而不走 `et init`,需要先找到全局安装目录,例如:
136
+ 如果需要查看你自己机器上的真实路径,可以执行:
166
137
 
167
138
  ```bash
168
139
  npm root -g
140
+ npm prefix -g
169
141
  ```
170
142
 
171
- 然后再执行对应路径下的 `init.js`,而不是 `./node_modules/...`:
143
+ 也可以显式指定输出位置:
172
144
 
173
145
  ```bash
174
- node <全局安装目录>/@whuanle/easytouch/init.js
146
+ easytouch init --output <你想放置 et 的路径>
175
147
  ```
176
148
 
177
- **宿主程序不走 PATH 时(旧方式)**
178
-
179
- - Windows:把 `command` 改成 `C:\\Users\\<你自己的用户名>\\AppData\\Roaming\\npm\\et.cmd`
180
- - Linux / macOS:先执行 `npm prefix -g`,然后把 `command` 改成 `<prefix>/bin/et`
149
+ 如果你安装的是平台包,初始化命令分别是 `easytouch-windows init`、`easytouch-linux init`、`easytouch-macos init`。
181
150
 
182
- **不想初始化原生文件时(备用)**
183
-
184
- 如果你不想先执行 `init.js`,也可以临时通过 `npx` 启动。这里同样建议统一使用 `@whuanle/easytouch`,不要再按平台分别写包名。首次运行可能会多花一点时间,因为会自动安装当前平台包。
185
-
186
- - Windows:`command` 推荐写 `npx.cmd`
187
- - Linux / macOS:`command` 写 `npx`
151
+ 生成完原生文件后,MCP 直接调用这个文件即可:
188
152
 
189
153
  ```json
190
154
  {
191
155
  "mcpServers": {
192
156
  "easytouch": {
193
- "command": "npx.cmd",
194
- "args": ["-y", "@whuanle/easytouch", "mcp-stdio"]
157
+ "command": "et",
158
+ "args": ["mcp-stdio"]
195
159
  }
196
160
  }
197
161
  }
198
162
  ```
199
163
 
200
- > 如果是在 Windows 的 GUI 程序中配置 MCP,直接用 `init.js` 生成的 `et.exe` 最稳。只有在走 `npx` 或全局 npm 命令时,才需要关心 `npx.cmd`、`et.cmd` 这些桥接文件;常见失败表现就是 `LOCAL_PROCESS_ERROR`。
201
-
202
- Linux / macOS 如果使用这段备用配置,把 `command` 改回 `npx` 即可。
164
+ 如果宿主程序不走 PATH,再改成 `npm prefix -g` `npm root -g` 对应的实际路径。
203
165
 
204
166
  ### 语义元素定位
205
167
 
package/SKILL.md CHANGED
@@ -364,21 +364,23 @@ et mcp-stdio --output json
364
364
 
365
365
  ### 配置示例
366
366
 
367
- 优先在安装后执行包内 `init.js`,把真实原生 `et` 程序复制出来,再让 MCP 直接调用这个文件:
367
+ 优先在全局安装后执行 `init`,把真实原生 `et` 程序复制出来,再让 MCP 直接调用这个文件:
368
368
 
369
369
  ```bash
370
- npm i @whuanle/easytouch
371
- npx @whuanle/easytouch init
370
+ npm i -g @whuanle/easytouch
371
+ easytouch init
372
372
  ```
373
373
 
374
- 如果安装的是 `@whuanle/easytouch`,这一步会先自动安装当前系统对应的平台包,再生成原生 `et` 文件。
375
-
376
- 如果依赖已经装在当前项目里,也可以直接执行 `node ./node_modules/@whuanle/easytouch/init.js`,但这只适用于本地安装目录。
374
+ 这一步会直接从包内复制当前主机对应的原生 `et` 文件。
377
375
 
378
376
  生成后的默认路径:
379
377
 
380
- - Windows:`./node_modules/@whuanle/easytouch/et.exe`
381
- - Linux / macOS:`./node_modules/@whuanle/easytouch/et`
378
+ - Windows:`<npm root -g>/@whuanle/easytouch/et.exe`
379
+ - Linux / macOS:`<npm root -g>/@whuanle/easytouch/et`
380
+
381
+ 同时会刷新全局 `et` 命令。
382
+
383
+ 也可以通过 `--output` 指定输出位置。
382
384
 
383
385
  推荐配置:
384
386
 
@@ -386,7 +388,7 @@ npx @whuanle/easytouch init
386
388
  {
387
389
  "mcpServers": {
388
390
  "easytouch": {
389
- "command": "<你的项目路径>/node_modules/@whuanle/easytouch/et",
391
+ "command": "et",
390
392
  "args": ["mcp-stdio"]
391
393
  }
392
394
  }
@@ -395,39 +397,17 @@ npx @whuanle/easytouch init
395
397
 
396
398
  Windows 请把文件名写成 `et.exe`。Linux / macOS 写 `et`。
397
399
 
398
- 如果是全局安装:
400
+ 默认会把 `et` 生成到全局安装目录下的包目录里,并同步刷新全局 `et` 命令。也可以显式指定输出路径:
399
401
 
400
402
  ```bash
401
- npm i -g @whuanle/easytouch
402
- et init
403
+ easytouch init --output <你想放置 et 的路径>
403
404
  ```
404
405
 
405
- 不要再写成 `node ./node_modules/@whuanle/easytouch/init.js`,因为全局安装不在当前项目目录下。
406
-
407
- 如果你已经全局安装并且宿主能正确处理 PATH,也可以继续直接调用全局 `et`。首次运行时,如果平台包缺失,启动器也会自动安装当前平台包。
408
-
409
- 如果宿主程序不能从 PATH 找到命令,旧方式仍可用:
410
-
411
- - Windows:把 `command` 改成 `C:\Users\<你自己的用户名>\AppData\Roaming\npm\et.cmd`
412
- - Linux / macOS:先执行 `npm prefix -g`,再把 `command` 改成 `<prefix>/bin/et`
413
-
414
- 如果不想执行 `init.js`,也可以临时通过 `npx` 启动。首次运行可能会稍慢,因为会自动安装当前平台包:
406
+ 如果你直接安装的是平台包,初始化命令分别是 `easytouch-windows init`、`easytouch-linux init`、`easytouch-macos init`。
415
407
 
416
- - Windows:`command` 推荐写 `npx.cmd`
417
- - Linux / macOS:`command` 写 `npx`
418
-
419
- ```json
420
- {
421
- "mcpServers": {
422
- "easytouch": {
423
- "command": "npx.cmd",
424
- "args": ["-y", "@whuanle/easytouch", "mcp-stdio"]
425
- }
426
- }
427
- }
428
- ```
408
+ 如果需要查看实际路径,可以执行 `npm root -g``npm prefix -g`。
429
409
 
430
- Linux / macOS 如果使用这段备用配置,把 `command` 改回 `npx` 即可。
410
+ 如果宿主能正确处理 PATH,MCP 直接写 `command: "et"` 即可;否则改成 `npm prefix -g` 或 `npm root -g` 对应的实际路径。
431
411
 
432
412
  如果 Windows 宿主报 `LOCAL_PROCESS_ERROR`,优先改用 `init.js` 生成的 `et.exe`;如果仍走 npm 命令,再检查这里是不是还写成了 `npx`。
433
413
 
Binary file
Binary file
package/init.js CHANGED
@@ -3,19 +3,23 @@
3
3
  const fs = require("node:fs");
4
4
  const path = require("node:path");
5
5
 
6
- const archDirectoryByNodeArch = {
7
- x64: "x64",
8
- arm64: "arm64",
9
- };
6
+ const helperCommandName = "easytouch-windows";
7
+ const generatedCommandName = "et";
8
+
9
+ const supportedArchitectures = new Set(["x64", "arm64"]);
10
10
 
11
11
  function printUsage() {
12
12
  process.stdout.write(
13
13
  [
14
14
  "Usage:",
15
- " node init.js [--output <path>] [--force]",
15
+ " easytouch-windows init [--output <path>] [--force]",
16
+ " npx easytouch-windows init [--output <path>] [--force]",
17
+ " node init.js [init] [--output <path>] [--force]",
16
18
  "",
17
19
  "Behavior:",
18
- " Copies the current Windows binary into the package directory as 'et.exe' by default.",
20
+ " Copies the current Windows binary out of this package as 'et.exe' by default.",
21
+ " By default, writes into this package directory.",
22
+ " When installed through npm, also refreshes the 'et' command if possible.",
19
23
  " Use --output to write to a different file or directory.",
20
24
  ].join("\n") + "\n"
21
25
  );
@@ -26,7 +30,16 @@ function fail(message) {
26
30
  process.exit(1);
27
31
  }
28
32
 
29
- function parseArgs(argv) {
33
+ function normalizeArgs(argv) {
34
+ if (argv[0] === "init") {
35
+ return argv.slice(1);
36
+ }
37
+
38
+ return argv;
39
+ }
40
+
41
+ function parseArgs(rawArgv) {
42
+ const argv = normalizeArgs(rawArgv);
30
43
  let output = null;
31
44
  let force = false;
32
45
 
@@ -54,11 +67,11 @@ function parseArgs(argv) {
54
67
  return { output, force };
55
68
  }
56
69
 
57
- function getAvailableArchitectures() {
70
+ function getAvailableBinaries() {
58
71
  try {
59
72
  return fs
60
73
  .readdirSync(path.join(__dirname, "bin"), { withFileTypes: true })
61
- .filter((entry) => entry.isDirectory())
74
+ .filter((entry) => entry.isFile() && entry.name.startsWith("et_"))
62
75
  .map((entry) => entry.name)
63
76
  .sort();
64
77
  } catch {
@@ -66,28 +79,36 @@ function getAvailableArchitectures() {
66
79
  }
67
80
  }
68
81
 
69
- function resolveBinaryPath() {
70
- const archDirectory = archDirectoryByNodeArch[process.arch];
71
- if (!archDirectory) {
72
- fail(`Unsupported architecture '${process.arch}' on platform '${process.platform}'.`);
82
+ function binaryNameForArch(arch = process.arch) {
83
+ if (!supportedArchitectures.has(arch)) {
84
+ fail(`Unsupported architecture '${arch}' on platform '${process.platform}'.`);
73
85
  }
74
86
 
75
- const sourcePath = path.join(__dirname, "bin", archDirectory, "et.exe");
87
+ return `et_${arch}.exe`;
88
+ }
89
+
90
+ function resolveBinaryPath() {
91
+ const fileName = binaryNameForArch();
92
+ const sourcePath = path.join(__dirname, "bin", fileName);
76
93
  if (!fs.existsSync(sourcePath)) {
77
- const availableArchitectures = getAvailableArchitectures();
78
- const availableMessage = availableArchitectures.length
79
- ? ` Available architectures: ${availableArchitectures.join(", ")}.`
94
+ const availableBinaries = getAvailableBinaries();
95
+ const availableMessage = availableBinaries.length
96
+ ? ` Available binaries: ${availableBinaries.join(", ")}.`
80
97
  : "";
81
- fail(`The package is missing 'et.exe' for architecture '${archDirectory}'.${availableMessage}`);
98
+ fail(`The package is missing '${fileName}' for architecture '${process.arch}'.${availableMessage}`);
82
99
  }
83
100
 
84
101
  return sourcePath;
85
102
  }
86
103
 
104
+ function defaultOutputPath() {
105
+ return path.join(__dirname, "et.exe");
106
+ }
107
+
87
108
  function resolveOutputPath(requestedOutput) {
88
109
  let outputPath = requestedOutput
89
110
  ? path.resolve(process.cwd(), requestedOutput)
90
- : path.join(__dirname, "et.exe");
111
+ : defaultOutputPath();
91
112
 
92
113
  if (fs.existsSync(outputPath)) {
93
114
  const stat = fs.statSync(outputPath);
@@ -103,6 +124,22 @@ function resolveOutputPath(requestedOutput) {
103
124
  return outputPath;
104
125
  }
105
126
 
127
+ function filesAreIdentical(leftPath, rightPath) {
128
+ try {
129
+ const leftStat = fs.statSync(leftPath);
130
+ const rightStat = fs.statSync(rightPath);
131
+ if (leftStat.size !== rightStat.size) {
132
+ return false;
133
+ }
134
+
135
+ const leftContent = fs.readFileSync(leftPath);
136
+ const rightContent = fs.readFileSync(rightPath);
137
+ return leftContent.equals(rightContent);
138
+ } catch {
139
+ return false;
140
+ }
141
+ }
142
+
106
143
  function initializeBinary(sourcePath, destinationPath, force) {
107
144
  const resolvedSource = path.resolve(sourcePath);
108
145
  const resolvedDestination = path.resolve(destinationPath);
@@ -111,8 +148,15 @@ function initializeBinary(sourcePath, destinationPath, force) {
111
148
  return;
112
149
  }
113
150
 
114
- if (fs.existsSync(resolvedDestination) && !force) {
115
- fail(`Destination '${resolvedDestination}' already exists. Use --force to overwrite it.`);
151
+ if (fs.existsSync(resolvedDestination)) {
152
+ if (filesAreIdentical(resolvedSource, resolvedDestination)) {
153
+ process.stdout.write(`et init: binary already available at ${resolvedDestination}\n`);
154
+ return;
155
+ }
156
+
157
+ if (!force) {
158
+ fail(`Destination '${resolvedDestination}' already exists. Use --force to overwrite it.`);
159
+ }
116
160
  }
117
161
 
118
162
  fs.mkdirSync(path.dirname(resolvedDestination), { recursive: true });
@@ -120,5 +164,157 @@ function initializeBinary(sourcePath, destinationPath, force) {
120
164
  process.stdout.write(`et init: copied ${resolvedSource} -> ${resolvedDestination}\n`);
121
165
  }
122
166
 
167
+ function findNodeModulesRoot(startDir) {
168
+ let current = path.resolve(startDir);
169
+
170
+ while (true) {
171
+ if (path.basename(current) === "node_modules") {
172
+ return current;
173
+ }
174
+
175
+ const parent = path.dirname(current);
176
+ if (parent === current) {
177
+ return null;
178
+ }
179
+ current = parent;
180
+ }
181
+ }
182
+
183
+ function commandFileCandidates(commandName) {
184
+ return [`${commandName}.cmd`, `${commandName}.ps1`, commandName];
185
+ }
186
+
187
+ function uniquePaths(paths) {
188
+ return [...new Set(paths.filter(Boolean).map((entry) => path.resolve(entry)))];
189
+ }
190
+
191
+ function resolveCommandBinDir(startDir, commandName) {
192
+ const nodeModulesRoot = findNodeModulesRoot(startDir);
193
+ if (!nodeModulesRoot) {
194
+ return null;
195
+ }
196
+
197
+ const installRoot = path.dirname(nodeModulesRoot);
198
+ const candidates = uniquePaths([path.join(nodeModulesRoot, ".bin"), installRoot]);
199
+
200
+ for (const candidate of candidates) {
201
+ for (const fileName of commandFileCandidates(commandName)) {
202
+ if (fs.existsSync(path.join(candidate, fileName))) {
203
+ return candidate;
204
+ }
205
+ }
206
+ }
207
+
208
+ for (const candidate of candidates) {
209
+ if (fs.existsSync(candidate)) {
210
+ return candidate;
211
+ }
212
+ }
213
+
214
+ return null;
215
+ }
216
+
217
+ function managedCommandMarker() {
218
+ return "EasyTouch generated by init";
219
+ }
220
+
221
+ function readTextFile(filePath) {
222
+ try {
223
+ return fs.readFileSync(filePath, "utf8");
224
+ } catch {
225
+ return null;
226
+ }
227
+ }
228
+
229
+ function assertManagedCommandTarget(filePath, force) {
230
+ if (!fs.existsSync(filePath)) {
231
+ return;
232
+ }
233
+
234
+ const content = readTextFile(filePath);
235
+ if (content && content.includes(managedCommandMarker())) {
236
+ return;
237
+ }
238
+
239
+ if (!force) {
240
+ fail(`Command '${filePath}' already exists. Use --force to overwrite it.`);
241
+ }
242
+ }
243
+
244
+ function writeManagedCommand(filePath, content, force, executable) {
245
+ assertManagedCommandTarget(filePath, force);
246
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
247
+ fs.writeFileSync(filePath, content, "utf8");
248
+ if (executable) {
249
+ fs.chmodSync(filePath, 0o755);
250
+ }
251
+ }
252
+
253
+ function escapeForSingleQuotedPowerShell(value) {
254
+ return value.replace(/'/g, "''");
255
+ }
256
+
257
+ function relativeShellPath(fromDir, toFile) {
258
+ return path.relative(fromDir, toFile).split(path.sep).join("/");
259
+ }
260
+
261
+ function installGeneratedCommand(targetBinaryPath, force) {
262
+ const binDir = resolveCommandBinDir(__dirname, helperCommandName);
263
+ if (!binDir) {
264
+ return;
265
+ }
266
+
267
+ const resolvedTarget = path.resolve(targetBinaryPath);
268
+ const relativeWindowsPath = path.relative(binDir, resolvedTarget);
269
+ const relativePosixPath = relativeShellPath(binDir, resolvedTarget);
270
+
271
+ writeManagedCommand(
272
+ path.join(binDir, generatedCommandName),
273
+ [
274
+ "#!/bin/sh",
275
+ `# ${managedCommandMarker()}`,
276
+ 'basedir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)',
277
+ `exec "$basedir/${relativePosixPath}" "$@"`,
278
+ "",
279
+ ].join("\n"),
280
+ force,
281
+ true
282
+ );
283
+
284
+ writeManagedCommand(
285
+ path.join(binDir, `${generatedCommandName}.cmd`),
286
+ [
287
+ "@ECHO off",
288
+ `:: ${managedCommandMarker()}`,
289
+ "SETLOCAL",
290
+ `SET \"_ET_TARGET=%~dp0${relativeWindowsPath}\"`,
291
+ '"%_ET_TARGET%" %*',
292
+ "",
293
+ ].join("\r\n"),
294
+ force,
295
+ false
296
+ );
297
+
298
+ writeManagedCommand(
299
+ path.join(binDir, `${generatedCommandName}.ps1`),
300
+ [
301
+ `# ${managedCommandMarker()}`,
302
+ `$target = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '${escapeForSingleQuotedPowerShell(relativeWindowsPath)}'))`,
303
+ "& $target @args",
304
+ "exit $LASTEXITCODE",
305
+ "",
306
+ ].join("\r\n"),
307
+ force,
308
+ false
309
+ );
310
+
311
+ process.stdout.write(`et init: updated command '${generatedCommandName}' in ${binDir}\n`);
312
+ }
313
+
123
314
  const options = parseArgs(process.argv.slice(2));
124
- initializeBinary(resolveBinaryPath(), resolveOutputPath(options.output), options.force);
315
+ const outputPath = resolveOutputPath(options.output);
316
+ initializeBinary(resolveBinaryPath(), outputPath, options.force);
317
+
318
+ if (path.resolve(outputPath) === path.resolve(defaultOutputPath())) {
319
+ installGeneratedCommand(outputPath, options.force);
320
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easytouch-windows",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "Windows binary distribution for EasyTouch with x64 and arm64 binaries.",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "type": "commonjs",
@@ -13,7 +13,9 @@
13
13
  },
14
14
  "homepage": "https://github.com/whuanle/EasyTouch#readme",
15
15
  "bin": {
16
- "et": "bin/et.js"
16
+ "easytouch-windows": "init.js",
17
+ "et_x64": "bin/et_x64.exe",
18
+ "et_arm64": "bin/et_arm64.exe"
17
19
  },
18
20
  "os": [
19
21
  "win32"
package/bin/et.js DELETED
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const cp = require("node:child_process");
4
- const fs = require("node:fs");
5
- const path = require("node:path");
6
-
7
- const archDirectoryByNodeArch = {
8
- x64: "x64",
9
- arm64: "arm64",
10
- };
11
-
12
- const packageName = require(path.join(__dirname, "..", "package.json")).name;
13
-
14
- function fail(message) {
15
- process.stderr.write(`et: ${message}\n`);
16
- process.exit(1);
17
- }
18
-
19
- function getAvailableArchitectures() {
20
- try {
21
- return fs
22
- .readdirSync(__dirname, { withFileTypes: true })
23
- .filter((entry) => entry.isDirectory())
24
- .map((entry) => entry.name)
25
- .sort();
26
- } catch {
27
- return [];
28
- }
29
- }
30
-
31
- function resolveBinaryPath() {
32
- const archDirectory = archDirectoryByNodeArch[process.arch];
33
- if (!archDirectory) {
34
- fail(`Unsupported architecture '${process.arch}' on platform '${process.platform}'.`);
35
- }
36
-
37
- const binaryName = process.platform === "win32" ? "et.exe" : "et";
38
- const binaryPath = path.join(__dirname, archDirectory, binaryName);
39
- if (!fs.existsSync(binaryPath)) {
40
- const availableArchitectures = getAvailableArchitectures();
41
- const availableMessage = availableArchitectures.length
42
- ? ` Available architectures: ${availableArchitectures.join(", ")}.`
43
- : "";
44
- fail(
45
- `The platform package '${packageName}' is missing '${binaryName}' for architecture '${archDirectory}'.${availableMessage}`
46
- );
47
- }
48
-
49
- return binaryPath;
50
- }
51
-
52
- const result = cp.spawnSync(resolveBinaryPath(), process.argv.slice(2), {
53
- stdio: "inherit",
54
- });
55
-
56
- if (result.error) {
57
- fail(result.error.message);
58
- }
59
-
60
- process.exit(result.status ?? 1);