yo-moss-ai 0.0.12 → 0.0.14

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 (81) hide show
  1. package/README.md +8 -7
  2. package/bin/bootstrap-deps.mjs +60 -19
  3. package/bin/runtime-manifest.json +1 -1
  4. package/bin/yo-moss-ai.mjs +1 -0
  5. package/dist/assets/esp-flasher-CLKzE7JE.js +2 -2
  6. package/dist/assets/{index-DawfICNZ.css → index-DHPw3h1p.css} +1 -1
  7. package/dist/assets/index-LX2Lv8b-.js +45 -0
  8. package/dist/index.html +2 -2
  9. package/dist-server/board-presets.mjs +1 -0
  10. package/dist-server/camera.mjs +1 -1
  11. package/dist-server/device-chat-sync.mjs +1 -0
  12. package/dist-server/device-config-view.mjs +1 -0
  13. package/dist-server/device-focus.mjs +1 -0
  14. package/dist-server/device-http.mjs +1 -0
  15. package/dist-server/device-identity.mjs +1 -0
  16. package/dist-server/device-presence.mjs +1 -0
  17. package/dist-server/device-probe.mjs +1 -0
  18. package/dist-server/device-registry.mjs +1 -0
  19. package/dist-server/device-routes.mjs +1 -0
  20. package/dist-server/device-runtime.mjs +1 -0
  21. package/dist-server/device-session.mjs +1 -0
  22. package/dist-server/ffmpeg.mjs +1 -1
  23. package/dist-server/gimbal-control.mjs +1 -0
  24. package/dist-server/home-path.mjs +1 -0
  25. package/dist-server/index.mjs +1 -1
  26. package/dist-server/ir-import-validate.mjs +1 -1
  27. package/dist-server/known-scan-device.mjs +1 -0
  28. package/dist-server/lan-discover.mjs +1 -0
  29. package/dist-server/mcp/backoff.mjs +1 -1
  30. package/dist-server/mcp/bridge-manager.mjs +1 -1
  31. package/dist-server/mcp/builtin-tools.mjs +1 -1
  32. package/dist-server/mcp/dedupe-servers.mjs +1 -1
  33. package/dist-server/mcp/doctor.mjs +1 -1
  34. package/dist-server/mcp/fixtures/echo-mcp.mjs +1 -1
  35. package/dist-server/mcp/fixtures/hotkey-mcp.mjs +1 -1
  36. package/dist-server/mcp/fixtures/onvif-mcp.mjs +1 -1
  37. package/dist-server/mcp/fixtures/shell-mcp.mjs +1 -1
  38. package/dist-server/mcp/fixtures/yunxiangji-mcp.mjs +2 -0
  39. package/dist-server/mcp/hotkey-agent-docs.mjs +1 -1
  40. package/dist-server/mcp/hotkey-driver.mjs +1 -1
  41. package/dist-server/mcp/hotkey-handlers.mjs +1 -1
  42. package/dist-server/mcp/hotkey-import-validate.mjs +1 -1
  43. package/dist-server/mcp/hotkey-store.mjs +1 -1
  44. package/dist-server/mcp/http-client.mjs +1 -1
  45. package/dist-server/mcp/http-pipe.mjs +1 -1
  46. package/dist-server/mcp/local-probe.mjs +1 -1
  47. package/dist-server/mcp/marketplace.mjs +1 -1
  48. package/dist-server/mcp/onvif-handlers.mjs +1 -1
  49. package/dist-server/mcp/parse-server-json.mjs +1 -1
  50. package/dist-server/mcp/paths.mjs +1 -1
  51. package/dist-server/mcp/routes.mjs +1 -1
  52. package/dist-server/mcp/schema.mjs +1 -1
  53. package/dist-server/mcp/settings.mjs +1 -1
  54. package/dist-server/mcp/shell-approval.mjs +1 -1
  55. package/dist-server/mcp/shell-policy.mjs +1 -1
  56. package/dist-server/mcp/shell-trash.mjs +1 -1
  57. package/dist-server/mcp/stdio-pipe.mjs +1 -1
  58. package/dist-server/mcp/store.mjs +1 -1
  59. package/dist-server/mcp/task-notify.mjs +1 -1
  60. package/dist-server/mcp/ws-connect.mjs +1 -1
  61. package/dist-server/mcp/yunxiangji.mjs +1 -0
  62. package/dist-server/media-cache.mjs +1 -1
  63. package/dist-server/onboard-preview.mjs +1 -0
  64. package/dist-server/tab-focus.mjs +1 -0
  65. package/dist-server/voice-wake.mjs +1 -0
  66. package/package.json +2 -3
  67. package/dist/assets/index-CZ_NROJp.js +0 -45
  68. package/dist/models/mediapipe/blaze_face_full_range.tflite +0 -0
  69. package/dist/models/mediapipe/blaze_face_short_range.tflite +0 -0
  70. package/dist/models/mediapipe/wasm/vision_wasm_internal.js +0 -8841
  71. package/dist/models/mediapipe/wasm/vision_wasm_internal.wasm +0 -0
  72. package/dist/models/mediapipe/wasm/vision_wasm_nosimd_internal.js +0 -8832
  73. package/dist/models/mediapipe/wasm/vision_wasm_nosimd_internal.wasm +0 -0
  74. package/dist/stl/moss.stl +0 -0
  75. package/dist/stl/planetary_engine.stl +0 -0
  76. package/dist/textures/earth-lights.png +0 -0
  77. package/dist/textures/earth-night.jpg +0 -0
  78. package/dist/textures/earth_clouds.jpg +0 -0
  79. package/dist/textures/moon-base.jpg +0 -0
  80. package/dist/textures/moon-bump.jpg +0 -0
  81. package/dist/textures/wandering.png +0 -0
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # yo-moss-ai
2
2
 
