kinstra-neko 1.0.0 → 1.0.1

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
@@ -89,14 +89,17 @@ irm https://raw.githubusercontent.com/EROQIN/kinstra-neko/main/installer/windows
89
89
 
90
90
  ### 🧑‍💻 已有 Node 环境,只想装插件
91
91
 
92
+ DSH 是 pnpm 生态(依赖多为 alpha 预发布版本,npm 的严格 peer 校验会报 ERESOLVE),请用 pnpm:
93
+
92
94
  ```bash
93
- npx kinstra-neko@latest init # 建 profile、装 bundle、引导写凭据
94
- dsh --profile kinstra-neko web --port 3090
95
+ npm i -g pnpm # 若还没有 pnpm
96
+ pnpm dlx kinstra-neko@latest init # 建 profile、装 bundle、引导写凭据
97
+ dsh --profile kinstra-neko --port 3090 # 控制台会自动打开带一次性 token 的页面
95
98
  ```
96
99
 
97
100
  ### 装完之后 · 3 分钟向导
98
101
 
99
- 1. 浏览器打开 `http://127.0.0.1:3090`(云服务器用 `http://<IP>:3090`,注意安全组放行)。
102
+ 1. 打开控制台:Windows 双击桌面图标会自动用带一次性 token 的链接打开;Linux 服务器从安装结尾输出或 `journalctl -u kinstra-neko -n 30 | grep -o 'http://.*token=.*' | tail -1` 取带 token 的地址(裸 `http://<IP>:3090` 会被令牌门挡住,云服务器记得安全组放行 3090)。
100
103
  2. 按向导填:**猫娘小号 QQ**、**你的 QQ(主人)**。
101
104
  3. 在「连接」页点「生成 OneBot 配置」再点「启动 NapCat」,用猫娘小号扫弹出窗口里的二维码登录;插件会自动核对登录号与配置是否一致。
102
105
  4. 在 DSH 设置里配置模型服务商与 API Key(DeepSeek 官方或任意 OpenAI 兼容端点)。
@@ -219,7 +222,7 @@ npm run build # tsdown 双入口:lib/index.js + lib/clien
219
222
  # 装进本地 DSH 调试:
220
223
  dsh kinstra-neko --from-default-profile web --dump-config >/dev/null # 仅首次
221
224
  dsh plugin --profile kinstra-neko add "link:$PWD"
222
- dsh --profile kinstra-neko web --port 3090
225
+ dsh --profile kinstra-neko --port 3090 # 控制台会自动打开带一次性 token 的页面
223
226
  ```
224
227
 
225
228
  无真实 QQ 环境时,决策、消息解析、记忆、回复拆条均为纯函数,直接跑单测即可;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // Kinstra Neko 初始化器:创建独立 DSH profile、装入猫娘 bundle、引导最小配置。
3
3
  // 用法:
4
- // npx kinstra-neko init # 从 npm 装插件
4
+ // pnpm dlx kinstra-neko init # 从 npm 装插件(推荐;npm/npx 会因 alpha 严格 peer 报 ERESOLVE)
5
5
  // node kinstra-neko-init.mjs init --link /path/to/kinstra-neko # 开发/离线本地装
6
6
  // node kinstra-neko-init.mjs doctor # 环境自检
7
7
  // node kinstra-neko-init.mjs set-napcat-dir <NapCat Shell 目录> # 安装器种协议端目录
@@ -157,7 +157,7 @@ function cmdInit(options) {
157
157
  console.log()
158
158
  say('初始化完成!接下来:')
159
159
  console.log(` 1. 确保 QQ 协议端在跑(NapCat:先执行平台安装脚本;或自行准备 OneBot v11)`)
160
- console.log(` 2. 启动控制台: ${c.bold}dsh --profile ${PROFILE} web --port ${port}${c.reset}`)
160
+ console.log(` 2. 启动控制台: ${c.bold}dsh --profile ${PROFILE} --port ${port} --no-open${c.reset}`)
161
161
  console.log(` 3. 浏览器打开 http://127.0.0.1:${port} ,按猫娘向导填小号 QQ、你的 QQ、白名单`)
162
162
  console.log(` 默认是试运行:她只会在面板记录“本来会说什么”,确认对味后再关试运行\n`)
