Skip to content

Commit 1427d86

Browse files
authored
Merge pull request #200 from qnbs/release/v1.24.0
release: v1.24.0
2 parents 03ceee9 + 49a7d30 commit 1427d86

8 files changed

Lines changed: 31 additions & 11 deletions

File tree

‎AUDIT.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**Date:** 2026-04-17 (baseline); **follow-up chain:** … → 2026-05-28 (v1.19.0 — Security/Voice/RTL/Logger B-1..B-8) → **2026-05-30 (B-1 passphrase UX + CI unblock)** → **2026-05-31 (i18n audit + settings features + CI stabilization)** → **2026-05-31 (Edge-AI Perfection Cycle — Phases 0-7 complete)** → **2026-06-01 (Post-crash session: CI stabilisation + 14 CodeAnt AI fixes + E2E hardening)** → **2026-06-02 (Perf Phase 2.3 — pipeline-LRU unification + PR #69 CodeAnt fixes)** → **2026-06-03 (WorkerBus v2 Phase 3 — Rust TaskSupervisor + Tauri-build unblock)** → **2026-06-06 (Phase 3 i18n Expansion — ja/zh/pt/el + Intl APIs)** → **2026-06-09 (v1.21 Deep Audit Correction — Whisper WASM download UI + 3 CodeAnt fixes + CloudSync LWW)** → **2026-06-09 (feat/deep-audit-v1.21 — CSP hardening, zh locale ≤5% EN, coverage Batches A/B/C, VoiceActivityCoordinator B-2 bridge)** → **2026-06-11 (Ultimate Copilot v2 Phase 2+3 — markdown, sidebar, Apply-to-chapter, InlineAnnotation, ProForge chip; PR #110+#111)** → **2026-06-11 (v1.22.0 release — OpenRouter Cloud 5 provider, AI Execution Modes hybrid/cloud/local/eco, AiModeIndicator, SW cache-invalidation fix)** → **2026-06-13/14 (v1.23 perfection batch — OpenRouter + AI-Execution-Mode settings sections localized/modernized, i18n single-brace interpolation bug-class fix + `i18nPlaceholders` regression guard, bundle split + budget tightening PR #130)** → **2026-06-16 (v1.23.0 release — rebrand StoryCraft → WorldScript Studio, local-first data foundation ADR-0008, Tauri blank-screen + asset-URL fixes, AI error taxonomy + retry hardening, command-palette & local-AI settings localization, WorldScript W monogram icons)** → **2026-06-16 (post-release documentation perfection pass — corpus sync, metric reconciliation, history archival, dependabot hardening)** → **2026-06-17 (Language expansion — +6 locales fi/sv/hu/is/eu/fa (RTL); PR #174 merged; `LanguageSelector` exonym localization via `portal.language.names.*`; portal chrome 100 % for the 6 new langs; README/AUDIT/CHANGELOG docs sync)**
44
**Scope:** Full application, repository configuration, CI/CD, documentation, release validation
5-
**Current version:** **v1.23.0** — 2026-06-16 (Rebrand StoryCraft → WorldScript Studio; local-first data foundation behind `enableLocalFirstSync` (ADR-0008); Tauri blank-screen + updater asset-URL fixes; AI error taxonomy + retry hardening; OpenRouter reactive cloud-policy; command-palette & local-AI settings localization; WorldScript W monogram icons; **2709 keys × 11 locales**; v1.23 perfection engagement — docs/AUDIT-PERFECTION-PLAN-v1.23.md)
5+
**Current version:** **v1.24.0** — 2026-06-21 (Critical & Immediate hardening sequence: Privacy → Analytics opt-out now gates all DuckDB writes + telemetry (SEC-6); reusable `Badge` + experimental labeling; +101 tests for collab-transport/ProForge/Copilot; voice consent clarity; device-aware Ollama recommendation + one-click pull; dependency/onboarding/docs hygiene; **2786 keys × 17 locales**)
66

77
**Quality gate (2026-06-17 — language expansion +6 locales):** lint ✅ · typecheck ✅ · i18n:check ✅ (**2716 keys × 17 locales** — fi/sv/hu/is/eu + fa RTL) · placeholder guard ✅ (17 bundles) · targeted unit tests ✅ (LanguageSelector 9 · I18nContext 59 · i18nPlaceholders 33). `LanguageSelector` exonym labels localized via `portal.language.names.*` (native endonym stays hardcoded by design). **Bulk translation completed** for all 10 Beta locales (glossary v2.0, ~44 anchor terms/locale; placeholder-masked, checkpointed): post-run coverage fi 91 % · sv 90 % · hu 91 % · is 92 % · eu 92 % · fa 93 % · ja 99 % · zh 100 % · pt 98 % · el 97 % (Beta MT; human native review tracked). Two bulk-script bugs fixed: (1) `glossaryTranslate` partial-match left ~1,300 strings partially English → now exact-match only; (2) `--all` mangled `help.json` rich HTML → `help.json` excluded from `--all` (`ALL_SKIP`) and kept English fallback for the 6 new langs (tag-dense markup isn't MT-safe; human-review task). New `docs/TRANSLATION-GUIDE.md` + `I18N-GLOSSARY.md` v2.0.
88

‎CHANGELOG.md‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,46 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [1.23.1] — 2026-06-17
8+
## [Unreleased]
99

10-
### Fixed
10+
## [1.24.0] — 2026-06-21
1111

12-
- **Tauri desktop app stuck on "WorldScript Studio ist offline."**: the PWA Service Worker was registering inside the Tauri WebView (WebView2 supports SWs) and hijacking the root navigation. When its versioned caches were empty (precache fails under the `tauri.localhost` custom protocol while a version bump had already pruned the previous caches), the SW's network-first navigation strategy fell through to the hardcoded inline offline fallback (`public/sw.js`), rendering a bare "<APP> ist offline." page instead of the app. A Service Worker has no place in Tauri — the desktop app is already served locally and offline-first. Two-layer fix: (1) `register-sw.ts` now detects the Tauri runtime and never registers, additionally unregistering any SW + deleting `worldscript-*` caches so already-broken installs self-heal; (2) `public/sw.js` detects the Tauri origin (`tauri://` / `tauri.localhost`) and becomes a no-op — it precaches nothing, never intercepts `fetch`, and self-unregisters on `activate`. The browser PWA path is unchanged.
12+
> **Critical & Immediate hardening sequence** — six stacked PRs (privacy, experimental labeling, coverage, voice consent, local-AI, hygiene/docs) plus the 11→17 locale expansion, shipped as a minor release.
1313
14-
## [Unreleased]
14+
### Security
15+
16+
- **Privacy → Analytics is now a real opt-out (SEC-6).** The Settings → Privacy "Analytics" toggle was cosmetic — only the `enableDuckDbAnalytics` flag controlled persistence. A single enforcement point (`app/analyticsGate.ts` `isAnalyticsPersistenceAllowed`) now gates **every** DuckDB write path (project dual-write, codex, cross-project mirror, RAG vector mirror, seed + RAG migrations, and inference telemetry) on **both** the flag **and** the privacy toggle. The gate is re-evaluated at the last synchronous moment before each async write (no opt-out race); migrations abort without writing their done-marker (so re-opt-in retries) and recover from a transient `error` state; a one-time `analyticsGateMigrated` marker preserves existing-install behavior on upgrade. Analytics remain **local-only metadata** (never manuscript prose, never leaves the device). Full DuckDB OPFS/cell encryption stays deferred to v2.0 (`docs/SECURITY-THREAT-MODEL.md`).
17+
- **Voice consent clarity.** Corrected the misleading "all voice processing runs locally" intro (the default STT path is the cloud Web Speech API) and added a per-engine cloud-vs-on-device privacy note beside the STT engine selector (`settings.voice.engine.privacyNote`, 17 locales).
1518

1619
### Added
1720

21+
- **Device-aware Ollama recommendation + one-click pull.** `pullOllamaModel` streams `POST /api/pull` progress with cancel + error-retry (surfaces Ollama's in-band `{error}` lines, propagates AbortError for cancel, releases the reader on every path); `getOllamaModelForDevice` picks a tiered model (qwen2.5:7b / llama3.2:3b / llama3.2:1b) from the device profile and steps down a size on low battery; new `OllamaDevicePull` settings UI with a recommendation chip + progress/cancel/retry.
22+
- **Reusable `Badge` design-system atom** (variant `experimental | beta | new | neutral`, theme-token driven, accessible) with a Storybook story; applied as maturity badges (driven by `FEATURE_CATALOG`) in the Experimental flags list and an "Experimental" badge in the ProForge dashboard header. New "Limitations, Token Cost & Loop Risks" section in `docs/PROFORGE-PIPELINE.md`.
23+
- **Test coverage for newer subsystems (+101 tests):** collab-transport E2E crypto (the vendored y-webrtc C-1 fork), the ProForge Core Capability Layer + adapters (`proForgeCapabilityCore`, schemas, `agentRegistry`, `nodeInferenceGateway`, `browserProForgeCapability`), and the 5 previously-untested Copilot components (`CopilotPanel`, `CopilotLauncher`, `InlineAnnotationLayer`, `InsightSection`, `HeuristicsModeToggle`).
1824
- **Language expansion — 6 new locales (11 → 17):** Finnish (`fi`), Swedish (`sv`), Hungarian (`hu`), Icelandic (`is`), Basque (`eu`) and Persian/Farsi (`fa`, **RTL**, Arabic script). All ship as Beta. The high-traffic chrome (`portal`, `sidebar`, `dashboard`, top `common.*` verbs) plus native cold-start strings (`i18nBootstrap`) and glossary blocks are hand-translated; the remaining modules were then completed via the glossary-anchored bulk translator (see the bulk-translation entry below). `fa` direction/fonts are automatic via `RTL_LOCALES` + the existing `[dir="rtl"]` Noto Arabic swap — no App/CSS/font changes. New guide: [`docs/LANGUAGE-EXPANSION-2026.md`](docs/LANGUAGE-EXPANSION-2026.md).
1925
- **Bulk-translate hardening (`scripts/bulk-translate-locales.mjs`):** placeholder masking (`{{token}}` → sentinel → restore, so MT can't mangle interpolation) and a `--dry-run` mode (per-file key + glossary-hit counts, no network calls, no writes). The 6 new languages are added to `SUPPORTED_LANGS`, `check-i18n-keys.mjs`, and `build-i18n.mjs`. The `i18nPlaceholders` guard now covers all 17 locale bundles.
2026
- **Localized language picker:** `LanguageSelector` now resolves each language's exonym label (e.g. "Finnish", "Swedish") through `t('portal.language.names.<code>')` at render time instead of a hardcoded string — the native endonym (`Suomi`, `Svenska`, …) stays hardcoded by design so users always find their own language regardless of the active UI locale. Adds `portal.language.names.*` (17 names) to all 17 locales, hand-translated for the 5 core + 6 new languages (other Beta locales' exonyms filled by the bulk translator). `portal` chrome is now fully localized for the 6 new languages.
2127
- **Beta-locale bulk translation (10 languages):** ran the glossary-anchored, placeholder-masked `bulk-translate-locales.mjs` pipeline for `fi/sv/hu/is/eu/fa` (full) and topped up `ja/zh/pt/el`, lifting the 6 new locales from ~8 % to **90-93 %** coverage (machine-translated, **Beta** quality, human native review tracked as follow-up). `help.json` (long-form rich HTML) stays English fallback for the new langs and is excluded from `--all` — its tag-dense markup is not safely machine-translatable. Glossary expanded to **v2.0** (~44 anchor terms/locale: + `Co-Pilot`, `ProForge`, `Subplot`, `Timeline`, `Snapshot`, `Synopsis`, `Mind Map`, `Word Count`, `Continue Writing`, `Improve Writing`, `Consistency Checker`, `Plot Hole`, …). Two bulk-script bugs fixed: `glossaryTranslate` partial-match (→ exact-match only) and `--all` mangling `help.json` HTML (→ excluded).
2228
- **New `docs/TRANSLATION-GUIDE.md`:** end-to-end localization guide — architecture/build flow, placeholder/token rules, tone-by-category, RTL guidelines + per-locale verification checklist, glossary usage, native-review checklist, common pitfalls, and the new-language contribution workflow. `docs/I18N-GLOSSARY.md` updated for the v2.0 anchor set.
2329

30+
### Fixed
31+
32+
- **`enableIdbAtRestEncryption` default drift:** `featureCatalog` declared `defaultOn: false`, contradicting the slice (`true`, the source of truth) — reconciled.
33+
- **README metric drift:** `scripts/sync-readme-metrics.mjs` hard-coded the locale count to `11`, so its regexes stopped matching after the 11→17 expansion and silently froze the i18n key count. Locale count is now dynamic and the regexes match any digit count — README reads the live **17 locales / 2786 keys** with the drift guard green.
34+
2435
### Changed
2536

37+
- **Dependency hygiene + onboarding + docs truth-up:** documented the `joi` accepted-risk override (GHSA-q7cg-457f-vx79; still required via `wait-on`) and the SBOM deferral in `AUDIT.md` (`pnpm audit --audit-level=high` clean); corrected the stale `public/sw.js` "must hand-sync `APP_VERSION`" note in `CLAUDE.md`; added a "Do NOT run heavy suites locally" callout + Minimal Change Checklist to `CONTRIBUTING.md` and mirrored the heavy-suite warning into `.github/copilot-instructions.md`.
38+
2639
- **Docs completion (language-expansion pass):** README i18n badge, language list, capability table and metrics line updated to **17 locales / 2716 keys**; Persian added to the RTL-Beta section; `AUDIT.md` follow-up chain + quality-gate entry for 2026-06-17.
2740

41+
42+
## [1.23.1] — 2026-06-17
43+
44+
### Fixed
45+
46+
- **Tauri desktop app stuck on "WorldScript Studio ist offline."**: the PWA Service Worker was registering inside the Tauri WebView (WebView2 supports SWs) and hijacking the root navigation. When its versioned caches were empty (precache fails under the `tauri.localhost` custom protocol while a version bump had already pruned the previous caches), the SW's network-first navigation strategy fell through to the hardcoded inline offline fallback (`public/sw.js`), rendering a bare "<APP> ist offline." page instead of the app. A Service Worker has no place in Tauri — the desktop app is already served locally and offline-first. Two-layer fix: (1) `register-sw.ts` now detects the Tauri runtime and never registers, additionally unregistering any SW + deleting `worldscript-*` caches so already-broken installs self-heal; (2) `public/sw.js` detects the Tauri origin (`tauri://` / `tauri.localhost`) and becomes a no-op — it precaches nothing, never intercepts `fetch`, and self-unregisters on `activate`. The browser PWA path is unchanged.
47+
2848
## [1.23.0] — 2026-06-16
2949

3050
### Changed

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<img src="https://img.shields.io/badge/TypeScript-7.x_(tsgo)-3178C6?logo=typescript&logoColor=white" alt="TypeScript 7 (tsgo)">
1010
<img src="https://img.shields.io/badge/AI-Gemini_%7C_OpenAI_%7C_OpenRouter_%7C_Ollama_%7C_WebLLM-4285F4?logo=google" alt="Gemini · OpenAI · OpenRouter · Ollama · WebLLM">
1111
<img src="https://img.shields.io/badge/Local_AI-WebGPU_%7C_ONNX_%7C_Transformers.js-8B5CF6" alt="WebGPU · ONNX · Transformers.js">
12-
<img src="https://img.shields.io/badge/Version-v1.23.1-6366F1" alt="v1.23.1">
12+
<img src="https://img.shields.io/badge/Version-v1.24.0-6366F1" alt="v1.24.0">
1313
<img src="https://img.shields.io/badge/Storage-IndexedDB_v8-F59E0B" alt="IndexedDB v8">
1414
<img src="https://img.shields.io/badge/PWA-v3.0-5BB974?logo=pwa" alt="PWA v3.0">
1515
<img src="https://img.shields.io/badge/i18n-17_locales-2786_keys-0EA5E9" alt="i18n 17 locales — 2786 keys">

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "worldscript-studio",
33
"private": true,
4-
"version": "1.23.1",
4+
"version": "1.24.0",
55
"description": "WorldScript Studio — offline-first, AI-powered creative writing application.",
66
"author": "QNBS",
77
"keywords": [

‎public/sw.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// offline fallback, push notifications, share target
66
// ============================================================
77

8-
const APP_VERSION = '1.23.1';
8+
const APP_VERSION = '1.24.0';
99
const CACHE_STATIC = `worldscript-static-v${APP_VERSION}`;
1010
const CACHE_DYNAMIC = `worldscript-dynamic-v${APP_VERSION}`;
1111
const CACHE_IMAGES = `worldscript-images-v${APP_VERSION}`;

‎src-tauri/Cargo.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src-tauri/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "worldscript-studio"
3-
version = "1.23.1"
3+
version = "1.24.0"
44
description = "AI-powered creative writing and world-building application"
55
authors = ["QNBS"]
66
license = "MIT"

‎src-tauri/tauri.conf.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
33
"productName": "WorldScript Studio",
4-
"version": "1.23.1",
4+
"version": "1.24.0",
55
"identifier": "com.worldscript.studio",
66
"build": {
77
"frontendDist": "../dist",

0 commit comments

Comments
 (0)