This commit removes deprecated QQ quick-login and user-list API calls from the frontend and updates the login page to use the newer quick-login response format. It also fixes the initial loading state by ensuring the spinner is cleared in a finally block and moves QQ list refresh to its own effect so the list loads reliably on first render.
Initialize comment like data required by QQNT and allow comments on upload batches while preserving single-image targets. Add action and native argument conversion regression tests.
Fixes#1979. Closes#2028.
Use the TypeScript parser instead of a regex that truncates nested generics and function types. Validate generated syntax and add a regression test. Include workspace aliases and PTY ambient declarations. The full type package build still reports six errors in third-party node-pty source; this commit does not claim to resolve that remaining issue.
Bundle required crypto and SSL DLLs and gate releases on a Windows native-load smoke test. Resolve loader paths independently of the working directory and encode file URLs correctly. Include the quick-login launcher built from Windows-Boot 0ff70ce10e34ac26411f9e6bcedaedfacc1e74f0. Validated builds, five path regressions, and live Shell and Windows Node startup to QR login.
Include the x64 Release hook built from NapCat-Windows-Boot commit 789e6cce00be40d02659e1aca992f8cd928b790a. SHA256: 7C48E7D10D77E2C3936E5D190AEB0DDEE353D55FD06DE81C714F2740112B94B1.
Related to #2091. The replacement passes 10 independent Win32 checks; the reported QQ crash remains to be verified in the reporter's environment.
Updated the external QQ appid, native, and packet tables for newer Linux and Windows builds, including architecture-specific Linux AppID entries. QQBasicInfoWrapper now prefers the matching x64/arm64 AppID before falling back to version-only lookups, and regression tests cover Linux/Windows version resolution and fallback behavior.
The Windows release workflow now uses a fixed QQ installer URL and SHA256 hash, verifies the downloaded installer before packaging, and makes the download cache key sensitive to the selected QQ URL, hash, and Node version. The workflow also switches QQ downloads to curl with retries for transient HTTP errors and centralizes the Node version variable to keep the build config consistent.
The release publishing workflow now installs pnpm via pnpm/action-setup instead of globally via npm, and applies the same improvement to the APIFox update job. This keeps the workflow consistent and avoids relying on the environment's global pnpm installation.
Add a project-level .npmrc so npm does not skip package lifecycle scripts during installation. This ensures dependency setup and initialization continue to run as expected.
This update adds the missing QQ face definitions for QSid 450-484 (EMCode 10450-10484) to the external face configuration. It covers newer emoji entries such as /撇嘴, /微笑, /无语, and /学习, aligning the config with the current face set.
Add support for release 9.9.32-55230: update packages/napcat-core/external/appid.json with Windows appid 537379411 and QUA, and add x64 send/recv mappings to packages/napcat-core/external/napi2native.json to support the new Win x64 build.
Sanitize formatted log messages by removing control characters and ANSI escape sequences when creating the message. Consolidates ANSI/control stripping into the initial message and removes the redundant replace in the file-only logging branch to prevent control/ANSI codes from polluting console or file logs.
Refresh the downstream release workflow to use the newer QQNT 3.2.30-50969 AppImage URLs for both x86_64 and arm64 builds.
Update release note prompt and AI model
Clarifies the release note prompt to require strict output format without wrapping the result in a code block. Also updates the release publish workflow to use `google/gemma-4-26b-a4b-it:free` instead of the previous OpenAI model endpoint setting.
Update QQNT installer URL in release workflow
Switches the release publish workflow to download a newer QQNT x64 installer (9.9.32.50969) from the updated qqdl.gtimg.cn source instead of the previous dldir1v6.qq.com link.
Add mappings for QQ 50969 builds
Add appid/QUA entries and native/packet send-recv offsets for the new 9.9.32-50969 Windows build and 3.2.30-50969 Linux x64/arm64 builds. Also normalize the existing 3.2.30-50828 x64 native recv offset format by removing the leading zero.
Update external version metadata to support new QQ releases. Added appid/qua entries for 9.9.32-50828 and 3.2.30-50828, plus corresponding send/recv native and packet offsets across x64 and arm64 targets.
Register new builds and architecture-specific offsets/IDs for 9.9.31-49738 and 3.2.29-49738. Updated packages/napcat-core/external/appid.json to add appid/qua entries, and napi2native.json and packet.json to add send/recv offsets for x64 (and arm64 where applicable). These additions track the new builds and their native mappings.
Replace the previous "New Feature" section with a short suggestion to try SnowLuma as a NapCat GUI alternative. Removes the v4.8.115+ notes about Stream API and recommending string IDs, simplifying the README and pointing users to the SnowLuma GitHub repository.
Add compilerOptions.rootDir = ".." to tsconfig.json for napcat-onebot, napcat-shell, and napcat-webui-backend to ensure the TypeScript compiler uses the monorepo package root for source resolution. Also remove an extraneous blank line in theme.tsx near FileManager.uploadWebUIFont (minor formatting cleanup).
CI: use `pnpm i --ignore-scripts` in release-publish workflow to avoid running package install scripts during CI.
Shell: defer showing the QR code until after attempting WebUi quick-login/password fallback. Adds checks for NAPCAT_QUICK_ACCOUNT and quick-password env vars (and WebUi quick-login list), runs WebUi quick config, and only calls getQRCodePicture() if no fallback was attempted and the user is not logged in. Includes error handling for the quick-login attempt.
Add external mappings for Windows x64 versions 9.9.30-48762 and 9.9.31-49599 across appid, napi2native, and packet files. appid.json: add appid 537352525 (9.9.30-48762) and 537355779 (9.9.31-49599) with QUA strings. napi2native.json: add send/recv hashes for 9.9.30-48762-x64 (0A9B1BC / 1F0324D) and 9.9.31-49599-x64 (0AF885C / 20058E1). packet.json: add send/recv offsets for 9.9.30-48762-x64 (2F3B960 / 2F3EEE0) and 9.9.31-49599-x64 (3082C40 / 30861C8).
Switch moduleResolution to "bundler" in base and package tsconfigs and consolidate path aliases for monorepo packages. Remove several package-level baseUrl entries and update package paths to reference ../../packages/* (add explicit napcat-common/src and napcat-image-size/src mappings). Also add a rootDir override for napcat-core. These changes unify module resolution and path aliases so TypeScript and bundlers resolve workspace packages consistently.
Introduce a safe PR build dispatch flow and related helpers.
- Add GitHubAPI.createWorkflowDispatch to .github/scripts/lib/github.ts and tighten getRepository nullability.
- Add .github/scripts/pr-build-dispatch.ts to dispatch an untrusted workflow_run (workflow_dispatch) for PR builds.
- Rewrite .github/workflows/build-pr.yml to split privileged checks (pull_request_target / issue_comment) from untrusted execution (workflow_dispatch):
- Add workflow_dispatch inputs for PR metadata.
- Ensure privileged jobs only check conditions, post comments and dispatch the untrusted build.
- Untrusted build jobs (framework/shell/publish) run under workflow_dispatch, checkout PR code into a separate workspace, clear GITHUB_TOKEN in build steps, and set stricter permissions and persist-credentials:false where appropriate.
- Adjust concurrency, outputs, and inter-job dependencies to work with inputs rather than passing sensitive data between privileged and untrusted contexts.
- Update trigger-docker and result-comment flows to rely on workflow_dispatch inputs and only run in the untrusted run where appropriate.
- Change packages/napcat-vite/vite-plugin-version.js to read NAPCAT_GITHUB_TOKEN (instead of GITHUB_TOKEN) to avoid exposing Actions write tokens in untrusted builds.
These changes aim to improve security by preventing execution of PR-controlled code with elevated repo permissions and by isolating token usage.
Add mappings for version 9.9.30-48517: update packages/napcat-core/external/appid.json with appid 537352474 and qua "V1_WIN_NQ_9.9.30_48517_GW_B", and update packages/napcat-core/external/napi2native.json with the x64 mapping (send: "0A9B1BC", recv: "1F0324D"). These entries add support for the new 9.9.30-48517 release.
Remove the explicit `token: ${{ secrets.NAPCAT_BUILD }}` line from the release-publish GitHub Actions workflow. This stops passing the custom NAPCAT_BUILD secret to the release step, allowing the action to use the default authentication mechanism or another configured token and reducing exposure of the custom secret.
Change the OPENAI_MODEL environment variable in .github/workflows/release-publish.yml from "openrouter/hunter-alpha" to "z-ai/glm-4.5-air:free" so the release-publish job uses the new model endpoint for OpenAI API calls. No other workflow changes.
Update packages/napcat-core/external/napi2native.json and packet.json to include send/recv offsets for 3.2.26-46928 (x64 and arm64) and 9.9.28-46928-x64. Arm64 entries reuse the same offsets as 3.2.26-46494-arm64; new x64 offsets were added for both files.
Replace secrets.NAPCAT_BUILD with the built-in secrets.GITHUB_TOKEN in the release-publish workflow to authenticate triggering downstream release workflows. This removes dependency on a custom secret and uses the repo-scoped Actions token for simpler, more secure automation.
Update the OPENAI_MODEL env var in .github/workflows/release-publish.yml from "stepfun/step-3.5-flash:free" to "openrouter/hunter-alpha" so the release publish job uses the new model for API calls. No other workflow changes.
Add a fallback for video duration by including this.getDuration(videoPath).catch(() => 60) in the Promise.all alongside fileTypeFromFile. This prevents Promise.all from rejecting when duration retrieval fails and supplies a sensible default (60s) for downstream processing (e.g., thumbnail generation).
Remove prefetching of video duration from the initial Promise.all and change getDuration to stop swallowing errors: it now throws when ffprobe returns a non-numeric duration (including the raw stdout in the error) instead of returning a default 60s. This prevents silently masking ffprobe failures — callers should handle or catch errors from getDuration.
Replace three entries in packages/napcat-core/external/napi2native.json that used the '-46949' suffix with '-46494' for versions 9.9.28-x64 and 3.2.26 (x64 and arm64). send/recv hashes are unchanged; this corrects the version/build identifiers in the mapping.
Expose an isLocal boolean from uriToLocalFile to indicate user-owned files vs temporary downloads/decodes, and update callers to avoid deleting or cleaning up user local files. Update OneBot file APIs to accept the isLocal hint (including createValidSendFileElement/createValidSendPicElement/createValidSendVideoElement) and adjust temp-file handling for videos: local files are copied into the NapCat temp dir with a random UUID filename to avoid polluting user directories, while temporary files get an added extension in-place. Also adjust deleteAfterSentFiles usage, image/video thumb handling, and numeric parsing fallbacks for element fileSize to be more robust. Minor imports (randomUUID) and related callsites were updated accordingly.
Remove filesystem stat calls and the node:fs/promises import; replace the async size calculation with a synchronous reduce that sums parseInt(fileSize) from each send element (falls back to 0 on parse failure). This avoids runtime I/O, simplifies the logic, and still provides a totalSize used to compute message timeout.
Introduce timeout configuration and automatic timeout estimation for uploads/downloads. Added TimeoutConfig to OneBot config with baseTimeout, upload/downloadSpeedKBps and maxTimeout, plus calculateTimeout and capTimeout helpers. Applied estimation to FileApi.downloadFileById calls (GetFile, BaseDownloadStream) and to message sending (OneBotMsgApi) to compute timeouts from total payload size; sendMsg now accepts an optional timeout override which is capped by maxTimeout. Updated SendMsg payload schema to allow a custom timeout, and updated web UI store, types and config form to expose timeout settings and defaults.
Upgrade workflow action versions across .github/workflows: actions/checkout@v4 -> @v5, actions/setup-node@v4 -> @v6, actions/upload-artifact@v4 -> @v6, and actions/download-artifact@v4 -> @v7. Changes touch auto-release.yml, build.yml, pr-build.yml, and release.yml to keep CI tooling current and compatible with newer runner features; also add a missing newline at end of auto-release.yml.
Add send/recv offsets for several new builds to packages/napcat-core/external/napi2native.json and packages/napcat-core/external/packet.json. Entries added: 9.9.27-46949-x64 and 3.2.26-46949-(x64, arm64) in napi2native.json; 3.2.26-46494-(x64, arm64) and 9.9.28-46494-x64 in packet.json. These register offsets for newly encountered builds.
Small cleanup across multiple packages: adjust TypeBox imports (add TSchema) and reorder imports in napcat-core/helper/config.ts; normalize indentation and type formatting in napcat-protobuf/NapProto.ts; add missing trailing commas and minor object formatting fixes in tests (packages/napcat-test/schema.test.ts); remove an extra blank line in external-shims.d.ts; and remove an unnecessary blank line in post-build.mjs. These are whitespace/formatting and minor import fixes to satisfy linting and type checks.
Move logSubscription.notify into the branch that calls this.logger.log and remove the previous external call. This ensures the subscription is notified only when the configured logger is used, avoiding redundant or spurious notifications.
Set file logging off by default and defer creation of the File transport until file logging is enabled. Store logPath and fileLogLevel (with fileTransportAdded flag) so the file transport can be added later with the correct filename and level. Remove the eager File transport from the constructor, update setFileAndConsoleLogLevel to persist fileLogLevel, and add the transport in setFileLogEnabled(true). Improve _log to only format messages when needed and notify subscribers once. Replace some direct logger.* calls with wrapper methods for consistent handling when deleting/reading old log files.
Delete packages/napcat-onebot/test_schema.ts — a standalone script that compiled and validated OB11 TypeBox schemas and performed a sample validation. This file appeared to be a local test/diagnostic harness and was removed as part of cleanup to avoid keeping ad-hoc test scripts in the package source.
Use Value.Parse from @sinclair/typebox/value instead of the previous Value.Default + Value.Convert sequence across the codebase. Updated config loaders, OneBot action handling, tests and web UI helpers to rely on Value.Parse so schema defaults and coercion are applied consistently and errors surface in a single Parse call. Added two scratch files (scratch.ts, scratch2.ts) to inspect Parse error structure and boolean coercion behavior, and adjusted a test type annotation in test_schema.ts.
Measure local time before and after fetching server time and compute offset using the midpoint (compensates for network latency). Round the calculated offset and lower the adjustment threshold from 5000ms to 500ms to avoid applying small corrections. Also rename timing variables for clarity.
Migrate schema validation from AJV to @sinclair/typebox across the monorepo. Key changes:
- Core validation: ConfigBase now uses TypeCompiler/Value (TypeBox) for compile/defaults/coercion and replaces Ajv usage.
- OneBot & Protocol: loadConfig functions and related config loaders updated to use Value.Default/Convert and TypeCompiler.Compile with improved error reporting.
- OneBot action validation: OneBotAction now compiles TypeBox schemas, applies defaults/conversions and returns TypeBox errors.
- Web UI backend: use TypeBox Value/TypeCompiler to fetch and validate defaults for Napcat/Web UI configs.
- Types/scripts: removed AJV type shims and adjusted post-build script to stop special-casing AJV types.
- Dependencies: removed ajv from several package.json files and added/normalized @sinclair/typebox usage; updated pnpm-lock accordingly.
- Tests/tools: added schema validation test utilities and tests (packages/napcat-onebot/test_schema.ts and packages/napcat-test/schema.test.ts) to validate schema compilation, coercion, and defaults.
This change standardizes on TypeBox for runtime schema compilation, default population and type coercion, simplifying validation logic and improving default handling across packages.
Remove a pointless `void options.callbackTimeout;` no-op in napcat-rpc client. In the service worker template, add `/* eslint-disable no-undef */` and an explicit `return undefined;` in the cache cleanup callback to make the return value explicit and satisfy linters. In the OneBot debug UI, call `sendRequest(value)` without the leading `void` so the returned promise is not intentionally ignored.
Apply a collection of small code cleanups across the repo for consistency and lint-safety. Changes include:
- Use strict equality (===) where appropriate (GetEmojiLikes, about page checks).
- Replace Array.map used for side effects with Array.forEach (GetMsg).
- Rename unused catch parameters to underscore-prefixed names to avoid lint warnings (multiple backend/middleware files).
- Replace void with undefined in an actions.call invocation (builtin plugin index).
- Remove an unused loadedCount variable when reading .env (napcat-shell).
- Rename promise resolver parameter to `resolve` for clarity in tests and keep setTimeout usage (rpc.test.ts).
- Strengthen external shims types by changing generic parameter names to _T and update inversify ServiceIdentifier generic param (external-shims.d.ts).
- Simplify post-build script imports and comment out an external-type mapping block; fix a regex character class bug (post-build.mjs).
- Prefix several unused test stub variables with underscore to indicate intentional unused status (test-dist.ts).
- Minor JSX formatting/indentation fixes in password_login component and UI text indentation in system_info.
- Misc: SSE/config and plugin config handlers adjusted to consistent catch parameter naming; update mirror/download error catch variable name.
These edits are non-functional refactors focused on code style, lint compliance and small robustness/clarity improvements.
Normalize code style across multiple packages: whitespace cleanup, consistent commas and trailing commas in arrays/enums/objects, fix table markdown lines in CI comment template, ensure newline at EOF, normalize header/object property quoting and spacing, remove stray blank lines and minor non-functional comment tweaks. These are formatting-only changes and small type/annotation spacing adjustments; no functional behavior changes intended.
Backend: add per-UIN config support (napcat_{uin}.json) with read/write helpers, handlers (GetUinConfig/SetUinConfig) and router entries; handlers check login status via WebUiDataRuntime and fall back to napcat.json when needed. Frontend: add QQManager methods to get/set per-UIN config, new CoreConfigCard React component for core settings (autoTimeSync, fileLog, consoleLog) and register it in the config page tabs. Types: expose autoTimeSync in NapCatConfig type. Config writes create config directory and merge updates with existing per-UIN config.
Add autoTimeSync (default: true) to the Napcat config and honor NAPCAT_DISABLE_TIME_SYNC=1 or autoTimeSync=false to disable automatic time synchronization. When enabled, time sync is attempted via getServerTime with errors logged; warning threshold for significant drift increased from 1s to 5s. Adds informational log when auto time sync is disabled.
Introduce helper server-time.ts that preserves the original Date.now and provides hookGlobalDateNow(getServerTimeFn) to compute an offset from a server timestamp and override Date.now when the offset is significant. The function parses a server time string, returns the computed offset, and only patches Date.now if |offset| > 5000ms. Export the helper and call it in NapCatCore startup using session.getMSFService().getServerTime(), logging synchronization results (info for small offsets, warning for >1s) and catching errors. Improves global time consistency with server-provided time.
When existing lookup methods fail to find a referenced/reply message, try a protocol-level fallback using PacketApi. If PacketApi.packetStatus is available, attempt FetchGroupMessage or FetchC2CMessage by sequence, match by contentHead.sequence, and use contentHead.newId as the message id to build reply data. Log warnings on success/not-found and errors on exceptions.
Prevent the main process from writing logs to file when running in multi-process mode. base.ts and napcat.ts now disable file logging unless the process is a worker or multi-process mode is disabled (checks NAPCAT_WORKER_PROCESS / NAPCAT_DISABLE_MULTI_PROCESS and ENV.isWorkerProcess / ENV.isMultiProcessDisabled). This reduces duplicate log output and disk I/O by ensuring only worker processes write log files.
Replace direct schema references inside Type.Intersect with Type.Omit(schema, []) in two places (OB11MessageSchema and OB11MessageImageSchema). This avoids reusing the original schema metadata/$id when intersecting, preventing duplicate-id or type-merging issues with TypeBox/OpenAPI generation.
Start the WebUI earlier and integrate it with the login process. Initialize WebUI before user login so the UI can control and display login status; set working environment and start InitWebUi asynchronously. Add login listener handlers to update WebUiDataRuntime for QR updates, session failures, login errors, connection events and history. Introduce registerWebUiLoginCallbacks to expose refresh QR, quick login, password/captcha/new-device login flows to the WebUI and update loginContext and UI state accordingly. Also set QQ data path after successful login.
Remove the onlyBuiltDependencies section from pnpm-workspace.yaml to simplify the workspace configuration. The removed list included '@heroui/shared-utils', '@homebridge/node-pty-prebuilt-multiarch', '@swc/core', esbuild, sharp, ttf2woff2, and unrs-resolver; the file now only declares packages: - packages/*.
Switch the release workflow to use the NAPCAT_BUILD secret instead of the default GITHUB_TOKEN. This allows the release job to run with a dedicated token (e.g., with different scopes or credentials) when creating tags, changelogs, and uploading release artifacts.