163
163
  }
@@ -6,7 +6,7 @@
6
6
  # 2. Node.js 22(缺失时用 NodeSource;国内可用 CN_MIRROR=1 走镜像)
7
7
  # 3. 全局安装 DeepSeek Harness
8
8
  # 4. 调 kinstra-neko init 建 profile、装猫娘 bundle
9
- # 5. 装 NapCat(官方 NapCat-Installer;无桌面环境自动配 Xvfb+x11vnc 扫码)并生成 OneBot 配置
9
+ # 5. 装 NapCat(官方 NapCat-Installer · rootless Shell:Xvfb 里跑 QQNT,扫码走 NapCat 内置 WebUI)并生成 OneBot 配置
10
10
  # 6. 注册 systemd 服务 kinstra-neko(开机自启、崩溃重启、Node 内存上限)
11
11
  #
12
12
  # 用法:
@@ -14,13 +14,19 @@
14
14
  # # 或下载后:sudo CN_MIRROR=1 bash install.sh
15
15
  #
16
16
  # 可覆盖变量:DSH_VERSION、KINSTRA_NEKO_SPEC(本地/自定义插件源)、WEB_PORT(默认 3090)、
17
- # NAPCAT_INSTALL_URL、SKIP_NAPCAT=1
17
+ # WEB_HOST(默认主网卡 IP 供远程访问;设 127.0.0.1 只本机)、
18
+ # NAPCAT_INSTALL_URL、NAPCAT_PROXY(官方脚本 GitHub 加速选项,0=直连;默认 0)、SKIP_NAPCAT=1
18
19
 
19
20
  set -euo pipefail
20
21
 
21
22
  WEB_PORT="${WEB_PORT:-3090}"
23
+ # 远程(云服务器)浏览器访问需绑到网卡上的具体 IP(DSH 拒绝 0.0.0.0 通配)。
24
+ # 默认取主网卡首个 IPv4;只想本机访问可 WEB_HOST=127.0.0.1。
25
+ WEB_HOST="${WEB_HOST:-$(hostname -I 2>/dev/null | awk '{print $1}')}"
22
26
  DSH_VERSION="${DSH_VERSION:-0.2.1-rc.3}"
23
- NAPCAT_INSTALL_URL="${NAPCAT_INSTALL_URL:-https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh}"
27
+ # 官方脚本源在 GitHub(NapNeko/NapCat-Installer);旧默认域名 nclatest.znin.net 已不可达,可用 NAPCAT_INSTALL_URL 覆盖。
28
+ NAPCAT_INSTALL_URL="${NAPCAT_INSTALL_URL:-https://raw.githubusercontent.com/NapNeko/NapCat-Installer/main/script/install.sh}"
29
+ NAPCAT_PROXY="${NAPCAT_PROXY:-0}"
24
30
  RUN_USER="${SUDO_USER:-$USER}"
25
31
  RUN_HOME="$(eval echo "~$RUN_USER")"
26
32
 
@@ -83,54 +89,106 @@ if [ "$need_node" = 1 ]; then
83
89
  fi
84
90
 
85
91
  # ---------- 3. DSH ----------
86
- if ! su - "$RUN_USER" -c 'command -v dsh' >/dev/null 2>&1; then
92
+ # 系统级 node(NodeSource)的全局 prefix 是 /usr,/usr/lib/node_modules 归 root,
93
+ # 因此全局包必须以 root 身份装(bin 链到 /usr/bin/dsh,普通用户也能调用)。
94
+ # 切勿 su 到普通用户执行 npm -g:写不进 root 目录会 EACCES。
95
+ if ! command -v dsh >/dev/null 2>&1; then
87
96
  say "全局安装 DeepSeek Harness @$DSH_VERSION…"
88
- su - "$RUN_USER" -c "npm install -g @deepseek-ai/dsh@$DSH_VERSION --no-audit --no-fund"
97
+ npm install -g "@deepseek-ai/dsh@$DSH_VERSION" --no-audit --no-fund
89
98
  fi
