glasspane-install 1.18.0 → 1.19.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.
Files changed (2) hide show
  1. package/cli.js +17 -11
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -70,7 +70,7 @@ export const INSTALL_SH_URL =
70
70
  /** 发布线锚点(版本真源 = 根 package.json,由 scripts/set-version.mjs 统一改写,
71
71
  * 勿手改):npx 形态下本地没有仓库时,引导 clone 的就是这个 tag,与 install.sh
72
72
  * 的 `GLASSPANE_RELEASE` 同值——两条一键入口必须拿到同一份源码。 */
73
- export const RELEASE_VERSION = '1.18.0'
73
+ export const RELEASE_VERSION = '1.19.0'
74
74
  /** 发布 ref(tag 名)。GLASSPANE_REF 环境变量可覆盖(追主干用 `main`)。 */
75
75
  export const REPO_REF = `v${RELEASE_VERSION}`
76
76
 
@@ -483,7 +483,7 @@ export function classifyKillResult({ status, stderr = '', error = null } = {}) {
483
483
  }
484
484
 
485
485
  /** 这个 pid 是不是**僵尸**(已死、等父进程回收):`kill -0` 对僵尸回 0,光靠信号探测会把
486
- * 一个已经不服务 socket 的进程报成"还活着、请你 sudo kill"。状态读不出来时保守回 false
486
+ * 一个已经不服务 socket 的进程报成"还活着、请你去收尾"。状态读不出来时保守回 false
487
487
  * (宁可多报一个幸存者,也不放走真的还在跑的进程)。 */
488
488
  export function isZombiePid(pid, { spawn = spawnSync } = {}) {
489
489
  try {
@@ -536,13 +536,13 @@ export function terminatePids(pids, { spawn = spawnSync, sleepMs = 1000, reprobe
536
536
  let after = state(pid)
537
537
  if (after !== 'gone') {
538
538
  // 刚被 SIGKILL 的进程要等它的父进程回收(父进程正 `wait` 着的话是毫秒级);
539
- // 立刻探一次会把它读成"还活着",于是红字让人去 sudo kill 一个已经没了的 pid。
539
+ // 立刻探一次会把它读成"还活着",于是红字让人去收尾一个已经没了的 pid。
540
540
  // 给一次**有界**的再探窗口,只有窗口过后还在的才算幸存者。
541
541
  if (sleep) sleep(reprobeMs)
542
542
  else spawn('sleep', [String(reprobeMs / 1000)], { encoding: 'utf8' })
543
543
  after = state(pid)
544
544
  // 还"活着"但状态是 Z = 它已经死了,只差父进程 wait() 收尸:这种东西不持有 socket、
545
- // 不需要人去 sudo kill,报成幸存者就是把人支到一条没用的命令上。
545
+ // 不需要人去做任何收尾动作,报成幸存者就是把人支到一条没用的命令上。
546
546
  if (after === 'alive' && isZombiePid(pid, { spawn })) after = 'gone'
547
547
  }
548
548
  if (after === 'gone') {
@@ -556,11 +556,15 @@ export function terminatePids(pids, { spawn = spawnSync, sleepMs = 1000, reprobe
556
556
  return { terminated, forced, survivors }
557
557
  }
558
558
 
559
- /** 幸存者(安装器发不动信号的进程)的红字(finding 5,纯函数)。
560
- * 这里给的必须是**人能直接执行**的动作,而不是"请检查权限":安装器没有 root 权限,
561
- * 所以只有坐在键盘前的这个人能 `sudo kill -9`;他知道 pid、知道为什么必须他做、
562
- * 也知道做完要重跑什么。socket 还挂在这些 pid 上,所以本轮的产物从未接管——
563
- * 收尾那次版本核对会把这件事再钉一次。 */
559
+ /** 幸存者(安装器收不掉的进程)的红字(finding 5,纯函数)。
560
+ * 这里给的必须是**能直接执行**的动作,而不是"请检查权限";而本产品的红线是:
561
+ * 补救文案一律不发提权命令。发信号这条本来就分两档,两档都如实写出来——
562
+ * ① 当前账号自己就能做的 `/bin/kill -9 <pid>`(安装器已经试过 TERM 与 KILL,
563
+ * 再报一次只是给人一个能手敲的等价动作,它不越权);
564
+ * ② 它被 EPERM 拒掉 = 这些 pid 不属于当前账号,那一步**只有坐在键盘前的这个人
565
+ * 能做**。这一步归人,不归脚本:本产品保留给真人的就是这种物理动作。
566
+ * socket 还挂在这些 pid 上,所以本轮的产物从未接管——收尾那次版本核对会把这件
567
+ * 事再钉一次。退出码契约不变(调用方仍按失败说)。 */
564
568
  export function survivorText(survivors, { socketPath } = {}) {
565
569
  const pids = survivors.map((entry) => entry.pid).join(' ')
566
570
  return [
@@ -568,8 +572,10 @@ export function survivorText(survivors, { socketPath } = {}) {
568
572
  + survivors.map((entry) => `pid ${entry.pid} — ${entry.reason}`).join(';'),
569
573
  `安装器无权向这些进程发信号(它们不属于当前账号,典型是 root 拉起的旧 daemon)。`
570
574
  + `上面"已结束"那句只对确实已经不在的 pid 成立,不含这些。`,
571
- `由人来收尾:先看清是谁起的 \`ps -o pid=,user=,lstart=,command= -p ${pids}\`,`
572
- + `再 \`sudo kill -9 ${pids}\`,然后重跑本安装器并加 --replace-daemon。`,
575
+ `先试当前账号自己就能做的那条(不提权):\`/bin/kill -9 ${pids}\`。`
576
+ + `它若仍被拒,就只能由坐在键盘前的人来结束这些进程——本安装器不发放提权命令,`
577
+ + `这一步归人。先看清是谁起的 \`ps -o pid=,user=,lstart=,command= -p ${pids}\`,`
578
+ + `由本人结束它们,然后重跑本安装器并加 --replace-daemon。`,
573
579
  ].join('\n')
574
580
  }
575
581
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glasspane-install",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "GlassPane one-command installer: terminal onboarding → install deps → build TS + Swift engine → start daemon → open settings GUI for permission guide",
5
5
  "type": "module",
6
6
  "license": "MIT",