Skip to content

Win7 x64, Ubuntu 20.04+ and macOS 15 packages; document conversion/OCR, white-label, bundled FFmpeg - #1

Merged
airzope merged 29 commits into
mainfrom
claude/vxkex-win7-x64-compat-b7vtnr
Sep 29, 2026
Merged

airzope merged 29 commits into
mainfrom
claude/vxkex-win7-x64-compat-b7vtnr

Conversation

@airzope

@airzope airzope commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Summary / 摘要

This PR adds Desktop packages for Windows 7 SP1 x64, Ubuntu 20.04+ (x64 and arm64), and macOS 15+ (Intel and Apple silicon). It also adds offline document conversion (AnyDoc), text recognition (PaddleOCR PP-OCRv5), build-time white-label branding, and bundled FFmpeg for audio and video. Three community Office plugins were evaluated and none is integrated.

本 PR 新增 Windows 7 SP1 x64、Ubuntu 20.04+(x64/arm64)与 macOS 15+(Intel/Apple silicon)安装包,以及离线文档转换(AnyDoc)、文字识别(PaddleOCR PP-OCRv5)、构建时白牌配置和内置 FFmpeg 音视频处理。另评估了三个社区 Office 插件,均未集成。

Windows 7 x64 (VxKex NEXT)

  • Carrier: on NT 6.1 the carrier sets NODE_SKIP_PLATFORM_CHECK=1 for the bundled Node 24 and disables GPU acceleration. WORKDSH_WINDOWS7_COMPAT=1|0 overrides detection.
  • Installer: registers WorkDSH.exe with VxKex's own KexCfg.exe and removes that registration on uninstall. It also reports Windows updates it cannot redistribute: SP1, KB2533623, KB2670838 and WMF 5.1.
  • Offline installer: dist/win7/…-win7-x64-Offline-Setup.exe (scripts/package-win7.ts) wraps the same win-unpacked. It carries VxKex NEXT 1.2.3.2463 and the Microsoft VC++ runtime 14.44.35211, the last build that runs on Windows 7, both pinned by SHA-256. Each is installed silently when missing.
  • Audit: scripts/windows7-payload-audit.ts resolves every x64 PE import against Windows 7, VxKex, the VC++ runtime and the payload itself. It also requires the offline content: Node, Python with the Office libraries, the Office skills, LibreOffice Kit, AnyDoc, the OCR models and FFmpeg.

Ubuntu 20.04+ x64 and arm64

  • Packages: dist:linux builds …-linux-<amd64|arm64>.deb natively on each architecture. Dependencies renamed for 64-bit time_t on Ubuntu 24.04 are declared as alternatives, and the package recommends fonts-noto-cjk.
  • SenseVoice on 20.04: the x64 sherpa-onnx 1.13.8 binding is recompiled from the pinned upstream commit 11afbd00 with GCC 9, in a digest-pinned ubuntu:20.04 container (scripts/linux-sherpa-onnx.ts).
  • Audit: scripts/linux-glibc-audit.ts rejects any bundled ELF that needs more than glibc 2.31, GLIBCXX_3.4.28 or CXXABI_1.3.12, with no exceptions.
  • Container smoke: each .deb is installed into clean ubuntu:20.04 and ubuntu:24.04 containers, which then run every bundled runtime (scripts/smoke-ubuntu-deb.sh → smoke-bundled-runtime.sh).

macOS 15+ Intel and Apple silicon (unsigned)

  • Native builds: each DMG is built by Node of its own architecture, on macos-15-intel and macos-15. pnpm installs the per-CPU packages that match the Node running it (LibreOffice Kit, sherpa-onnx, canvas, AnyDoc), so a cross-built DMG would carry the wrong ones. package-mac/release-mac now refuse a mismatch.
  • Audit: scripts/macos-compat-audit.ts reads each Mach-O's architecture slices and minimum macOS. It rejects missing target slices, another CPU's platform packages, and anything that needs a macOS newer than 15.0.
  • DMG smoke: scripts/smoke-macos-dmg.sh mounts the DMG and runs the shared runtime smoke on macOS 15.