90
- ok "DSH:$(su - "$RUN_USER" -c 'dsh --version' 2>/dev/null || echo 已安装)"
99
+ ok "DSH:$(dsh --version 2>/dev/null || echo 已安装)"
100
+
101
+ # pnpm:DSH 的 `dsh plugin add` 用 pnpm 装插件,且本生态全是 alpha 预发布版本,
102
+ # npm 的严格 peer 解析会因版本范围(精确 alpha vs ~x.y.z)报 ERESOLVE,pnpm 只告警不阻断。
103
+ if ! command -v pnpm >/dev/null 2>&1; then
104
+ say '安装 pnpm(DSH 插件管理器依赖)…'
105
+ npm install -g pnpm --no-audit --no-fund
106
+ fi
107
+ ok "pnpm $(pnpm -v)"
91
108
 
92
109
  # ---------- 4. Kinstra Neko 插件 ----------
93
110
  say '初始化 Kinstra Neko profile 与插件…'
94
111
  INIT_ARGS='init'
95
112
  [ -n "${KINSTRA_NEKO_SPEC:-}" ] && INIT_ARGS="init --link $KINSTRA_NEKO_SPEC"
96
- su - "$RUN_USER" -c "DSH_VERSION=$DSH_VERSION npx -y kinstra-neko@latest $INIT_ARGS </dev/tty" || \
113
+ # init 的 stdin 一律接 /dev/null:唯一交互是可跳过的模型 API Key(EOF 自动取空),
114
+ # 密钥本就改在装完后的面板向导里填,curl|bash 过程中不该卡在输入。
115
+ # 切勿在此重定向 /dev/tty:root 脚本里探测到的控制终端,在 `su - <user>` 经 PAM/setsid
116
+ # 起 login shell 后可能已不可达(交互式 ssh 下 curl|sudo bash 必现),反而让整条 su 失败。
117
+ su - "$RUN_USER" -c "DSH_VERSION=$DSH_VERSION pnpm dlx kinstra-neko@latest $INIT_ARGS </dev/null" || \
97
118
  die '插件初始化失败(网络问题可重试;开发版可设 KINSTRA_NEKO_SPEC=本地目录)'
98
119
  ok '猫娘插件已装入 profile'
99
120
 
100
121
  # ---------- 5. NapCat(可跳过)----------
122
+ # 真机确认的官方 NapCat Shell(rootless) 布局(NapCat-Installer --docker n):
123
+ # $RUN_HOME/Napcat/opt/QQ/qq QQNT 可执行
124
+ # $RUN_HOME/Napcat/opt/QQ/resources/app/app_launcher/napcat/ NapCat 插件目录(config/ 在此)
125
+ # 启动是 `xvfb-run -a <qq> --no-sandbox`(无头自动起 Xvfb);官方【不】注册 systemd 服务、
126
+ # 也【不】装 x11vnc,headless 扫码走 NapCat 内置 WebUI(首启后 config/webui.json 出 token,默认 6099)。
101
127
  if [ "${SKIP_NAPCAT:-0}" != 1 ]; then
