Copyright (C) 2026 Doan Luu Duc Tai This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . TYPESCRIPT BROWSER TOOLCHAIN First-party browser logic/automation use TypeScript. Rust handles crypto, API, backups, deployment. Browsers run generated JavaScript; compile-time types never replace validation of untrusted input. SOURCE LAYOUT crates/chat-server/web/app.ts Interface, session, history, downloads, API validation. crates/chat-server/web/worker.ts One-shot crypto worker; ends after each request. crates/chat-crypto/browser/wasi.ts Restricted WASI host for unchanged Rust/OpenSSL module. crates/chat-crypto/browser/protocol.d.ts Shared API/crypto request/response contracts. No emitted JavaScript; checked in both browser environments. crates/chat-crypto/tests/browser.ts Real WebAssembly compatibility, entropy, capability tests. crates/chat-server/tests/browser.ts Complete browser chat/recovery tests, including GNU LibreJS. crates/chat-server/tests/progress.ts Download progress/failure tests, including GNU LibreJS. tests/browser-support.ts Checked fixture parsing, typed browser-automation helpers. eslint.config.ts/tsconfig.tools.json provide typed lint-tool checks. Private Rust CLIs: src/app and crates/chat-server/src/app. Parser/runtime changes: LINTING.txt. tsconfig.json supplies shared strict checks. Separate browser/worker/test configs use DOM/WebWorker/Node environments, preventing accidental production Node API use. Check strict, unchecked indexed access, exact optional properties, unused declarations/parameters, implicit returns, switch fallthrough, implicit overrides, indexed-property access. Type errors prevent emission. No suppression directives or untyped escape hatches. DEVELOPMENT Development needs Node >=22.18.0/npm. Root package.json/package-lock.json pin TypeScript 7.0.2, Playwright 1.64.1, Node declarations, platform compilers, integrity hashes. ESLint 10.14.0/typescript-eslint 8.72.1 supply typed strict linting. TypeScript 6.0.3 supplies their supported JavaScript API; native TypeScript 7.0.2 alias emits. Both check sources. LINTING.txt explains the advisory-driven minimatch override. No npm application/runtime dependencies. TypeScript/Playwright: Apache License, Version 2.0. Node declarations/ undici-types: Expat License. Installed packages retain original notices; machine SPDX spelling stays unchanged. Build/check all TypeScript, including browser tests: npm run build infra/chat/build-typescript.sh installs locked dev packages without lifecycle scripts, checks browser/worker/test/tool configs, typed ESLint, both compilers, npm advisories; emits JavaScript under var/build/typescript. npm cache: .tools/npm-cache. Git ignores node_modules/generated output. Scripts stay readable/unminified; no bundler needed. cargo stack check runs this build, strict Rust checks, cargo-about generation. cargo stack release builds TypeScript before packaging production artifacts. Recheck after npm run build without reinstalling: npm run check Fetch pinned Playwright browsers once: PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node_modules/.bin/playwright install chromium firefox Build native chat server/WASI module, then run: PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:crypto PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:chat PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:progress CHAT_LIBREJS=1 PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:chat CHAT_LIBREJS=1 PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:progress LibreJS variants need signed Mozilla extension .tools/librejs.xpi; see CHAT-APPLICATION.txt. Complete chat test proves LibreJS active and rejects an unlicensed control. Run chat variants sequentially; they share default port. npm audit checks dev dependencies in npm run check/Cargo check/release; it does not audit Rust, delivered browser code, or containers. cargo-deny remains the separate strict Rust dependency audit. RELEASES, SOURCE, AND LIBREJS Generated app.js/worker.js/wasi.mjs retain public URLs, AGPL headers, recognized @license/@license-end markers. JavaScript license table links each file to complete corresponding TypeScript/Rust source archive. Classic scripts/importScripts preserve LibreJS compatibility. No runtime module loader or third-party browser scripts added. Local native-server tests serve var/build/typescript. Release packages files into bin/chat/web and bin/chat/wasi.mjs; containers serve packaged files. Copy HTML/CSS explicitly; never substitute TypeScript for executable JS. /SOURCE.tar.gz contains TypeScript, shared declarations, every compiler config, npm lock, tests/build scripts, Cargo-vendored dependencies, verified OpenSSL archive. Node/npm/TypeScript are general-purpose development tools pinned and documented here. Exclude installed copies/downloaded browsers. Source exports/releases/backups carry root npm manifests/TypeScript configs. Activation/restored prebuilt images need no destination Node/npm/TypeScript/ Rust. Preserve single private root .env and persistent data. Source archive excludes .env, credentials, runtime DBs, exports, .git, node_modules, build/cache directories. Root .env.example remains public; no extra environment file. Test generated JavaScript after every compiler upgrade. Static types cannot guarantee privacy, security, or LibreJS recognition. Existing runtime/Rust still enforce browser storage restrictions, protocol validation, algorithms.