feat(translator-tools): add locale review and glossary workflow

This commit is contained in:
2026-09-02 21:39:02 +02:00
parent 5e962ff0f3
commit 655797c4fe
32 changed files with 2084 additions and 2192 deletions
+6 -8
View File
@@ -1,13 +1,11 @@
# Changelog
## 0.2.0 - 2026-09-02
## Unreleased
- Added composable literal and line transforms with allocation preflights, plus BOM, UTF-8 validity, zero-byte and byte-newline evidence.
- Added paired text/artifact-evidence downloads with source/output hashes and
pipeline provenance; automatic Toolbox handoff remains intentionally disabled
pending the coordinated Portal consumer rollout.
- Added local translator workspace for i18next-like and single-locale JSON review.
- Added language pair selection, glossary storage and fuzzy in-context suggestions.
- Added local-only import/export pipeline with portal handoff integration.
## 0.1.0 - 2026-09-01
## 0.1.0 - 2026-09-02
- Added the initial local-first Text Tools workbench.
- Added Toolbox integration, bounded input handling, offline shell and deterministic release packaging.
- Initial local-first translator review implementation.
+30
View File
@@ -1077,6 +1077,36 @@ Declared licence: Apache-2.0
limitations under the License.
==============================================================================
json5@2.2.3
Declared licence: MIT
==============================================================================
--- LICENSE.md ---
MIT License
Copyright (c) 2012-2018 Aseem Kishore, and [others].
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[others]: https://github.com/json5/json5/contributors
==============================================================================
react@19.2.8
Declared licence: MIT
+18 -17
View File
@@ -1,24 +1,25 @@
# Text Tools
# Translator Tools
Compose, inspect and evidence plain-text transformations locally in the browser.
Translator Tools is a standalone local-first application in the
[add·ideas Toolbox](https://git.add-ideas.de/lotobo/toolbox-portal). Inputs are
parsed and edited in the browser only; no locale strings are uploaded.
Text Tools is a standalone local-first application in the [add·ideas Toolbox](https://git.add-ideas.de/lotobo/toolbox-portal). Inputs are processed in the browser and are not uploaded.
## Quick scope
## Version 0.2 scope
- Import locale files (`.json`, `.js`, `.txt`) in i18next-like or single-locale forms.
- Review authoritative language against one target language at a time.
- Edit source and target strings and copy-source quickly.
- Add translation glossary entries per language pair and receive fuzzy suggestions.
- Add new languages and export a reviewer-updated translation bundle locally.
- Send exports through the same-tool transfer channel to the Portal.
- Ordered pipelines for line endings, trimming, whitespace, stable sorting, deduplication, literal replacement, line prefix/suffix/filter/number/join and line-order reversal
- Locale-aware case conversion, Unicode NFC/NFD/NFKC/NFKD and best-effort Latin transliteration
- JSON/HTML/URL/Base64/hex escaping plus strict inverse decode/unescape stages; binary decoders accept canonical encodings and require valid UTF-8 text
- Bounded RFC-style quoted CSV column selection across embedded delimiters and newlines, alongside the retained literal multi-character delimiter-per-line mode
- Explicit UTF-8, UTF-16LE and Latin-1 file decoding plus BOM, malformed UTF-8 offset, zero-byte parity, byte-level newline and replacement-character evidence
- Versioned JSON recipe import/export, per-step size/change reports, and a paired text-plus-JSON artifact download with source/output SHA-256 and transformation provenance
## Notes
Pipelines are limited to 2,000,000 UTF-16 input units and an 8×/32 MiB output expansion. File input is limited to 16 MiB before decoding. Encoding is selected explicitly rather than guessed; compatibility normalisation, transliteration, narrow encodings and several transforms can be lossy, so source, result, and warnings remain visible. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) and [docs/PRIVACY-SECURITY.md](docs/PRIVACY-SECURITY.md).
The artifact evidence is a portable download contract, not an automatic Toolbox
handoff. SDK 0.3.0 provides the shared transfer contract, but automatic Open With
remains disabled in this release until the Portal consumer rollout is
coordinated. Local downloads stay explicit and portable in the meantime.
- The parser accepts JavaScript-style locale assignment forms such as
`const de = { ... }` and tolerant spacing/commas.
- Parsing and transfers are bounded to 5 MiB per imported/exported transfer file.
- Language detection relies on file name hints (`de_*.json`) and explicit user
selection.
## Development
@@ -32,7 +33,7 @@ npm run test:browser
## Release
`npm run release:artifact` creates a deterministic `release/text-tools-0.2.0.zip` and checksum sidecar.
`npm run release:artifact` creates a deterministic `release/translator-tools-0.1.0.zip` and checksum sidecar.
## Licence
+1 -1
View File
@@ -1,6 +1,6 @@
# Third-party notices
Text Tools 0.2.0 directly depends on these runtime packages:
Translator Tools 0.1.0 directly depends on these runtime packages:
| Package | Pinned version | Declared licence |
| -------------------------------- | -------------: | ---------------- |
+11 -4
View File
@@ -1,9 +1,16 @@
# Architecture
Text Tools is a static React/Vite application wrapped in the shared Toolbox shell. `text/pipeline.ts` defines an ordered, typed list of transformations. `applyPipeline` starts from the exact source, applies enabled steps one at a time, checks expansion after every step, and returns the last successful output with per-step before/after counts and warnings.
Translator Tools is a static React/Vite application wrapped in the shared Toolbox shell.
Text encoding/decoding, line-ending conversion, bounded CSV parsing and Unicode-aware case primitives come from `@add-ideas/toolbox-helpers`. File decoding uses an explicit encoding and fatal-or-replacement choice; it does not guess a charset. Inverse JSON/HTML/URL/Base64/hex stages are strict: malformed syntax and non-UTF-8 byte output fail the step rather than being silently repaired. Column selection offers a quoted CSV mode that preserves embedded delimiters/newlines and a separate literal-delimiter-per-line mode. Recipe JSON carries a schema/app identity, accepts at most 100 supported steps, discards supplied IDs and assigns local monotonic IDs.
The workbench parses a single imported locale file in-browser, normalizes either:
`text/evidence.ts` inspects original bytes before decoding, including BOM, exact UTF-8 validity/first invalid offset, zero-byte parity and CR/LF/CRLF counts. Artifact export emits the selected output bytes and a deterministic evidence document containing canonical-source and exact-output SHA-256 values, inventories, recipe and step reports. The document records that direct Toolbox handoff is unavailable in this release; the SDK 0.3.0 transfer contract is intentionally not activated until the Portal consumer rollout is coordinated.
- i18next-like language maps (`{ "en": {...}, "de": {...} }`)
- single-locale objects (`{ "key": "value" }`, or JS-style assignment forms like `const de = {...}`).
Version 0.2 operations are synchronous and bounded, so the app creates no worker and has no persistence or server API. Relative entry and asset URLs keep the build relocatable below a nested portal path.
Strings are flattened into stable dot paths for review/editing and can be serialized
back with an inverse unflattening step. Suggestions come from local glossary entries
and are matched by language pair and fuzzy string distance.
No background workers are required today. Persistent state is limited to a local
Storage glossary cache; everything else remains in process memory until download or
transfer.
+11 -4
View File
@@ -1,9 +1,16 @@
# Privacy and security
Source text, imported files, recipes and results stay in page memory. There is no telemetry, analytics, account, persistence or runtime network path. Imported text is rendered as text/preformatted content, not executable HTML; HTML escaping produces a string and does not preview it as markup.
Locale files and generated outputs stay in-browser and are not uploaded.
Files are rejected above 16 MiB before reading. Decoded/pasted pipeline input is limited to 2,000,000 UTF-16 units, recipe text to 1,000,000 units/100 steps, and output to both 8× the original (with a small-input floor) and 32 MiB. Quoted CSV selection additionally limits rows, columns and field size. Strict inverse stages reject malformed escapes/encodings and invalid UTF-8; they do not attempt permissive repair. These limits reduce accidental expansion but do not prove that output is safe for a downstream interpreter.
No accounts, telemetry or runtime network requests are used for the core workflow.
The app stores glossary terms in local browser storage so they are available on the same
device for repeated reviews.
Compatibility normalisation, case conversion, transliteration, whitespace/line transforms, column selection and narrow encodings can change or lose information. Locale sorting depends on the browser's `Intl.Collator`. The exact source, output, per-step counts and warnings remain visible so users can review those changes before copying or downloading.
Parser/serializer limits are bounded to prevent accidental expansion:
Byte evidence does not guess an encoding or prove the selected decoder is correct. A valid UTF-8 byte sequence may represent text intended for another encoding, zero-byte parity is only a UTF-16 review signal, and replacement characters may already have existed in the source. Artifact evidence hashes canonical UTF-8 source text and exact exported bytes, clearly labels both, and includes filenames and transformation details that may themselves be sensitive.
- Imports and exports are capped at 5 MiB each.
- Large objects are flattened and rendered with per-session bounds.
Suggested translations are purely local matching; they do not call external services.
Transfers to the Portal are signed local handoffs only and never stored by a remote
processor by default.
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Text Tools"><path fill="#5b4ec4" d="M11 4h30l12 12v44H11z"/><path fill="#fff" opacity=".28" d="M41 4v14h12"/><text x="32" y="43" fill="#fff" font-family="system-ui,sans-serif" font-size="18" font-weight="800" text-anchor="middle">TE</text></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Translator Tools"><path fill="#5b4ec4" d="M11 4h30l12 12v44H11z"/><path fill="#fff" opacity=".28" d="M41 4v14h12"/><text x="32" y="43" fill="#fff" font-family="system-ui,sans-serif" font-size="18" font-weight="800" text-anchor="middle">TR</text></svg>

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 335 B

+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "Text Tools",
"short_name": "Text",
"description": "Transform and inspect plain text locally in the browser.",
"name": "Translator Tools",
"short_name": "Translator",
"description": "Review and edit locale strings locally in the browser.",
"start_url": "./",
"scope": "./",
"display": "standalone",
+2 -2
View File
@@ -1,5 +1,5 @@
const CACHE_PREFIX = "text-tools-shell-";
const CACHE_NAME = CACHE_PREFIX + "0.2.0";
const CACHE_PREFIX = "translator-tools-shell-";
const CACHE_NAME = CACHE_PREFIX + "0.1.0";
const CORE = ["./", "./manifest.webmanifest", "./favicon.svg"];
self.addEventListener("install", (event) => {
event.waitUntil(
+23 -26
View File
@@ -1,22 +1,21 @@
{
"$schema": "https://git.add-ideas.de/lotobo/toolbox-sdk/raw/branch/main/schemas/toolbox-app.v1.schema.json",
"schemaVersion": 1,
"id": "de.add-ideas.text-tools",
"name": "Text Tools",
"version": "0.2.0",
"description": "Compose text transforms and export encoding evidence locally.",
"id": "de.add-ideas.translator-tools",
"name": "Translator Tools",
"version": "0.1.0",
"description": "Review and edit translation bundles in the browser with glossary suggestions.",
"entry": "./",
"icon": "./favicon.svg",
"categories": ["text", "developer", "productivity"],
"categories": ["text", "developer", "productivity", "i18n"],
"tags": [
"text",
"unicode",
"pipeline",
"normalize",
"sort",
"escape",
"encoding",
"newline"
"translation",
"i18n",
"locale",
"glossary",
"review",
"json",
"localization"
],
"integration": {
"contextVersion": 1,
@@ -26,32 +25,30 @@
"requirements": {
"secureContext": false,
"workers": false,
"indexedDb": false,
"indexedDb": true,
"crossOriginIsolated": false,
"topLevelContext": false
},
"io": {
"accepts": [
{
"mediaType": "text/*",
"extensions": [".txt", ".csv", ".md", ".log"],
"label": "Bounded text files"
"mediaType": "application/json",
"extensions": [".json", ".js"],
"label": "Locale JSON or i18next-like translation files"
}
],
"produces": [
{
"mediaType": "text/plain",
"extensions": [".txt"],
"label": "Transformed text"
},
{
"mediaType": "application/json",
"extensions": [".json"],
"label": "Recipe and artifact evidence"
"label": "Reviewed translation bundle"
}
]
},
"capabilities": { "required": [], "optional": ["web-crypto"] },
"capabilities": {
"required": [],
"optional": ["indexeddb", "local-artifact-handoff"]
},
"privacy": {
"processing": "local",
"fileUploads": true,
@@ -59,14 +56,14 @@
"label": "Inputs stay in this browser; nothing is uploaded."
},
"source": {
"repository": "https://git.add-ideas.de/lotobo/text-tools",
"repository": "https://git.add-ideas.de/lotobo/translator-tools",
"license": "GPL-3.0-or-later"
},
"actions": [
{
"id": "source",
"label": "Source",
"url": "https://git.add-ideas.de/lotobo/text-tools"
"url": "https://git.add-ideas.de/lotobo/translator-tools"
}
]
}