102
- say '安装 NapCat(官方安装器;无桌面环境会配 Xvfb + x11vnc 供扫码)…'
103
- if [ "${CN_MIRROR:-0}" = 1 ]; then
104
- warn '国内镜像模式:NapCat 官方脚本从 GitHub 拉取,如缓慢可稍后手动执行其安装指引'
128
+ NAPCAT_HOME="$RUN_HOME/Napcat"
129
+ NAPCAT_QQ="$NAPCAT_HOME/opt/QQ"
130
+ NAPCAT_DIR="$NAPCAT_QQ/resources/app/app_launcher/napcat" # config 与 run-napcat.sh 所在,种给插件
131
+ NAPCAT_QQ_BIN="$NAPCAT_QQ/qq"
132
+
133
+ if [ -x "$NAPCAT_QQ_BIN" ] && [ -f "$NAPCAT_DIR/napcat.mjs" ]; then
134
+ # 幂等:已装好就别再下载/重跑官方安装器(重跑几百 MB 且易因 /tmp 残留触发 curl 写错误)。
135
+ ok "NapCat 已安装:$NAPCAT_HOME(跳过官方安装器)"
136
+ else
137
+ say '安装 NapCat(官方 NapCat-Installer · rootless Shell:QQNT + NapCat + Xvfb,约几百 MB)…'
138
+ # 下到唯一临时文件再执行:curl -o 直接覆盖一个属主为普通用户的 /tmp 残留会报 write error 23
139
+ # (真机实测),mktemp 新文件可规避;下载失败只跳过 NapCat、不阻断已就绪的核心服务。
140
+ napcat_inst="$(mktemp /tmp/napcat-installer.XXXXXX.sh)"
141
+ # --retry 让瞬态网络/写错误就地自愈(curl 23 在真机出现过一次),尽量一次装成;
142
+ # 最终仍失败才降级为跳过 NapCat,不阻断核心控制台。
143
+ if curl -fsSL --retry 3 --retry-delay 2 --connect-timeout 20 "$NAPCAT_INSTALL_URL" -o "$napcat_inst"; then
144
+ # 以 root 跑(apt 装 Xvfb/依赖免密),但 HOME 指向普通用户家目录:rootless 安装器按
145
+ # $HOME/Napcat 落文件,这样 QQ/NapCat 落在运行用户名下;后面再 chown 兜底归属。
146
+ # 显式参数跳过交互菜单:--docker n 走 Shell、--cli y 装 napcat 命令、--proxy 直连。
147
+ HOME="$RUN_HOME" bash "$napcat_inst" --docker n --cli y --proxy "$NAPCAT_PROXY" \
148
+ || warn 'NapCat 安装器返回非零(多为网络/版本差异)。可稍后重跑本脚本,或面板「连接」改接任意 OneBot v11。'
149
+ else
150
+ warn "下载 NapCat 官方安装器失败(网络受限可设 NAPCAT_INSTALL_URL 指向可达镜像)。跳过 NapCat,核心控制台仍可用。"
151
+ fi
152
+ rm -f "$napcat_inst"
105
153
  fi
106
- curl -fsSL "$NAPCAT_INSTALL_URL" -o /tmp/napcat-install.sh
107
- # 官方脚本通常支持 sudo bash napcat.sh;交互项尽量走默认(它会处理 QQ/Xvfb/systemd)
108
- bash /tmp/napcat-install.sh || warn 'NapCat 安装器返回非零(版本差异)。可稍后手动安装,或在面板「连接」里改接任意 OneBot。'
109
-
110
- NAPCAT_DIR="${NAPCAT_DIR:-$RUN_HOME/napcat}"
111
- say "在 $NAPCAT_DIR 准备 OneBot 配置(首次扫码登录小号后,由面板自动写入正式 onebot11_<QQ>.json)…"
112
- install -d -o "$RUN_USER" -g "$RUN_USER" "$NAPCAT_DIR/config"
113
- cat > "$NAPCAT_DIR/run-napcat.sh" <<'RUNEOF'
154
+
155
+ if [ -x "$NAPCAT_QQ_BIN" ] && [ -d "$NAPCAT_DIR" ]; then
156
+ # root 跑安装器可能在用户家目录留下 root 属主文件;插件以普通用户 spawn,要能写
157
+ # config(onebot11_*.json),NapCat 首启也要写 webui.json/登录态,故整目录归普通用户。
158
+ chown -R "$RUN_USER":"$RUN_USER" "$NAPCAT_HOME"
159
+ install -d -o "$RUN_USER" -g "$RUN_USER" "$NAPCAT_DIR/config"
160
+ cat > "$NAPCAT_DIR/run-napcat.sh" <<'RUNEOF'
114
161
  #!/usr/bin/env bash
115
- # Kinstra Neko 调起的 NapCat 启动脚本(由安装器生成;如官方安装器的服务名不同,
116
- # 本脚本作为兜底:优先用 systemd 服务,否则提示手动启动)。
162
+ # Kinstra Neko 调起的 NapCat 启动脚本(安装器生成)。
163
+ # 官方 rootless Shell 形态:没有 systemd 服务、没有 x11vnc;在 Xvfb 虚拟显示里前台跑 QQNT,
164
+ # 扫码/登录管理走 NapCat 内置 WebUI(token 见同目录 config/webui.json,默认端口 6099)。
165
+ # 插件以普通用户 spawn 本脚本(cwd=本目录);exec 让 QQ 顶替本壳,信号可直达。
117
166
  set -e