Document conversion and OCR (Library)

  • AnyDoc (@firecrawl/anydoc 0.2.4) converts DOC, XLS/XLSX, PPT, ODT/ODS/ODP, RTF, EPUB and CSV to searchable Markdown.
  • PaddleOCR PP-OCRv5 mobile runs with ONNX Runtime Web (WebAssembly) in a worker thread. It recognizes images and the PDF pages that have no text layer; models and runtime are pinned by SHA-256.
  • Queue: conversion runs outside the Library's serial queue. A failed recognition keeps the original file.
  • Agent tools: document_to_markdown and document_ocr.
  • Checks: every package requires both engines, and the packaged runtime converts a CSV and recognizes a rendered image. The OCR smoke folds look-alike glyphs (O/0, I/1), because runner fonts differ.

Build-time white-label

  • Brand directory: a brand directory (brand.json, logo.png, optional mark.svg) selected by WORKDSH_BRAND sets:
    • the product and file names, appId, and the Linux command and package;
    • the user-data folder and all icons;
    • the window title, the sidebar name and mark, and the page title;
    • the creator of exported XLSX and PDF files.
  • Default brand: branding/workdsh/ is the default, and its generated icons are byte-identical to the icons previously committed.
  • Generation: scripts/generate-brand.ts writes build/brand/. Packaging reads the generated brand and adds electron-builder overrides only where it differs from WorkDSH, and afterPack checks that the brand files are packaged.
  • Runtime: the carrier passes WORKDSH_BRAND_NAME/WORKDSH_BRAND_MARK, and workdsh-bundle serves them at /api/workdsh-brand.
  • CI: a manual CI run accepts a brand input.
  • Docs: see docs/white-label.md.

Bundled FFmpeg (audio/video)

  • Build: Shaka Project static-ffmpeg-binaries n8.1.2-1 (FFmpeg 8.1.2, GPLv3, with x264, x265, libvpx, SVT-AV1, Opus, LAME), pinned by SHA-256 for all five targets.
    • The Windows build links msvcrt and imports nothing newer than Windows 7.
    • The Linux builds are fully static.
    • The macOS builds require 15.0.
  • Staging: scripts/prepare-workdsh-media.ts stages it in workdsh-runtime/media/ together with manifest.json, COPYING.GPLv3 and SOURCES.md. It fails when a required encoder is missing.
  • Skill: the Office plugin registers the media-ffmpeg skill: inspect, convert, compress, trim losslessly by stream copy, join, and extract audio. The skill names the bundled executables' absolute paths. The agent runs them through DSH's command tool, so approvals and the sandbox apply.
  • Checks: every platform audit requires FFmpeg. scripts/smoke-media.mjs synthesizes a clip, cuts it losslessly, converts its audio and compresses it, in the Ubuntu, macOS and Windows packaged-runtime smokes.

Community Office plugins: evaluated, not integrated

Package Verdict Blockers
dsh-univer-office 0.3.5 No Unlicensed @univerjs-pro code with an embedded key that expires 2026-11-15; needs glibc 2.35; telemetry and CDN assets by default; runs model-written JS outside the sandbox.
@huiliyi37/dsh-office 0.2.4 Not as-is Reads and writes model-supplied paths with node:fs, bypassing the DSH file service, sandbox and WorkDSH access control and audit; no source repository.
dsh-officecli 0.1.1 No Uses an icon missing from DSH 0.1.7-rc.2; its preview route has no connection check and rewrites Host/Origin; the .NET 10 officecli updates itself and has no Windows 7 support.

CI and fixes along the way

  • CI matrix: desktop-linux on x64 and arm64 runners, desktop-macos on macOS 15 Intel and Apple silicon, plus the Windows 7 installer in the Windows job.
  • Fixes:
    • The Windows 7 NSIS wrapper includes installer.nsh by full path.
    • The packaged brand is read with platform path separators.
    • media/ is included in extraResources.
    • Each Profile pnpm install gets five minutes before the bound that ends a pnpm stuck after finishing; the Office plugin install took longer than 90 s on the Intel runner.
    • The Windows 7 audit fixtures get time for Defender scans.

