Developer guide
Monorepo layout, runtime startup chain, and contribution notes
SnowLuma is a TypeScript + native-module hybrid. TypeScript handles runtime orchestration, the OneBot implementation, the protocol bridge, the SDK, and the WebUI; native modules cover the hook, injection, and the high-performance WebSocket implementation.
Monorepo layout
pnpm workspace with five packages:
SnowLuma/
├─ packages/
│ ├─ core/ @snowluma/core Bridge / OneBot / Hook orchestration
│ ├─ websocket/ @snowluma/websocket In-tree WS impl (uses native addon)
│ ├─ sdk/ @snowluma/sdk Typed OneBot client for external use
│ ├─ webui/ webui React + Vite console
│ └─ runtime/ distribution templates (launcher, package.json, scripts)
├─ native/ per-platform native artefacts (.node / .dll / .so)
├─ dist/ build output
├─ tools/ helper scripts (version bump, release, etc.)
├─ docs/ ADRs and developer notes
└─ package.jsonCore startup chain
Entry point: packages/core/src/index.ts.
loadRuntimeConfig() ← reads config/runtime.json / env
↓
HookManager(autoLoadOnDiscovery)
↓
BridgeManager
↓
OneBotManager ← spins up OneBotInstance per UIN
↓
initWebUI(port=webuiPort) ← full builds onlyWhat the runtime creates:
HookManager— discovers QQ main processes and injects the native addon. WithhookAutoLoad: true, every new PID gets injected automatically.BridgeManager— decodes hook messages from the named pipe into bridge events; caches rkey / contacts / group members.OneBotManager— ownsOneBotInstances keyed by UIN; each instance has its ownMessageStore,MediaStore, andNetworkManager.initWebUI— full builds boot the WebUI; default port5099(override viaruntime.json.webuiPort).
Hook + native modules
The native hook module is loaded via process.dlopen(). Source lives in the separate dev/nnphook repo.
Filename convention:
snowluma-win32-x64.node snowluma-win32-x64.dll
snowluma-linux-x64.node snowluma-linux-x64.so
snowluma-linux-arm64.node snowluma-linux-arm64.soLoad search paths:
native/
dist/native/
packages/runtime/native/Native addon API:
getAllMainProcess— enumerate QQ main processes.loadModuleManual— manually map the injection module into the target process.unloadModuleManual— unload an injected module.
Default target process is QQ.exe on Windows, qq on Linux.
OneBot lifecycle
When the bridge detects a QQ session starting:
- Load
config/onebot_<uin>.json(or copy from global if missing). - Construct
OneBotInstance. - Boot HTTP / WS / reverse WS / HTTP-POST adapters per
networks.*config. - Asynchronously warm up the friend list, group list, and group members.
- Forward bridge events into OneBot events.
When the session closes the matching instance is released.
WebSocket package
@snowluma/websocket is the in-repo WebSocket implementation; its surface tracks ws closely while routing through a native fast path.
Exports:
WebSocket— client constructor.WebSocketServer— server constructor.Server— alias forWebSocketServer.InternalWebSocket— internal connection implementation.
Loads its own platform-specific .node from the same native/ search paths.
SDK package
@snowluma/sdk is a typed OneBot client for downstream consumers — standalone-publishable to npm and independent of the SnowLuma runtime. It's built inside the monorepo (see pnpm build:sdk / build:all below); for consumer-side usage see the SDK docs.
Dev scripts
pnpm install
pnpm dev # core dev mode
pnpm dev:web # WebUI dev server
pnpm build # core only
pnpm build:webui # WebUI only
pnpm build:sdk # SDK only
pnpm build:all # core + SDK + WebUI
pnpm test # core tests
pnpm typecheck # workspace typecheck
pnpm lint # workspace lintBuild order
Full distribution:
pnpm build:allRuns, in order:
@snowluma/corefull build@snowluma/sdkwebui
Output goes to the repo root dist/.
Docs site
The docs site lives in a separate repo: SnowLuma/SnowLumaDocs. Local development usually checks it out at dev/SnowLumaDocs/ alongside SnowLuma.
Stack: Rspress + React + TypeScript + MDX + KaTeX.
The OneBot API reference is generated by the docs repo's pnpm api:generate (also wired to prebuild) from docs/public/api/catalog.json — one page per action, plus a category overview and a searchable landing page. catalog.json is the action catalog produced by the main repo's collectActionDocs() (same shape as @snowluma/mcp's CatalogAction); the main repo's sync-docs-catalog workflow commits it here automatically via the SnowLuma bot on release — no manual upkeep.
Contribution notes
- Don't bypass
BridgeManager— every OneBot action should reach NTQQ throughBridgeInterface. Keeps the OneBot layer decoupled and testable. - Keep configs auto-generatable — new fields must stay backwards-compatible; normalize them on load and write the result back.
- Native modules are per-platform — when adding a platform, sync the
.nodeand the injectable library. - Tests first — core OneBot behavior should be validated with
vitest; seepackages/core/tests/. - API docs automation — just add the action with
defineAction(optionallyreturnsSchemato describedata);catalog.jsonis kept in sync by thesync-docs-catalogworkflow, so the API reference never drifts. Runpnpm api:generatelocally to preview.
Was this page helpful?
Last updated on