118
- if systemctl list-unit-files | grep -q napcat; then
119
- sudo systemctl start napcat
120
- else
121
- echo "未发现 napcat systemd 服务,请用 NapCat 官方方式启动(如 sudo napcat)" >&2
122
- exit 1
123
- fi
167
+ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
168
+ # 本脚本在 resources/app/app_launcher/napcat 下,上溯四级到 opt/QQ,QQ 本体在那。
169
+ QQ="$(cd "$DIR/../../../.." && pwd)/qq"
170
+ [ -x "$QQ" ] || QQ="$HOME/Napcat/opt/QQ/qq"
171
+ exec xvfb-run -a "$QQ" --no-sandbox "$@"
124
172
  RUNEOF
125
- chmod +x "$NAPCAT_DIR/run-napcat.sh"
126
- chown -R "$RUN_USER":"$RUN_USER" "$NAPCAT_DIR"
127
- ok 'NapCat 安装/引导完成(首次需扫码登录小号,见 NapCat 官方输出或面板连接页)'
173
+ chmod 755 "$NAPCAT_DIR/run-napcat.sh"
174
+ chown "$RUN_USER":"$RUN_USER" "$NAPCAT_DIR/run-napcat.sh"
175
+ # 关键:把 NapCat 插件目录(config 所在)种进插件配置,否则 detect() 回落到
176
+ # ~/.dsh/plugins-data/kinstra-neko/napcat,与真实安装目录不一致而判“未安装”。
177
+ su - "$RUN_USER" -c "pnpm dlx kinstra-neko@latest set-napcat-dir '$NAPCAT_DIR' </dev/null" \
178
+ || warn '未能把 NapCat 目录写入插件配置,可在面板「连接」页手填:'"$NAPCAT_DIR"
179
+ ok "NapCat 就绪:$NAPCAT_HOME(首次启动后经 SSH 隧道开 WebUI 扫码,见下方上线步骤)"
180
+ else
181
+ warn "NapCat 似乎没装完整(缺 $NAPCAT_QQ_BIN 或 $NAPCAT_DIR,多为下载失败)。可重跑本脚本,或面板「连接」改接 OneBot。"
182
+ fi
128
183
  fi
129
184
 
130
185
  # ---------- 6. systemd 服务 ----------
131
186
  say '注册 systemd 服务 kinstra-neko…'
132
187
  NODE_BIN="$(su - "$RUN_USER" -c 'command -v node')"
133
188
  DSH_BIN="$(su - "$RUN_USER" -c 'command -v dsh')"
189
+ # --host 只接受具体本机 IP(拒绝通配);取不到就不传给 DSH(回落其默认 loopback)。
190
+ BIND_ARGS="--port $WEB_PORT --no-open"
191
+ [ -n "$WEB_HOST" ] && BIND_ARGS="--host $WEB_HOST $BIND_ARGS"
134
192
  cat > /etc/systemd/system/kinstra-neko.service <<SVCEOF
135
193
  [Unit]
136
194
  Description=Kinstra Neko — DSH web with QQ catgirl
@@ -143,7 +201,7 @@ User=$RUN_USER
143
201
  Environment=NODE_ENV=production
144
202
  # 2H2G 内存上限:给 NapCat/系统留足,DSH 侧压缩到 ~700MB 老生代
145
203
  Environment=NODE_OPTIONS=--max-old-space-size=700
146
- ExecStart=$DSH_BIN --profile kinstra-neko web --port $WEB_PORT --no-open
204
+ ExecStart=$DSH_BIN --profile kinstra-neko $BIND_ARGS
147
205
  Restart=on-failure
148
206
  RestartSec=5
149
207
  WorkingDirectory=$RUN_HOME
@@ -157,20 +215,41 @@ systemctl enable kinstra-neko >/dev/null 2>&1
157
215
  systemctl restart kinstra-neko
158
216
  ok '服务已启动并设为开机自启'
159
217
 