3
- MOSS 配置客户端:连接云通道、学习红外遥控器、配置 Onvif 摄像头。
3
+ MOSS 配置客户端:在局域网发现设备、学习红外遥控器、配置摄像头。
4
+
5
+ 固件上报的 `board`(`moss-onvif` / `moss-ov2640`)决定相机源:onvif 走外接 ONVIF/RTSP,ov2640 走板载 MJPEG 与云台。`product=moss-xiaozhi` 只表示这是 MOSS 设备,不用于判断有没有板载摄像头。请与对应固件一起升级。
4
6
 
5
7
  客户电脑安装好 Node.js 后,一条命令即可启动,并自动打开浏览器。
6
8
 
@@ -30,7 +32,7 @@ yo-moss-ai v0.1.0 http://127.0.0.1:3780
30
32
 
31
33
  若要清掉本机残留:
32
34
 
33
- 1. **配置和账号**(云通道、摄像头密码等)在用户目录:
35
+ 1. **配置和账号**(设备列表、摄像头密码等)在用户目录:
34
36
 
35
37
  ```bash
36
38
  # macOS / Linux
@@ -110,11 +112,10 @@ npx yo-moss-ai
110
112
 
111
113
  ## 使用顺序
112
114
 
113
- 1. 连接云通道
114
- 2. 找到 MOSS(自动扫描或手填 IP)
115
- 3. 需要时把云通道信息写入设备
116
- 4. 添加电器并学习遥控器。学到信号后请先试发,确认电器有反应再保存
117
- 5. 可选:扫描 Onvif 摄像头,查看画面并控制云台
115
+ 1. 扫描局域网并添加 MOSS(给它起个名字)
116
+ 2. 在设备列表里选一台在线设备
117
+ 3. 添加电器并学习遥控器。学到信号后请先试发,确认电器有反应再保存
118
+ 4. 可选:扫描 Onvif 摄像头,查看画面并控制云台
118
119
 
119
120
  电脑、MOSS、摄像头需要在同一局域网。
120
121
 
@@ -25,8 +25,21 @@ export function formatProgressBar(label, ratio, width = PROGRESS_BAR_WIDTH) {
25
25
  return `${label} [${bar}] ${pct}%`
26
26
  }
27
27
 
28
- function renderBar(label, ratio) {
29
- process.stdout.write(`\r\x1b[2K${formatProgressBar(label, ratio)}`)
28
+ /** 终端单行刷新;非 TTY(部分 npx 环境)按步进换行,避免长时间无输出 */
29
+ export function createProgressReporter(label) {
30
+ let lastPct = -1
31
+ return (ratio) => {
32
+ const pct = Math.min(100, Math.max(0, Math.round(ratio * 100)))
33
+ const line = formatProgressBar(label, ratio)
34
+ if (process.stdout.isTTY) {
35
+ process.stdout.write(`\r\x1b[2K${line}`)
36
+ return
37
+ }
38
+ if (lastPct < 0 || pct >= lastPct + 10 || pct === 100) {
39
+ console.log(line)
40
+ lastPct = pct
41
+ }
42
+ }
30
43
  }
31
44
 
32
45
  /** @deprecated 单文件 CDN 对大体积 npm 包不可靠,保留仅供测试/兜底 */
@@ -164,10 +177,17 @@ export async function installMediaBundleFromNpm(
164
177
  )
165
178
 
166
179
  const expected = totalBytes > 0 ? totalBytes : 56_000_000
180
+ let tick = 0
167
181
  const poll = setInterval(() => {
182
+ tick += 1
168
183
  const size = dirByteSize(path.join(staging, 'node_modules', MEDIA_PACKAGE_NAME))
169
- onProgress?.(Math.min(0.92, size / expected))
170
- }, 400)
184
+ if (size > 0) {
185
+ onProgress?.(Math.min(0.92, size / expected))
186
+ } else {
187
+ // npm 解压前 node_modules 为空,用轻量动画避免长时间 0%
188
+ onProgress?.(0.02 + (tick % 6) * 0.012)
189
+ }
190
+ }, 350)
171
191
 
172
192
  let lastError
173
193
  try {
@@ -204,7 +224,11 @@ export async function installMediaBundleFromNpm(
204
224
  onProgress?.(1)
205
225
  }
206
226
 
207
- export async function ensureRuntimeNpmDeps(npmDeps, depsRoot = runtimeDepsRoot(), installImpl = runNpmInstall) {
227
+ export async function ensureRuntimeNpmDeps(
228
+ npmDeps,
229
+ depsRoot = runtimeDepsRoot(),
230
+ { installImpl = runNpmInstall, onProgress } = {},
231
+ ) {
208
232
  fs.mkdirSync(depsRoot, { recursive: true })
209
233
  const pkgPath = path.join(depsRoot, 'package.json')
210
234
  const deps = Object.fromEntries(npmDeps.map((item) => [item.name, item.version]))
@@ -223,7 +247,21 @@ export async function ensureRuntimeNpmDeps(npmDeps, depsRoot = runtimeDepsRoot()
223
247
  if (fs.existsSync(nutEntry)) return
224
248
  }
225
249
 
226
- await installImpl(depsRoot)
250
+ let tick = 0
251
+ const poll = onProgress
252
+ ? setInterval(() => {
253
+ tick += 1
254
+ const size = dirByteSize(path.join(depsRoot, 'node_modules'))
255
+ if (size > 0) onProgress(Math.min(0.95, size / 80_000_000))
256
+ else onProgress(0.02 + (tick % 6) * 0.012)
257
+ }, 350)
258
+ : null
259
+ try {
260
+ await installImpl(depsRoot)
261
+ } finally {
262
+ if (poll) clearInterval(poll)
263
+ }
264
+ onProgress?.(1)
227
265
  fs.writeFileSync(marker, nextMarker)
228
266
  }
229
267
 
@@ -260,7 +298,7 @@ export async function bootstrapRuntimeDeps(opts) {
260
298
  cacheDir = mediaCacheDir(),
261
299
  depsRoot = runtimeDepsRoot(),
262
300
  installMediaBundle = installMediaBundleFromNpm,
263
- installNpmDeps = (npmDeps) => ensureRuntimeNpmDeps(npmDeps, depsRoot),
301
+ installNpmDeps = (npmDeps, onProgress) => ensureRuntimeNpmDeps(npmDeps, depsRoot, { onProgress }),
264
302
  } = opts
265
303
 
266
304
  const distDir = path.join(root, 'dist')
@@ -290,33 +328,36 @@ export async function bootstrapRuntimeDeps(opts) {
290
328
  console.log('')
291
329
  if (needMedia) {
292
330
  const mb = (totalBytes / 1024 / 1024).toFixed(0)
293
- console.log(`正在下载运行资源(约 ${mb} MB),完成后自动启动服务…`)
331
+ console.log(`首次运行:正在下载 UI 资源(约 ${mb} MB),完成后自动启动…`)
294
332
  } else if (needNpm) {
295
- console.log('正在安装扩展依赖,完成后自动启动服务…')
333
+ console.log('首次运行:正在安装扩展组件,完成后自动启动…')
296
334
  }
297
335
 
298
336
  if (needMedia) {
299
- renderBar('下载资源', 0)
337
+ const reportMedia = createProgressReporter('下载资源')
338
+ reportMedia(0.02)
300
339
  await installMediaBundle(mediaVersion, cacheDir, {
301
340
  totalBytes,
302
- onProgress: (ratio) => renderBar('下载资源', ratio),
341
+ onProgress: reportMedia,
303
342
  })
304
- process.stdout.write('\n')
343
+ if (process.stdout.isTTY) process.stdout.write('\n')
344
+ else console.log(formatProgressBar('下载资源', 1))
305
345
 
306
346
  if (!mediaCacheReady(mediaFiles, cacheDir)) {
307
- throw new Error('媒体资源安装完成但校验失败,请删除 ~/.moss-desktop/media 后重试')
347
+ throw new Error('资源校验失败,请删除 ~/.moss-desktop/media 文件夹后重试')
308
348
  }
309
349
  }
310
350
 
311
351
  if (needNpm) {
312
- renderBar('安装扩展依赖', 0)
352
+ const reportNpm = createProgressReporter('安装扩展依赖')
353
+ reportNpm(0.02)
313
354
  try {
314
- await installNpmDeps(npmDeps)
315
- renderBar('安装扩展依赖', 1)
316
- process.stdout.write('\n')
355
+ await installNpmDeps(npmDeps, reportNpm)
356
+ if (process.stdout.isTTY) process.stdout.write('\n')
357
+ else console.log(formatProgressBar('安装扩展依赖', 1))
317
358
  } catch (err) {
318
- process.stdout.write('\n')
319
- console.warn('扩展依赖安装失败,快捷键/媒体键可能不可用:', err.message)
359
+ if (process.stdout.isTTY) process.stdout.write('\n')
360
+ console.warn('扩展组件安装失败,快捷键/媒体键可能不可用:', err.message)
320
361
  }
321
362
  }
322
363
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "mediaVersion": "0.0.12",
2
+ "mediaVersion": "0.0.14",
3
3
  "mediaFiles": [
4
4
  {
5
5
  "path": "models/mediapipe/blaze_face_full_range.tflite",
@@ -28,6 +28,7 @@ if (!fs.existsSync(server)) {
28
28
  }
29
29
 
30
30
  console.log(`yo-moss-ai${pkgVersion ? ` v${pkgVersion}` : ''}`)
31
+ if (typeof process.stdout.write === 'function') process.stdout.write('')
31
32
 
32
33
  try {
33
34
  await bootstrapRuntimeDeps({ root, version: pkg.version })