4 Commits
Author SHA1 Message Date
手瓜一十雪 1faa6c58fa fix: unify stream cleanup and configuration response handling 2026-10-18 13:18:25 +08:00
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +08:00
DrSmoothl f1ae0736c6 build(release): enforce neutral runtime layout
Keep release files at the archive root and reject product-named directory components before CI packages artifacts.

Use neutral directories for media staging, WebUI uploads, stream storage, and MCP downloads so packaged and runtime layouts remain consistent.
2026-08-06 23:08:19 +08:00
DrSmoothl a7667f1cd5 feat(core,onebot): debug-console stream-invoke + upload endpoints
Phase 2 of the debug-console expansion. Two backend endpoints under the
existing /api/* bearer auth:

- POST /api/debug/invoke-stream — drive a Stream API action (#163) and
  relay every frame to the browser over an SSE body. The frontend reads
  it with fetch()+a stream reader (header auth), so it needs no SSE
  query-token allowlist entry. Frames are NEVER dropped: backpressure is
  handled by waiting for the consumer to drain, not by discarding (a lost
  chunk corrupts a transfer). Non-stream actions emit a single frame.
- POST /api/debug/upload — stream a browser-selected file to a temp path
  on THIS server (the bot runs server-side, not on the operator's
  machine), so the path can feed a send action's file/image/record/video
  param. Raw bytes in the body (no multipart buffering), ?filename= for a
  readable suffix, streamed to disk under os.tmpdir()/snowluma-debug-
  upload with a 4 GiB cap and a 24h TTL sweep.

instance.invokeStream() delegates to ApiHandler.processStreamRequest.

Pure logic (filename sanitisation, fenced size-capped disk sink, the
stream-invoke Response builder) lives in debug-tools.ts with 12 unit
tests. Adversarially reviewed: path traversal is robust (19 hostile
filenames all fenced), frames provably never dropped, auth runs before
any disk write. Fixed a High found in review — the write stream had no
'error' listener (an async ENOSPC/EIO during flush would crash the whole
process) and a late-open race could leak a partial file; both now raced
into the awaits and cleaned up after 'close'.
2026-06-30 16:19:59 +08:00