Related Issues / 关联 Issue

N/A

Type / 类型

  • Bug fix / 问题修复
  • Feature / 新功能
  • Documentation / 文档
  • Release or packaging / 发布或打包
  • Tests only / 仅测试
  • Other / 其他

Platforms / 影响平台

  • Windows installer / Windows 安装包
  • Windows portable ZIP / Windows 便携版 ZIP
  • macOS Apple Silicon
  • macOS Intel
  • macOS Universal package / macOS 通用安装包
  • Linux
  • Not platform-specific / 与平台无关

Verification / 验证

  • corepack yarn check:layout: bilingual records consistent.
  • corepack yarn typecheck
  • corepack yarn test: Desktop 159 tests (158 passed, 1 Windows-only skip); Web Library, bundle brand and media tests pass.
  • Platform package smoke / 平台打包或启动冒烟: CI run #15 on aa910b9 is green on every job.
    • Windows: the standard and Windows 7 offline installers were built; the Windows 7 import audit (including ffmpeg.exe) passed; the post-fuse runtime smoke passed (DSH CLI, AnyDoc, OCR, FFmpeg).
    • Ubuntu x64 and arm64: the Ubuntu 20.04 ELF audit passed, and the .deb installed and ran every runtime in ubuntu:20.04 and ubuntu:24.04, including SenseVoice, DOCX→PDF, AnyDoc/OCR and FFmpeg.
    • macOS Intel and Apple silicon: the Mach-O audit for macOS 15 passed, and the DMG ran the shared runtime smoke on a macOS 15 runner.
  • Manual test / 人工测试: not yet run on a real Windows 7 SP1 x64 machine, a real Ubuntu desktop, or a real Mac

Other checks actually run:

  • FFmpeg compatibility:
    • Windows 7: the imports resolve on plain Windows 7, and the Wine smoke passes.
    • Linux x64: the smoke passes in ubuntu:20.04.
    • Linux arm64: the smoke passes in Ubuntu 20.04 arm64 under qemu.
    • macOS: both builds require 15.0 and link only system libraries.
  • FFmpeg, locally: smoke-media.mjs ran against the staged Linux build and the built Office plugin: a 2.17 s lossless cut, MP3 conversion, and compression from 201874 to 51765 bytes.
  • Earlier checks:
    • OCR output quality matched the RapidOCR reference.
    • Real SenseVoice transcription on Ubuntu 20.04 with the rebuilt binding.
    • Wine-based Windows 7 installer scenarios.

Release Notes / 发布说明

  • New assets:
    • Windows 7 SP1 x64 offline installer, with VxKex NEXT and the VC++ runtime; best effort;
    • Ubuntu 20.04+ .deb for x64 and arm64;
    • macOS 15+ DMGs for Intel and Apple silicon, unsigned.
  • The Library converts Office, OpenDocument, RTF, EPUB and CSV files and recognizes images and scanned PDFs, offline.
  • Audio and video conversion, compression and lossless trimming through the bundled FFmpeg.
  • Build-time white-label configuration (docs/white-label.md).
  • Before tagging a release:
    1. VxKex NEXT publishes no license. Redistributing it relies on its authors' permission, recorded in THIRD_PARTY_NOTICES.
    2. FFmpeg is GPLv3. Attach the corresponding source archives listed in media/SOURCES.md (FFmpeg n8.1.2, x264 0480cb0, x265 4.2, libvpx v1.16.0, SVT-AV1 v4.1.0, Opus v1.6.1, LAME 3.100, Mbed TLS v3.4.1, and the Shaka build scripts at 88caac41) to the release.
    3. Web package versions: publish the changed Web packages (workdsh-plugin-library, workdsh-plugin-office, workdsh-bundle) at new versions. Tag builds install published packages.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs

On NT 6.1 the carrier now sets NODE_SKIP_PLATFORM_CHECK=1 before it
starts the DSH Host, because the bundled Node.js 24 exits below Windows
10 without it and VxKex does not spoof the version Node checks. It also
disables GPU hardware acceleration: Windows 7 has no DirectComposition
and a repeatedly failing GPU process terminates Electron.

Detection uses os.release(), which VxKex NEXT leaves unspoofed for
Chromium and Node processes; WORKDSH_WINDOWS7_COMPAT=1|0 overrides it.
Browser workers run the same entry point and take the same policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
On Windows 7 / Server 2008 R2 the NSIS installer now requires VxKex
NEXT (HKLM\Software\VXsoft\VxKex KexDir) and stops with exit code 2 and
a download link when it is missing. It registers the installed
WorkDSH.exe through VxKex's own KexCfg.exe with propagation and
app-specific fixes on, leaving version spoofing to the user, then waits
up to 10 seconds for the IFEO filter key because KexCfg may apply it
through its asynchronous SYSTEM elevation task.

Uninstall removes the registration only when it exists and never during
an upgrade, where the removal could race the new installer's
registration. Other Windows versions are unaffected.

Validated with makensis -WX and under Wine configured as Windows 7 and
Windows 10 with a stand-in KexCfg.exe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Add bilingual FAQ, user-guide, README, and Desktop package guidance,
the Windows 7 issue-template option, and an Agent Note recording the
installer and carrier policy, its limits, and the remaining native
Windows 7 verification gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Require the offline content (Node.js, pnpm, Python with the Office
libraries, the Office skills, the LibreOffice Kit engine, the DSH Profile
and package cache) and resolve the static imports of every x64 PE image
against the payload, the VC++ runtime, VxKex NEXT 1.2.3.2463's rewrite
table and prebuilt DLLs, and Windows 7 SP1 system DLLs.

Calibrated on the pinned Electron 43.3.0, Node.js 24.21.0, Python 3.12.14
wheels and LibreOffice Kit 0.1.2 Windows binaries: all 143 x64 images
resolve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
dist:win7 audits dist/win-unpacked, downloads the pinned VxKex NEXT
1.2.3.2463 setup (SHA-256 checked), copies a Microsoft-signed
Windows 7-capable vc_redist.x64.exe (14.29-14.4x) from Visual Studio, and
wraps the same application with --prepackaged into
dist/win7/WorkDSH-<version>-win7-x64-Offline-Setup.exe. The release
script runs it on Windows.

On Windows 7 the offline installer silently installs the VC++ runtime
and VxKex NEXT through UAC only when missing or older, verifies them from
file and registry versions, then registers WorkDSH.exe. Both installers
now list missing Windows prerequisites they cannot redistribute: SP1,
KB2533623, KB2670838, WMF 5.1, and (standard only) the VC++ runtime.

Validated with makensis -WX and under Wine as Windows 7/10 with
stand-in setup programs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Upload dist/win7 as dsh-plugin-desktop-windows7-x64 so tagged releases
attach it, keep the Windows 7 audit report as a separate artifact, allow
90 minutes for the second NSIS package, and mention the package in the
release notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Update the download table, FAQ, user guides, Desktop README, and Agent
Note, and record in THIRD_PARTY_NOTICES that the offline installer
carries VxKex NEXT, which publishes no license, and the Microsoft VC++
redistributable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
The afterAll hook resolves the desktop root with realpathSync, so on
macOS (/var -> /private/var) and Windows 8.3 temp paths the recorded
executable differs from the unresolved temp root. Compare against the
resolved root.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
CI's windows-latest image now carries Visual Studio 2026, whose only
redistributable (14.51) requires Windows 10, and a Windows PowerShell
child could not load Get-AuthenticodeSignature under the PowerShell 7
PSModulePath exported by Actions.