160
- sleep 3
161
- systemctl is-active --quiet kinstra-neko && ok 'kinstra-neko 正在运行' || warn '服务没起来:journalctl -u kinstra-neko -n 50 看日志'
218
+ # web 首次挂载插件要十几秒,等到 active 且端口起来(最多 ~40s)
219
+ BIND_IP="${WEB_HOST:-127.0.0.1}"
220
+ for _ in $(seq 1 20); do
221
+ systemctl is-active --quiet kinstra-neko || { warn '服务没起来:journalctl -u kinstra-neko -n 50 看日志'; break; }
222
+ curl -s -o /dev/null --max-time 2 "http://$BIND_IP:$WEB_PORT/" && break
223
+ sleep 2
224
+ done
225
+ systemctl is-active --quiet kinstra-neko && ok "kinstra-neko 正在运行(监听 $BIND_IP:$WEB_PORT)"
226
+
227
+ # DSH web 默认带一次性 token 门,从日志取带 token 的直达 URL
228
+ TOKEN_URL="$(journalctl -u kinstra-neko --no-pager 2>/dev/null | grep -oE 'http://[^ ]*\?token=[^ ]+' | tail -1)"
229
+ if [ -n "$TOKEN_URL" ]; then
230
+ TOKEN_URL="${TOKEN_URL/127.0.0.1/$BIND_IP}"
231
+ TOKEN_URL="${TOKEN_URL/localhost/$BIND_IP}"
232
+ else
233
+ TOKEN_URL="http://$BIND_IP:$WEB_PORT/(按页面提示取 token:journalctl -u kinstra-neko -n 30)"
234
+ fi
162
235
 
163
236
  echo
164
237
  say '安装完成!'
165
238
  cat <<TIPS
166
239
 
167
- 控制台: http://<服务器IP>:$WEB_PORT
240
+ 控制台(带免输 token 的直达地址):
241
+ $TOKEN_URL
242
+ (也可运行: journalctl -u kinstra-neko -n 30 | grep -o 'http://.*token=.*' | tail -1)
243
+ 云服务器:确认安全组/防火墙放行 $WEB_PORT/tcp;只想本机访问用 WEB_HOST=127.0.0.1 重装。
168
244
  服务管理: sudo systemctl {status|restart|stop} kinstra-neko
169
245
  实时日志: journalctl -u kinstra-neko -f
170
246
 
171
247
  上线步骤:
172
248
  1. 控制台按猫娘向导填「猫娘小号 QQ」和「你的 QQ」
173
- 2. 扫码登录 NapCat 里的小号(无桌面服务器走 x11vnc,见 NapCat 安装输出)
249
+ 2. 扫码登录 NapCat 里的小号(headless 服务器走 SSH 隧道,勿对公网开放 6099):
250
+ 本机执行 ssh -L 6099:127.0.0.1:6099 $RUN_USER@<服务器 IP>
251
+ 浏览器开 http://127.0.0.1:6099 ,token 见服务器上
252
+ $NAPCAT_DIR/config/webui.json 的 "token" 字段
174
253
  3. 在 DSH 设置里配置模型服务商与 API Key
175
254
  4. 把要养她的群加进白名单
176
255
  5. 出厂是试运行:先在「试运行」页确认她会说什么,再关试运行开麦
@@ -49,22 +49,28 @@ try { dsh --version | Out-Null; Ok "DSH $(dsh --version)" } catch {
49
49
  npm install -g "@deepseek-ai/dsh@$DshVersion" --no-audit --no-fund
50
50
  }
51
51
 
52
- # 3. 插件初始化
52
+ # 2.5 pnpm:DSH 插件管理器用 pnpm;本生态全是 alpha 预发布版本,npm 严格 peer 会 ERESOLVE,pnpm 只告警。
53
+ try { pnpm --version | Out-Null; Ok "pnpm $(pnpm --version)" } catch {
54
+ Say '全局安装 pnpm(DSH 插件管理器依赖)…'
55
+ npm install -g pnpm --no-audit --no-fund
56
+ }
57
+
58
+ # 3. 插件初始化(用 pnpm dlx,不用 npx:避开 npm 对 alpha peer 的 ERESOLVE)
53
59
  Say '初始化 Kinstra Neko …'
54
60
  $initArgs = @('init')
55
61
  if ($env:KINSTRA_NEKO_SPEC) { $initArgs = @('init', '--link', $env:KINSTRA_NEKO_SPEC) }
