dsh-crossterm 0.3.35 → 0.3.36

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 (3) hide show
  1. package/lib/bus.js +1 -1
  2. package/lib/web.js +43 -6
  3. package/package.json +1 -1
package/lib/bus.js CHANGED
@@ -22,7 +22,7 @@ import os from 'node:os'
22
22
  import path from 'node:path'
23
23
  import crypto from 'node:crypto'
24
24
 
25
- export const VERSION = '0.3.35'
25
+ export const VERSION = '0.3.36'
26
26
 
27
27
  /** DSH 的家目录:与宿主其它状态(sessions / profiles)同一个根,多终端天然共享 */
28
28
  export function dshHome() {
package/lib/web.js CHANGED
@@ -129,9 +129,28 @@ async function latestVersion() {
129
129
  throw new Error(last || 'unknown')
130
130
  }
131
131
 
132
+ // 子进程输出解码:中文 Windows 控制台默认 CP936(GBK),直接当 UTF-8 读会变成 ����。
133
+ // 先按整段 UTF-8 严格解码,失败再退回 GBK;顺带清掉 ANSI 控制符与 \r 进度残留。
134
+ function decodeOutput(buffer) {
135
+ if (!buffer || buffer.length === 0) return ''
136
+ let text
137
+ try {
138
+ text = new TextDecoder('utf-8', { fatal: true }).decode(buffer)
139
+ } catch {
140
+ try {
141
+ text = new TextDecoder('gbk').decode(buffer)
142
+ } catch {
143
+ text = buffer.toString('utf8')
144
+ }
145
+ }
146
+ // eslint-disable-next-line no-control-regex
147
+ return text.replace(/\u001b\[[0-9;?]*[A-Za-z]/g, '').replace(/\r/g, '\n')
148
+ }
149
+
132
150
  function run(cmd, args, cwd) {
133
151
  return new Promise((resolve) => {
134
- let out = ''
152
+ const chunks = []
153
+ let size = 0
135
154
  let child
136
155
  try {
137
156
  child = spawn(cmd, args, {
@@ -144,16 +163,34 @@ function run(cmd, args, cwd) {
144
163
  return
145
164
  }
146
165
  const push = (chunk) => {
147
- out += String(chunk)
148
- if (out.length > 20000) out = out.slice(-20000)
166
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk), 'utf8')
167
+ chunks.push(buf)
168
+ size += buf.length
169
+ // 只留最后 64 KB,免得长日志把内存和卡片撑爆
170
+ while (size > 65536 && chunks.length > 1) size -= chunks.shift().length
149
171
  }
150
172
  child.stdout && child.stdout.on('data', push)
151
173
  child.stderr && child.stderr.on('data', push)
152
- child.on('error', (error) => resolve({ code: -1, out: out + String((error && error.message) || error) }))
153
- child.on('close', (code) => resolve({ code, out }))
174
+ child.on('error', (error) =>
175
+ resolve({ code: -1, out: decodeOutput(Buffer.concat(chunks)) + String((error && error.message) || error) }),
176
+ )
177
+ child.on('close', (code) => resolve({ code, out: decodeOutput(Buffer.concat(chunks)) }))
154
178
  })
155
179
  }
156
180
 
181
+ // 更新失败时给人的提示:命令找不到就明说,别把一行乱码甩到卡片上
182
+ function updateErrorText(result) {
183
+ const raw = (result.out || '').trim()
184
+ if (!raw) {
185
+ return `自动更新没跑起来(dsh 退出码 ${result.code}):本机找不到可用的 dsh 命令,请在命令行手动执行 dsh plugin add ${PKG}@latest,然后重启 DSH`
186
+ }
187
+ const tail = raw.slice(-1200)
188
+ if (/not recognized|不是内部或外部命令|无法将.{0,12}项识别|command not found|ENOENT/i.test(raw)) {
189
+ return `${tail}\n\n提示:PATH 里没有 dsh 命令,请在命令行手动执行 dsh plugin add ${PKG}@latest,然后重启 DSH`
190
+ }
191
+ return tail
192
+ }
193
+
157
194
  function statusOf(term) {
158
195
  const cfg = term.cfg || {}
159
196
  const info = profileInfo(cfg.busDir)
@@ -323,7 +360,7 @@ export function registerWeb(ctx, term, log) {
323
360
  message:
324
361
  result.code === 0
325
362
  ? '已更新,重启 DSH 后生效'
326
- : (result.out || `dsh 退出码 ${result.code}`).slice(-1200),
363
+ : updateErrorText(result),
327
364
  })
328
365
  },
329
366
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crossterm",
3
- "version": "0.3.35",
3
+ "version": "0.3.36",
4
4
  "description": "DSH 跨终端互联:同一账号下的多个 DSH 终端/进程互发邮件与文件(主题内联、正文落盘,收件方自己读)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",