Download Microsoft's VC_redist.x64.exe 14.44.35211, the last Visual
Studio 2022-stream build that supports Windows 7 SP1, from its versioned
URL and accept only the SHA-256 that URL embeds. WORKDSH_WIN7_VC_REDIST
still accepts an explicit Microsoft-signed 14.29-14.4x file, now checked
without the inherited PSModulePath. Share the pinned-download helper with
the VxKex NEXT setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Select the upstream linux-x64 or linux-arm64 primary runtime from the host
architecture and package a workdsh .deb natively with electron-builder.
Libraries renamed for 64-bit time_t on Ubuntu 24.04 are declared as
alternatives (libasound2t64 | libasound2), because a bare libasound2 can
resolve to liboss4-salsa-asound2, which lacks the ALSA symbols Electron needs.

The Linux audit parses .gnu.version_r of every target-architecture ELF image
and rejects requirements newer than Ubuntu 20.04 provides (GLIBC 2.31,
GLIBCXX 3.4.28, CXXABI 1.3.12). It also checks the main executables'
architecture and the offline Node.js, Python, Office skills, and LibreOffice
Kit WebAssembly engine. smoke-ubuntu-deb.sh installs a package in a clean
container and converts a DOCX to PDF with the bundled runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Add a desktop-linux matrix on ubuntu-24.04 (x64) and ubuntu-24.04-arm
(arm64). Each job builds through the single release script, installs the
.deb into clean ubuntu:20.04 and ubuntu:24.04 containers, and uploads the
package and its Ubuntu 20.04 audit. Releases attach both packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…indows 7 variant

