Group video sends could exit the process with no error after the file was
staged. Refresh the bundled addon from the build that covers this case.
Fixes#507
Recover invalidated native send bindings from same-account receive evidence. Track outbound connection loss in status health and refresh the six public native artifacts from native build 94f2b63.
Closes#342
Improve compatibility for accounts restored after a restart.
Keep existing accounts working normally while restoring full availability for affected sessions.
Update the packaged runtime files from the verified release pipeline.
Align all supported platform bundles with the validated account recovery release.
Refs #305
Refs #307
Refresh the bundled runtime files with outputs from the verified release pipeline.
Include the supported Linux and Windows builds for the latest startup reliability improvements.
Refs #305
Refs #307
WebSocket native is now built for darwin-arm64 — source is at
github.com/SnowLuma/snowluma-websocket (cmake-js + node-addon-api,
clones to dev/snowluma-websocket and builds with `npm install`).
npm install in dev/snowluma-websocket → build/Release/snowluma_ws.node
cp → packages/runtime/native/websocket-darwin-arm64.node (102 KB)
Reverts the SNOWLUMA_BUILD_SKIP_NATIVES escape hatch in vite.config.ts
that 67f8bf3 added — no longer needed; the darwin native binary is
present. Keeps `packages/core/config/.gitignore` (independently useful
runtime-state hygiene). vite build now runs clean on darwin with no
env overrides; the runtime SNOWLUMA_DEV_NO_NATIVE=1 stub also becomes
optional (only needed if the operator wants to bypass WebSocket I/O
specifically).
Existing native binaries unchanged. CI invariant restored: every
release build must include every platform's native set.
Remove the in-tree @snowluma/sqlite wrapper and vendored better-sqlite3 prebuilts; migrate consumers to node:sqlite's synchronous API. Replaced imports and types (Database/Statement -> DatabaseSync/StatementSync), updated PRAGMA calls to use exec, and adjusted code in onebot (media/message/reaction stores) and protocol (identity service). Vite config no longer bundles sqlite native binaries and references to the sqlite workspace were removed. Also delete the packages/sqlite package and its native prebuild artifacts, and add a couple of unrelated AST improvements in proton: use a module-level shared wrapper cache and add an inheritance cache to avoid repeated scans. Minor import reordering/cleanup applied where needed.
Replaces "runtime npm dependency that gets `npm install`-ed into
dist/" with "TS wrapper that loads the native `.node` from
`dist/native/` like every other native binding in the project".
Why the change
--------------
The previous approach (better-sqlite3 declared in
packages/runtime/package.json, materialized by `npm install
--omit=dev` in dist/) worked but produced an artifact that needed
runtime npm install — a step the rest of SnowLuma's native bindings
don't need (websocket / snowluma-hook / ffmpeg are all standalone
`.node` files copied into `dist/native/` by vite-plugin-cp). The
asymmetry was friction: dev mode required `pnpm dist:install`,
build artifacts carried a `dist/node_modules/` tree the other
modules didn't need, and Docker images had to special-case the
glibc-vs-musl ABI lookup that prebuild-install runs.
The new shape:
- `@snowluma/sqlite` (packages/sqlite/) — TS wrapper. Has
`better-sqlite3` as a devDep (for the JS-layer types + the
actual JS wrapper code that vite inlines). At runtime, calls
`createRequire().require()` against
`<dist|repo>/native/better-sqlite3-v<abi>-<platform>-<arch>.node`
and passes the resolved addon to `new Database(path, {
nativeBinding })`.
- `packages/runtime/native/better-sqlite3-v<abi>-<triplet>.node`
— prebuilt binaries vendored into the repo. Two ABIs ship side-
by-side (v127 = Node 22 LTS used by CI, v137 = Node 24 used by
dev boxes) so `process.versions.modules` picks the matching one
at load time.
- `tools/fetch-sqlite-prebuilts.mjs` — fetches all 5 platforms ×
N ABIs from WiseLibs's GitHub releases. Idempotent: existing
`.node` files skip. Accepts extra ABI args:
`node tools/fetch-sqlite-prebuilts.mjs 12.10.0 v127 v137 v115`.
What was unwound
----------------
- packages/runtime/package.json — dependencies removed (runtime
artifact is now self-contained, no `npm install` step needed).
- root package.json — `dist:install` script removed (no node_modules
to install).
- .github/workflows/dev-build.yml — `Bundle runtime dependencies`
step removed.
- .github/workflows/release.yml — kept the `Bundle runtime
dependencies` step (was a no-op already, but harmless safety net
in case a future runtime dep shows up).
- packages/core/vite.config.ts — `better-sqlite3` no longer
external; vite inlines the JS wrapper (+~33 KB to bundle, ~2.84
MB → 2.87 MB total).
Naming
------
Mirrors the existing `websocket-${triplet}.node` convention (flat
dir under `runtime/native/`, dash-separated `<platform>-<arch>`).
Adds a `v<abi>` segment because better-sqlite3 is NOT N-API — one
binary per Node ABI. Naming:
better-sqlite3-v127-darwin-arm64.node Node 22 / macOS arm
better-sqlite3-v127-darwin-x64.node Node 22 / macOS intel
better-sqlite3-v127-linux-arm64.node Node 22 / Linux arm
better-sqlite3-v127-linux-x64.node Node 22 / Linux x64
better-sqlite3-v127-win32-x64.node Node 22 / Windows x64
better-sqlite3-v137-... (5) Node 24 / same 5 hosts
Total: 10 binaries × ~1.9 MB = ~19 MB committed. Aligned with the
existing native-vendoring footprint (websocket ~2 MB × 5, snowluma-
hook ~10 MB × Windows + Linux, ffmpeg ~10-30 MB × 4).
What changes for consumers
--------------------------
Source-side: nothing. `import Database, { type Database, type
Statement } from '@snowluma/sqlite'` is a drop-in for the previous
`import Database from 'better-sqlite3'`. The wrapper re-exports the
same types and the `Database` callable factory has the same
overload set.
Runtime: `node` finds the binding at
`<dist|repo>/native/better-sqlite3-v${process.versions.modules}-
${process.platform}-${process.arch}.node`. If the ABI doesn't
match a vendored binary, the wrapper throws a clear error pointing
at `tools/fetch-sqlite-prebuilts.mjs` with the missing ABI/triplet.
Bumped better-sqlite3 from 11.10.0 → 12.10.0 because v11 only had
prebuilt up to Node ABI v127 (no v137 = no Node 24). v12.10.0
ships both. Both versions are API-compat (the breaking changes
between v11 and v12 were either internal or in error-handling
paths SnowLuma doesn't exercise).
Verification
------------
- pnpm -r typecheck (12 projects): clean
- @snowluma/core test: 302/302
- @snowluma/onebot test: 250/250 (552/552 combined, unchanged from
the perf-series baseline)
- Bench numbers preserved — wrapper indirection is sub-μs:
storeMeta ~11 μs, storeEvent ~17 μs, findMeta hit ~1.1 μs (all
within noise of the post-RoadMap-#5 measurements).
- Vite build clean, bundle = 2.87 MB / 230 KB gzip
- `dist/index.mjs` no longer contains a `node:sqlite` import (it
did before — media-store hadn't migrated; now neither it nor
message-store reach into the Node builtin).
Bonus side-fix: `packages/onebot/src/media-store.ts` also moved
off `node:sqlite` (caught by the post-build bundle grep — the
file was using `DatabaseSync` + `StatementSync` from the builtin
even though it had already been written to cache its prepared
statements). Its hot paths now go through the same wrapper.
Introduce NT SILK-based voice (PTT) upload pipeline and native FFmpeg addon wrapper.
- Add ffmpeg-addon wrapper (packages/core/src/bridge/highway/ffmpeg-addon.ts) to load platform/arch .node binaries, detect SILK files, and convert inputs to NT SILK via the native addon. Provides encodeSilk, isSilkFile and default temp dir helpers.
- Implement ptt-upload pipeline (packages/core/src/bridge/highway/ptt-upload.ts) to: resolve/fetch audio bytes, convert to NT SILK if needed, send OIDB upload request, perform highway HTTP upload when required, and produce Encodable MsgInfo bytes for commonElem.
- Wire record element support into element-builder: uploadPttMsgInfo is used to build a commonElem for 'record' sends; when SendContext is absent, record sends are skipped with a warning (graceful no-bridge path).
- Update message parsing to accept record segments from data.file, data.url or data.path and drop empty sources.
- Enable canSendRecord in OneBot instance context.
- Add tests covering record parsing and the graceful send path (packages/core/tests/message-parser.test.ts).
- Include prebuilt native ffmpeg addon binaries under packages/runtime/native/ffmpeg and update vite config to validate & copy the ffmpeg addon into the dist layout.
These changes enable sending voice messages by converting/encoding sources to the expected NT SILK format and uploading them through the existing highway/NTV2 flows.
Replace packages/runtime/native/snowluma-win32-x64.dll with an updated binary build. This commit updates the native Windows x64 runtime DLL; no other source changes are present in this diff.
Replace rebuilt native artifacts for Windows x64: packages/runtime/native/snowluma-win32-x64.dll and packages/runtime/native/snowluma-win32-x64.node. This updates the compiled DLL and Node addon (likely due to native fixes, dependency or build changes) without touching source files.
Introduce a new WebSocket package implementing RFC6455 functionality and permessage-deflate support. Adds core connection handling (packages/websocket/websocket.js), client wrapper (client.js), server and upgrade handling (server.js), extensions (permessage-deflate) and helpers (extensions.js), an index and native loader (native.js). Also include prebuilt native addon binaries for multiple platforms and integration points to use the native Parser and frame builder. The server supports handleUpgrade, subprotocol negotiation, and verifyClient hooks; the client performs handshakes and queues sends until open. Error handling, UTF-8 validation, close/ping/pong control frames, and max-payload checks are implemented.
Restructure the repository into a pnpm workspace under packages/ (core, webui, runtime). Move source files for core and webui into packages/*, add package manifests for @snowluma/core and @snowluma/runtime, and remove the old launcher package.json. Update root package.json to be a monorepo controller (scripts delegate to pnpm filters, set packageManager and Node engine). Configure build outputs to emit into the repo-root dist/ (vite config changes) so the existing release pipeline continues to work. Add .npmrc with mirrors, expand .gitignore for monorepo layout, add tsconfig base and package-level tsconfigs, and add vitest config for the core package. Adjust injector native search paths and update tests import paths to the new package layout. Small CI/workflow comment added to clarify build behavior and README updated with monorepo structure and common commands.