56
62
  $env:DSH_VERSION = $DshVersion
57
- npx -y kinstra-neko@latest @initArgs
63
+ pnpm dlx kinstra-neko@latest @initArgs
58
64
  if ($LASTEXITCODE -ne 0) { Die '插件初始化失败,检查网络后重试(开发版设 KINSTRA_NEKO_SPEC=本地目录)。' }
59
65
  Ok '猫娘插件已装入 profile'
60
66
 
61
- # 调用本包 CLI(npm 源或本地 --link 源),用于把探测到的 NapCat 目录种入插件配置。
67
+ # 调用本包 CLI(pnpm 源或本地 --link 源),用于把探测到的 NapCat 目录种入插件配置。
62
68
  function Invoke-KinstraCli([string[]]$CliArgs) {
63
69
  if ($env:KINSTRA_NEKO_SPEC) {
64
70
  $scriptPath = Join-Path $env:KINSTRA_NEKO_SPEC 'installer\bin\kinstra-neko-init.mjs'
65
71
  node $scriptPath @CliArgs
66
72
  } else {
67
- npx -y kinstra-neko@latest @CliArgs
73
+ pnpm dlx kinstra-neko@latest @CliArgs
68
74
  }
69
75
  }
70
76
 
@@ -177,8 +183,8 @@ $startBat = Join-Path $appData 'start-kinstra.bat'
177
183
  REM Kinstra Neko 启动脚本(安装器生成)
178
184
  title Kinstra Neko
179
185
  echo Starting Kinstra Neko on http://127.0.0.1:$WebPort ...
180
- start "" http://127.0.0.1:$WebPort
181
- dsh --profile $ProfileName web --port $WebPort
186
+ echo 浏览器会自动打开带一次性 token 的控制台;若没弹出,复制本窗口日志里 http://...?token=... 的链接。
187
+ dsh --profile $ProfileName --port $WebPort
182
188
  pause
183
189
  "@ | Set-Content -Encoding UTF8 $startBat
184
190
  Ok "启动脚本:$startBat(已在桌面放快捷方式)"
package/lib/index.js CHANGED
@@ -727,7 +727,7 @@ function createNapCatManager(opts) {
727
727
  child = spawn(script, [], {
728
728
  cwd: installDir(),
729
729
  windowsHide: process.platform !== "win32",
730
- detached: false,
730
+ detached: process.platform !== "win32",
731
731
  stdio: [
732
732
  "ignore",
733
733
  "pipe",
@@ -756,8 +756,11 @@ function createNapCatManager(opts) {
756
756
  message: "已启动"
757
757
  };
758
758
  }
759
- /** 结束 NapCat 进程。Windows 下 spawn(.bat, shell:true) 的 pid 是 cmd.exe,
760
- * 只 kill 它会孤儿化 NapCat/QQ,必须 taskkill /T 连整棵进程树一起结束。 */
759
+ /** 结束 NapCat 进程。
760
+ * Windows 下 spawn(.bat, shell:true) 的 pid 是 cmd.exe,只 kill 它会孤儿化
761
+ * NapCat/QQ,必须 taskkill /T 连整棵进程树一起结束。
762
+ * POSIX 下 start() 用 detached:true 建了新进程组,对负 pid 发 SIGTERM 即可连同
763
+ * xvfb-run → Xvfb + QQ(+zygote) 整组结束;进程组已不在(ESRCH)时兜底 kill 直接子。 */
761
764
  function killTree(me) {
762
765
  if (process.platform === "win32") try {
763
766
  execFileSync("taskkill", [
@@ -768,6 +771,10 @@ function createNapCatManager(opts) {
768
771
  ], { stdio: "ignore" });
769
772
  return;
770
773
  } catch {}
774
+ if (typeof me.pid === "number") try {
775
+ process.kill(-me.pid, "SIGTERM");
776
+ return;
777
+ } catch {}
771
778
  try {
772
779
  me.kill();
773
780
  } catch {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kinstra-neko",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Kinstra Neko —— 住在 QQ 群里的猫娘,基于 DeepSeek Harness 的 OneBot v11 社交陪伴发行版(自部署)",
5
5
  "license": "MIT",
6
6
  "author": "Kinstra Neko contributors",