electron-builder adds its templates/nsis/include directory, which has its own
installer.nsh. The Windows 7 wrapper's bare `!include "installer.nsh"`
resolved to that template, so its macros were defined twice ("macro named
extractEmbeddedAppPackage already exists") and the VxKex and VC++ logic was
never compiled in. Include build/installer.nsh through BUILD_RESOURCES_DIR,
as the payload definitions already are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
@airzope airzope changed the title Windows 7 x64 support through VxKex NEXT, with an offline installer Windows 7 x64 offline installer (VxKex NEXT) and Ubuntu 20.04+ x64/arm64 packages Sep 29, 2026
… Linux audit

The first native x64 build failed the Ubuntu 20.04 audit on
sherpa-onnx-linux-x64/sherpa-onnx.node from sherpa-onnx-node 1.13.8, which
the pinned DSH uses for experimental local SenseVoice speech-to-text. Only
that Node-API binding is built with GCC 11 on glibc 2.32
(__libc_single_threaded, std::__throw_bad_array_new_length); its ONNX
libraries and the whole arm64 build pass. DSH loads it only inside the
SenseVoice recognition process, and replacing it would modify the pinned DSH.

Record it as the audit's one feature exception: that file may need up to
Ubuntu 22.04's glibc 2.35, GLIBCXX_3.4.30, and CXXABI_1.3.13, and is
reported under limitedFeatures. Anything newer, or any other file, still
fails. The container smoke loads the binding and requires success from
glibc 2.35 on. Document that Ubuntu 20.04 x64 lacks this one feature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
… on Ubuntu 20.04

DSH's local SenseVoice speech-to-text uses sherpa-onnx-node 1.13.8.
Upstream builds its C API and ONNX Runtime libraries, and its arm64
binding, for glibc 2.17, but compiles the x64 sherpa-onnx.node on its CI
host, so it needs GLIBC_2.32 and GLIBCXX_3.4.29 and fails to load on
Ubuntu 20.04.

Before electron-builder copies the Profile, scripts/linux-sherpa-onnx.ts
finds every binding of the target architecture above the Ubuntu 20.04
limits. For each one it:
- fetches the binding sources at the pinned upstream commit with a sparse
  Git checkout and verifies the commit;
- compiles them with GCC 9 in a digest-pinned ubuntu:20.04 container, with
  upstream's flags and pinned node-addon-api 8.9.2 and node-api-headers
  1.9.0 dev dependencies;
- links the result against the package's own libsherpa-onnx-c-api.so;
- checks the result's architecture and symbol versions;
- renames it over the published file, so a store hard link stays intact.
Other sherpa-onnx releases are refused until their source is pinned.

The rebuilt binding needs GLIBC_2.14 and GLIBCXX_3.4.26 and imports the
same 202 Node-API and C API functions. With DSH's pinned SenseVoice model
it transcribes the sample recordings on Ubuntu 20.04, and on Ubuntu 24.04
it gives the same text as the published binding.

This removes the audit's Ubuntu 22.04 exception. The container smoke now
requires the binding to load and run native code on every release. It
also reads the glibc version with getconf rather than `ldd | head`, which
could fail with SIGPIPE under pipefail (CI run 5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
pnpm installs the Profile's per-CPU packages (LibreOffice Kit's native
engine, sherpa-onnx, @napi-rs/canvas) for the Node that runs it, so an x64
DMG packaged by arm64 Node carried only arm64 builds of them. Office
conversion and speech recognition would fail on Intel Macs, while the
lipo checks on the main executable, Node and Python still passed.

package-mac.ts and release-mac.ts now refuse a target architecture other
than the Node architecture. scripts/macos-compat-audit.ts parses thin and
universal Mach-O files (LC_BUILD_VERSION, LC_VERSION_MIN_MACOSX) in the
.app and fails on:
- executables without the target slice;
- platform packages installed only for another CPU, matched by name;
- target images or LSMinimumSystemVersion newer than macOS 15.0;
- incomplete offline content.
It writes macos-audit.json before asserting.

The Ubuntu smoke's runtime checks move to smoke-bundled-runtime.sh, which
also requires Electron and Node to report the target CPU. The new
smoke-macos-dmg.sh mounts a DMG and runs the same checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
Build x64 on macos-15-intel and arm64 on macos-15, run the DMG's bundled
runtimes on that macOS 15 host, and upload the macOS audit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
… PaddleOCR

The Library now imports DOC, XLS/XLSX, PPT, ODT/ODS/ODP, RTF, EPUB and CSV
through AnyDoc (@firecrawl/anydoc 0.2.4, local conversion only; its hosted
OCR option is never used), and images (PNG/JPEG/BMP/GIF/WebP/TIFF) through
PaddleOCR PP-OCRv5 mobile.

PDF pages without a text layer are rendered with PDF.js on the Profile's
@napi-rs/canvas and recognized, up to 100 per file. Pages with a text layer
are still extracted directly.

OCR runs the models on ONNX Runtime's WebAssembly build in a worker
thread, so it needs no per-platform inference binaries and never blocks
the Host event loop. The pre- and post-processing follows PaddleOCR's DB
detection and CTC decoding without OpenCV. It matches the reference
RapidOCR output on the same models.

scripts/prepare-library-ocr.mjs stages the models (SHA-256-pinned archive
and files) and the three ONNX Runtime files the Node entry loads into
resources/ocr; WORKDSH_OCR_MODEL_ARCHIVE allows offline builds.

Conversion leaves the Library's serial queue: an import checks in the
queue, converts outside it, and commits in the queue after re-checking.
Pictures and scanned PDFs can switch between the original and the
recognized text, and conversion notes appear above the document.

Two Agent tools read workspace files by path: document_to_markdown
returns paged Markdown for every supported format, and document_ocr
recognizes images or selected PDF pages with per-page confidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
The Linux, macOS and Windows 7 audits require the OCR models and the
ONNX Runtime WebAssembly file in the Library package, and the AnyDoc
native engine for the target platform.

smoke-document-engines.mjs converts a CSV with AnyDoc and recognizes a
rendered picture with the OCR worker through the packaged Library. It
runs with the bundled Node:
- in the post-packaging Profile gate on every platform, which is the only
  runtime check on Windows;
- in the shared container and DMG smoke.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…smoke

The Ubuntu arm64 runner's sans-serif renders O and 0 alike, so PaddleOCR
read INV0ICE. The smoke checks that the packaged engine runs end to end;
compare after folding O/0 and I/L/1 and log what was read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…d artwork

A brand directory (brand.json, logo.png, optional mark.svg) selected by
WORKDSH_BRAND now decides the product name, file and executable names,
appId, Linux package, user-data folder and every icon when the carrier
is built. branding/workdsh/ is the default and matches package.json.

- scripts/generate-brand.ts replaces the three icon generators and
  writes build/brand/ (ICO, macOS inset icon, tray bitmaps, mark and the
  brand fields). The WorkDSH outputs are byte-identical to the icons
  previously committed under build/.
- Packaging scripts read the generated brand, append electron-builder
  overrides only where it differs from WorkDSH, and verifiers look for
  artifacts under the brand's file name. afterPack checks that the brand
  file, window icon and unpacked mark are packaged.
- The carrier takes its window title, icon, app name and pinned userData
  folder from the brand and passes WORKDSH_BRAND_NAME/WORKDSH_BRAND_MARK
  to the runtime; installer messages use SHORTCUT_NAME.
- workdsh-bundle serves the brand at /api/workdsh-brand for the sidebar
  slots and page title; Office exports use it as creator; other panels
  use neutral wording.
- CI accepts a brand input on manual runs; the Ubuntu smoke derives
  paths from the package. Docs: docs/white-label and an Agent Note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…n tests

The brand tests hard-coded POSIX paths, so Windows resolved '/repo' to
'D:\repo' and joined the mark path with backslashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…ideo

Desktop installers now carry static FFmpeg and FFprobe (Shaka Project
static-ffmpeg-binaries n8.1.2-1, GPLv3) in workdsh-runtime/media, pinned
by SHA-256 per target: msvcrt-linked Windows build with no import newer
than Windows 7, fully static Linux x64/arm64 builds, and macOS 15.0 builds.

- prepare-workdsh-media.ts stages the build after the primary runtime,
  requires the expected encoders, and writes manifest.json, COPYING.GPLv3
  and SOURCES.md with every upstream source.
- The carrier passes WORKDSH_MEDIA_TOOLS; the Office plugin registers the
  media-ffmpeg skill (inspect, convert, compress, lossless trim, join,
  extract audio) with the executables' absolute paths, falling back to
  WORKDSH_FFMPEG/WORKDSH_FFPROBE or PATH. Commands run through DSH's
  command tool under the session's approval and sandbox policy.
- Linux, macOS and Windows 7 audits require the binaries; smoke-media.mjs
  cuts, converts and compresses a clip in the Ubuntu, macOS and Windows
  packaged-runtime smokes.
- Notices, user guide, Office README/CHANGELOG and an Agent Note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
extraResources copies only whitelisted workdsh-runtime directories, so
media/ was staged but left out of every package and the packaged-runtime
smoke could not find media/manifest.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
@electron/asar resolves extractFile paths with the host separator, so the
afterPack brand check could not find build/brand/brand.json on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…cans

The package-audit cases write several fresh .exe fixtures, now including
the FFmpeg executables. On Windows runners Defender scans each one, and the
first case exceeded Vitest's 5-second default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
…idle-exit bound

The release installer's pnpm adds were killed after 90 seconds to end a
finished pnpm that keeps an idle handle. On the macOS Intel runner, with
a slow registry, the Office plugin's install (1007 packages) was still
linking at 90 seconds, so the bound cut off a genuine install. Use the
five minutes the Windows path already allows; the post-timeout manifest
checks are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW3nu8eSrBPpqbAPc42TAs
@airzope airzope changed the title Windows 7 x64 offline installer (VxKex NEXT) and Ubuntu 20.04+ x64/arm64 packages Win7 x64, Ubuntu 20.04+ and macOS 15 packages; document conversion/OCR, white-label, bundled FFmpeg Sep 29, 2026
@airzope
airzope marked this pull request as ready for review September 29, 2026 07:07
@airzope
airzope merged commit 773585a into main Sep 29, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants