@leviyuan/lodestar 0.11.3 → 0.11.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leviyuan/lodestar",
3
- "version": "0.11.3",
3
+ "version": "0.11.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1,30 +1,17 @@
1
1
  #!/usr/bin/env node
2
- // Auto-launch lodestar-setup right after `npm i -g`. Tricky because npm
3
- // 7+ default pipes postinstall stdio into its own log — `console.log`
4
- // is invisible, plain `stdio:'inherit'` spawn inherits the same pipe.
5
- // Two escape routes here:
2
+ // Postinstall banner 只告诉用户下一步跑什么, 不在这里拉起向导。
6
3
  //
7
- // Windows: spawn `cmd /c start "" cmd /k node <bundle>` to open a
8
- // NEW console window. The new window has its own real terminal,
9
- // completely outside npm's pipe; `/k` keeps the window open after
10
- // the wizard exits so the user can read the success message.
4
+ // 为什么不自动拉向导: npm 7+ pipe postinstall stdio, 自动拉向导只能
5
+ // 靠接管 /dev/tty 把终端塞给子进程 —— 这套机制脆弱 (作者原注 "Tricky")。
6
+ // 实测在部分 mac 环境 /dev/tty 接管失败时, 向导的 readline 拿不到输入死等,
7
+ // 而父进程 npm wait 在向导退出上 npm 和向导互相卡死, 终端冻住 (文件
8
+ // 其实早装好了); 杀掉还会触发 npm 回滚删文件。
11
9
  //
12
- // Linux/macOS: fs.openSync('/dev/tty','r+') gives a fd attached to
13
- // the user's real terminal. Pass it as the spawned child's stdio
14
- // and it inherits the terminal directly, bypassing npm.
15
- //
16
- // Banner output goes to the same terminal device, not console.log, so
17
- // the user sees "✓ Lodestar 已安装" even though npm captures stdout.
18
- //
19
- // If both escape routes fail (no console / CI / weird sandbox), we
20
- // fall back to a hint, and the daemon entry (cli.ts) auto-triggers the
21
- // wizard on first run regardless.
10
+ // 稳的做法是 trigger-on-first-run: 用户在真终端首跑 lodestar-daemon 时,
11
+ // cli.ts 发现没 config + isTTY 就自动进入向导 (真 TTY, readline 一定正常)。
12
+ // 所以这里只打个提示就 process.exit(0), spawn 任何子进程, 永不卡死。
22
13
 
23
- const { spawn } = require('child_process')
24
14
  const fs = require('fs')
25
- const path = require('path')
26
-
27
- const setupBundle = path.join(__dirname, '..', 'dist', 'lodestar-setup.js')
28
15
 
29
16
  function termWrite (msg) {
30
17
  try {
@@ -36,62 +23,13 @@ function termWrite (msg) {
36
23
  fs.writeFileSync('/dev/tty', msg)
37
24
  }
38
25
  } catch {
39
- // No console accessiblewrite to stdout (npm likely swallows it).
26
+ // No controlling tty (CI / pipe) best-effort stdout, npm 多半会吞掉。
40
27
  try { process.stdout.write(msg) } catch {}
41
28
  }
42
29
  }
43
30
 
44
- function fallback (reason) {
45
- if (reason) termWrite(` \x1b[2m(${reason})\x1b[0m\n`)
46
- termWrite(' 下一步: cmd / PowerShell 里跑 \x1b[32mlodestar-daemon\x1b[0m')
47
- termWrite(' (会自动拉起向导)\n')
48
- termWrite(' 或者只跑向导: \x1b[32mlodestar-setup\x1b[0m\n\n')
49
- process.exit(0)
50
- }
51
-
52
- termWrite('\n \x1b[1m\x1b[36m✓ Lodestar 已安装\x1b[0m\n\n')
53
-
54
- // Path 1: npm started us with --foreground-scripts. Our own stdio is
55
- // already a real TTY. Just inherit-spawn the wizard, same window.
56
- if (process.stdout.isTTY && process.stdin.isTTY) {
57
- termWrite(' \x1b[2m启动配置向导...\x1b[0m\n\n')
58
- const child = spawn(process.execPath, [setupBundle], { stdio: 'inherit' })
59
- child.on('exit', (code) => process.exit(code == null ? 0 : code))
60
- child.on('error', (e) => fallback(`spawn 失败: ${e.message}`))
61
- return
62
- }
63
-
64
- // Path 2: Windows. Open a NEW console window — that window is outside
65
- // npm's stdio pipe and has a real terminal of its own. `cmd /k` keeps
66
- // it open after the wizard exits so the success message is readable.
67
- if (process.platform === 'win32') {
68
- termWrite(' \x1b[2m启动配置向导 (新窗口) ...\x1b[0m\n')
69
- termWrite(' \x1b[2m向导会在另一个 cmd 窗口里跑, 完成后按 Enter / 输入 exit 关掉它即可。\x1b[0m\n\n')
70
- try {
71
- const child = spawn(
72
- 'cmd.exe',
73
- ['/c', 'start', 'Lodestar Setup', 'cmd', '/k', process.execPath, setupBundle],
74
- { detached: true, stdio: 'ignore', windowsHide: false },
75
- )
76
- child.unref()
77
- process.exit(0)
78
- } catch (e) {
79
- fallback(`新窗口启动失败: ${e.message}`)
80
- }
81
- return
82
- }
31
+ termWrite('\n \x1b[1m\x1b[36m✓ Lodestar 已安装\x1b[0m\n')
32
+ termWrite('\n \x1b[2m下一步: 在终端跑 \x1b[32mlodestar-daemon\x1b[0m\x1b[2m 进入配置向导\x1b[0m')
33
+ termWrite('\n \x1b[2m(首次运行会自动拉起向导; 也可直接跑 \x1b[32mlodestar-setup\x1b[0m\x1b[2m)\x1b[0m\n\n')
83
34
 
84
- // Path 3: Linux / macOS. Open the user's controlling terminal directly
85
- // as a fd and pass it as child stdio. Bypasses npm's pipe in-place,
86
- // same terminal window.
87
- try {
88
- const ttyFd = fs.openSync('/dev/tty', 'r+')
89
- termWrite(' \x1b[2m启动配置向导...\x1b[0m\n\n')
90
- const child = spawn(process.execPath, [setupBundle], {
91
- stdio: [ttyFd, ttyFd, ttyFd],
92
- })
93
- child.on('exit', (code) => process.exit(code == null ? 0 : code))
94
- child.on('error', (e) => fallback(`spawn 失败: ${e.message}`))
95
- } catch (e) {
96
- fallback(`/dev/tty 打不开: ${e.message}`)
97
- }
35
+ process.exit(0)