dsh-cait 1.0.4 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  <p align="center">
17
17
  <a href="https://www.npmjs.com/package/dsh-cait"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-cait.svg" /></a>
18
18
  <img alt="DSH 0.2.x" src="https://img.shields.io/badge/DSH-0.2.x-4d6bfe.svg" />
19
- <img alt="Tests: 13 suites" src="https://img.shields.io/badge/tests-13%20suites-brightgreen.svg" />
19
+ <img alt="Tests: 29 suites" src="https://img.shields.io/badge/tests-29%20suites-brightgreen.svg" />
20
20
  <img alt="No API key required" src="https://img.shields.io/badge/API%20key-not%20required-6b7280.svg" />
21
21
  </p>
22
22
 
@@ -34,10 +34,10 @@ translated document.
34
34
  | | |
35
35
  |---|---|
36
36
  | **Native to DSH** | A real sidebar panel, a main workbench, DSH theme tokens, and the same store for humans and agents. No iframe, no separate app. |
37
- | **TM that explains itself** | Multiple TM libraries, mounted-only lookup, exact / near-exact / high / medium / low fuzzy grades, and automatic write-back on confirm. |
37
+ | **TM that explains itself** | Multiple TM libraries, mounted-only lookup, 101% context (ICE) matches, exact / near-exact / high / medium / low fuzzy grades, and automatic write-back on confirm. |
38
38
  | **Glossary-aware editing** | Multiple term bases, source-language filtering, inline highlighting, click-to-insert terms, and per-term case sensitivity. |
39
39
  | **A document workflow** | Tabs, close/reopen, recent-document cleanup, duplicate-import reuse, and progress per document. |
40
- | **Real format coverage** | TXT, Markdown, DOCX, TMX, CSV, SRT/VTT, PO, XLIFF 1.2/2.0/SDLXLIFF, HTML, JSON, XLSX, PPTX, and RTF. |
40
+ | **Real format coverage** | TXT, Markdown, DOCX, EPUB, TMX, CSV, SRT/VTT, PO, XLIFF 1.2/2.0/SDLXLIFF, HTML, JSON, XLSX, PPTX, and RTF. |
41
41
  | **Agent-ready** | Seven tools share the open document and store, so an agent can translate alongside you. |
42
42
 
43
43
  ## Quick start
@@ -60,6 +60,10 @@ manual reload.
60
60
  ### Translation memory
61
61
 
62
62
  - Multiple TM libraries with id, name, mount state, and a default write library.
63
+ - **Context match (ICE) at 101%.** Each confirmation records the two neighbouring
64
+ source sentences. A later segment with the same neighbours scores 101% and is
65
+ graded `context`; identical text with different neighbours stays at 100%. A key
66
+ keeps up to 8 context variants and always keeps the context-free one.
63
67
  - Exact, near-exact, and three fuzzy bands:
64
68
  - `near_exact` compares a key that ignores digits, punctuation, and whitespace;
65
69
  it does not depend on a score cutoff.
@@ -74,7 +78,8 @@ manual reload.
74
78
  `bootstrap().tm.count` is the mounted count and `bootstrap().tm.total` is the
75
79
  all-library count. Use `cat_lookup_tm` or the library modal for full data.
76
80
  - TMX 1.4 `<tu>/<tuv>/<seg>` import/export. Inline TMX placeholders are flattened
77
- to plain text with an explicit warning.
81
+ to plain text with an explicit warning. Context travels as
82
+ `<prop type="x-context">`, so a CAIT round-trip keeps 101% matches.
78
83
 
79
84
  ### Glossary
80
85
 
@@ -83,11 +88,71 @@ manual reload.
83
88
  - CSV/TSV import, per-term notes, source-language filtering, and a
84
89
  `caseSensitive` flag honored by both the workbench and `cat_lookup_glossary`.
85
90
  - Language codes are canonicalized (`EN` → `en`, `ZH_cn` → `zh-CN`).
91
+ - Entries can be edited or deleted in any library, mounted or not; mount state
92
+ only decides what the workbench searches and writes.
93
+ - **Terminology mining**: *Mine terms from the document* in the glossary toolbar
94
+ lists candidates with occurrence counts, sample wording from memory, and a
95
+ marker when the term is already known. Counting finds the candidates and ranks
96
+ them (Latin n-grams, repeated CJK substrings filtered by boundary entropy);
97
+ a model only judges a shortlist, which is the part models are good at.
98
+
99
+ ### Library workspace
100
+
101
+ `Documents` / `Libraries` / `Align` in the topbar switches between the translator
102
+ and the library manager. The library view needs no open document.
103
+
104
+ - One table for translation memory, one for glossaries, with paging
105
+ (20/50/100/200, remembered), language filters, and a search that can be scoped
106
+ to any combination of libraries.
107
+ - A side panel edits the selected entry in place, adds entries, and shows when a
108
+ draft is unsaved.
109
+ - Translation memory exports to **TMX**; glossaries export to **TBX**, **CSV**, or
110
+ **JSON**. Import and clear stay available in the same toolbar.
111
+ - The right panel's library button opens this workspace with the panel's search
112
+ text already applied, so a lookup in the panel continues in the full list.
113
+
114
+ ### Alignment
115
+
116
+ `Documents` / `Libraries` / `Align` — the third view builds a translation
117
+ memory from two finished files: the source document and its translation, as
118
+ separate files in any supported format and any pair of languages.
119
+
120
+ - Cross-language scoring: shared anchors (numbers, `{0}` placeholders, URLs,
121
+ capitalised names), length normalised per language, and paragraph structure.
122
+ Word overlap is deliberately not used, because it cannot compare two languages.
123
+ - Blocked dynamic programming pairs 1:1, 1:0, 0:1, 2:1 and 1:2; rows are graded
124
+ high / to review / doubtful and start selected only when they are high.
125
+ - Each row can be merged with the next, split on line breaks, or removed before
126
+ writing; the target library is chosen in the toolbar, and identical entries are
127
+ skipped rather than duplicated.
86
128
 
87
129
  ### Workbench
88
130
 
89
131
  - Paragraph/sentence segmentation with a per-segment target editor.
90
- - Draft saving, confirm-and-next, previous/next navigation, and progress.
132
+ - Segment states: **pending** → **translated** → **confirmed**, with the origin of
133
+ each translation (`tm`, `mt`, `agent`, `manual`) kept alongside the text. The
134
+ rail filters by state and search covers source, target, and suggestions.
135
+ - **Segment paging**: the rail pages through the filtered segments with a page
136
+ size of 20/50/100/200 and a box to jump straight to a segment number. Jumping
137
+ clears the filter when the target segment would otherwise be hidden.
138
+ - **Pre-translate** fills the whole document from exact TM matches and machine
139
+ translation in small blocks, shows `done/total`, and can be stopped between
140
+ blocks. Confirmed and already-translated segments are never overwritten.
141
+ - **Stacked review**: source, the machine/agent baseline, and the editable target
142
+ are laid out top to bottom, so each block gets the full pane width.
143
+ **Confirm all** accepts every segment awaiting review after one confirmation
144
+ dialog.
145
+ - Draft saving, confirm-and-next, previous/next navigation, and progress. The
146
+ selected segment and the draft are persisted (debounced) so a restart resumes
147
+ where you left off.
148
+ - **Repeated segments are mirrored**: confirming a sentence fills every other
149
+ unconfirmed copy with the same source (`origin: auto`), editing a draft keeps
150
+ them in sync, and *Fill repeated segments* does the whole document at once.
151
+ Confirmed segments are never touched.
152
+ - Advisory QA markers in the rail and an export-time summary: missing
153
+ placeholders/tags, mismatched numbers, unused glossary terms, empty targets,
154
+ an untouched copy of the source, and one source with several translations.
155
+ Nothing is blocked and nothing is stored.
91
156
  - Document tabs; closing a tab does not delete the document.
92
157
  - **Open existing document** reopens a closed document.
93
158
  - Interface language switch in **Settings → Interface**: *Follow DSH language*
@@ -100,9 +165,25 @@ manual reload.
100
165
  - Re-importing identical content in the same format reuses the existing document
101
166
  instead of creating a duplicate. The fingerprint covers languages, source,
102
167
  format, and exchange metadata.
103
- - Responsive density: the workbench measures its DSH panel and applies a
104
- `--cait-u` multiplier of 1×–1.8×. A 1600×900 panel renders at ~1.32× and a
105
- 2560×1440 panel at 1.8×; short windows stay at 1× rather than shrinking.
168
+ - Responsive density: the workbench measures its DSH panel and applies a damped
169
+ `--cait-u` multiplier of 1×–1.45×. A 1600×900 panel renders at ~1.17× and a
170
+ maximized 4K panel stops at 1.45×, which keeps large windows close to the host
171
+ UI and leaves room for the three review columns.
172
+ - The workbench follows the host light/dark theme, including native controls
173
+ (`color-scheme`), so selects, checkboxes, and scrollbars match the panel.
174
+
175
+ ### Preprocessing
176
+
177
+ Imported source text passes through a preprocessing stage before segmentation:
178
+
179
+ - Collapse repeated spaces and tabs, trim indentation, and merge consecutive
180
+ blank lines.
181
+ - Remove zero-width characters and stray control characters.
182
+ - Placeholder tokens (`{1}`, `{2}`, …), punctuation, casing, and paragraph order
183
+ are left untouched, so XLIFF/HTML/EPUB inline markup still round-trips.
184
+ - The three steps are independently switchable in **Settings → Preprocessing** and
185
+ are persisted with the other settings. They apply to new imports and
186
+ `createDocument` calls; existing documents are not rewritten.
106
187
 
107
188
  ### MT assistance
108
189
 
@@ -125,15 +206,16 @@ provider/model/code/status; the client receives only `MT_PROVIDER_FAILED`.
125
206
  | Format | Import | Export | Notes |
126
207
  | --- | :---: | :---: | --- |
127
208
  | TXT / Markdown | ✅ | ✅ | Paragraph and sentence segmentation |
128
- | CSV | ✅ | ✅ | Optional source/target column by header name or 1-based number; existing bilingual export |
209
+ | CSV | ✅ | ✅ | Comma, semicolon, tab, or pipe delimiter auto-detected; source/target column by header name or 1-based number; existing bilingual export |
129
210
  | DOCX | ✅ | ✅ | Body paragraphs; table blocks are excluded from import. Export patches the original package, keeping styles, numbering, images, headers, tables, and layout. |
130
- | TMX 1.4 | ✅ | ✅ | Common `<tu>/<tuv>/<seg>` subset; inline markup flattened with warning |
211
+ | EPUB | ✅ | ✅ | EPUB 3 spine order; XHTML text blocks with inline markup kept as tokens and patched back into the retained package. DRM-protected, fixed-layout, and scripted EPUBs are not supported. |
212
+ | TMX 1.4 | ✅ | ✅ | Common `<tu>/<tuv>/<seg>` subset; inline markup flattened with warning; context kept in `<prop type="x-context">` |
131
213
  | SRT / WebVTT | ✅ | ✅ | One cue per segment, timings/settings/identifier retained; semantic tags kept; invalid ranges rejected |
132
214
  | PO | ✅ | ✅ | Contexts, plural forms, translator comments, obsolete `#~` entries |
133
215
  | XLIFF 1.2 | ✅ | ✅ | Inline tags become `{n}` tokens; missing tokens block confirmation |
134
216
  | XLIFF 2.0 | ✅ | ✅ | Basic `<unit><segment><source>/<target>` subset |
135
217
  | SDLXLIFF | ✅ | ✅ | Basic XLIFF 1.2 path; SDL-specific extensions are not round-tripped |
136
- | HTML | ✅ | ✅ | Text blocks only; original markup/CSS not preserved |
218
+ | HTML | ✅ | ✅ | Text blocks and inline tags preserved; document CSS/layout is not rebuilt |
137
219
  | JSON | ✅ | ✅ | String-path subset; object/array structure preserved via a template; keys and numbers are not translated |
138
220
  | XLSX | ✅ | ✅ | First worksheet; `Source`/`Target` headers or columns A/B; export is a new two-column workbook |
139
221
  | PPTX | ✅ | ✅* | Source-preserving export; requires the imported `.pptx` package. Body text only; notes/charts/SmartArt not imported. |
@@ -143,8 +225,28 @@ provider/model/code/status; the client receives only `MT_PROVIDER_FAILED`.
143
225
  is missing rather than silently producing an unformatted deck.
144
226
 
145
227
  Exchange metadata (subtitle timings, PO contexts/plurals/comments, XLIFF ids and
146
- inline token maps, JSON paths/templates, XLSX rows, PPTX slide/paragraph positions)
147
- is stored on the document/segments and persists in the snapshot.
228
+ inline token maps, JSON paths/templates, XLSX rows, PPTX slide/paragraph positions,
229
+ EPUB spine hrefs and block indexes) is stored on the document/segments and persists
230
+ in the snapshot.
231
+
232
+ ### PDF is not supported
233
+
234
+ CAIT does not import PDF, and future releases will not add PDF support. PDF is a
235
+ fixed-layout print format: it has no logical paragraphs, reading order, or inline
236
+ markup. Text extracted from it is fragmented across drawing operations, loses
237
+ headings, tables, and inline emphasis, and produces segments that are poor input
238
+ for translation memory and MT — in other words, PDF is extremely unsuitable for
239
+ AI-related work.
240
+
241
+ To translate PDF content, convert it to a supported format first, for example:
242
+
243
+ ```sh
244
+ pandoc input.pdf -t docx -o output.docx # or -t html, -t markdown
245
+ ```
246
+
247
+ Adobe Acrobat's **Export to Word/HTML**, LibreOffice, or any other converter that
248
+ produces DOCX, HTML, EPUB, or plain text works too. Scanned PDFs need OCR before
249
+ conversion; CAIT has no image OCR stage.
148
250
 
149
251
  ## Install
150
252
 
@@ -161,7 +263,7 @@ In DSH Desktop (or any profile with the `plugin_manager` tool):
161
263
  plugin_manager install_bundle target: dsh-cait
162
264
  ```
163
265
 
164
- Pin a release with `dsh-cait@1.0.4`, or ask for the newest one with
266
+ Pin a release with `dsh-cait@1.1.3`, or ask for the newest one with
165
267
  `dsh-cait@latest`. The manager resolves the registry package, applies the bundle
166
268
  patch, and activates the plugin — no hand-written profile rows.
167
269
 
@@ -229,7 +331,7 @@ not both.
229
331
  ```
230
332
 
231
333
  The snapshot stores documents, open tabs, TM, glossary, libraries, mounts, and
232
- non-secret settings. Imported DOCX/PPTX source packages live in `sources/`.
334
+ non-secret settings. Imported DOCX/PPTX/EPUB source packages live in `sources/`.
233
335
 
234
336
  In-app settings (**Settings**) live in the snapshot rather than in the YAML
235
337
  above: source/target language, fuzzy threshold, TM result limit, MT
@@ -242,8 +344,9 @@ confirmation. Other structural edits remain best-effort and surface
242
344
 
243
345
  If the snapshot is corrupt or has an unknown version, CAIT logs a warning, moves
244
346
  it to `store.json.corrupt-<timestamp>`, and starts empty instead of failing
245
- activation. Version-1 snapshots are migrated to version 2 with default TM and
246
- glossary libraries.
347
+ activation. Version-1 and version-2 snapshots are migrated to version 3 with
348
+ default TM and glossary libraries; a version-2 draft that had text but was never
349
+ confirmed becomes `translated` with `origin: manual`.
247
350
 
248
351
  ## Agent tools
249
352
 
@@ -256,6 +359,20 @@ glossary libraries.
256
359
  | `cat_list_documents` | List documents and progress |
257
360
  | `cat_switch_document` | Select the active document |
258
361
  | `cat_suggest_mt` | MT via the selected DSH route, or the explicit offline fallback |
362
+ | `cat_pre_translate` | Fill one block from TM + MT, skipping confirmed/translated segments; returns `next` |
363
+ | `cat_get_segments` | Bounded segment window with status, origin, and suggestions |
364
+ | `cat_confirm_segments` | Confirm a list of indices, a window, or everything awaiting review |
365
+ | `cat_propose_translation` | Leave a suggestion plus a reason without touching the confirmed target |
366
+ | `cat_align` | Align two texts and report high / to-review / doubtful pairs |
367
+ | `cat_consistency_report` | Group repeated sources that carry different translations |
368
+ | `cat_term_candidates` | Mining shortlist: frequency, sample sentences, existing memory wording |
369
+ | `cat_add_terms` | Add accepted terminology to a library in one batch |
370
+
371
+ An agent can therefore draft a whole document without clicking in the UI:
372
+ `cat_pre_translate` with `from: next` until `next` is `null`, then
373
+ `cat_get_segments` to review, then `cat_confirm_segments` to accept. For
374
+ terminology it reads `cat_term_candidates`, judges the shortlist, and writes the
375
+ result with `cat_add_terms`.
259
376
 
260
377
  The workbench and tools share one `CatStore`, so an agent can translate the same
261
378
  document the user has open.
@@ -266,7 +383,7 @@ document the user has open.
266
383
  flowchart LR
267
384
  UI["DSH Web UI<br/>(sidebar + workbench)"] --> Client["client.js<br/>generated Web bundle"]
268
385
  Client --> API["/cait/api/rpc<br/>same-origin JSON"]
269
- Tools["7 agent tools"] --> Store["CatStore"]
386
+ Tools["15 agent tools"] --> Store["CatStore"]
270
387
  API --> Store
271
388
  Store --> Snapshot[("store.json<br/>+ sources/")]
272
389
  ```
@@ -301,11 +418,18 @@ cait/
301
418
  │ ├─ errors.js
302
419
  │ ├─ store-utils.js
303
420
  │ ├─ libraries.js # TM/glossary registries + mounts
421
+ │ ├─ library-view.js # Library paging/search + export entry points
422
+ │ ├─ library-export.js # Glossary TBX / CSV / JSON builders
304
423
  │ ├─ tm.js
305
424
  │ ├─ glossary.js
306
425
  │ ├─ persistence.js
307
426
  │ ├─ import-export.js
308
427
  │ ├─ formats.js # CSV/SRT/VTT/PO/XLIFF/HTML/JSON/RTF
428
+ │ ├─ html.js # Shared HTML/XHTML run scanner + patcher
429
+ │ ├─ epub.js # EPUB package read / spine import / patch export
430
+ │ ├─ preprocess.js # Import-time source cleaning stage
431
+ │ ├─ pre-translate.js # Block pre-translation methods
432
+ │ ├─ qa.js # Derived QA report (never persisted)
309
433
  │ ├─ xlsx.js
310
434
  │ ├─ pptx.js
311
435
  │ ├─ segmenter.js
@@ -334,6 +458,8 @@ node --check client.js
334
458
  node _dev/test-core.mjs
335
459
  node _dev/test-imports.mjs
336
460
  node _dev/test-formats.mjs
461
+ node _dev/test-epub.mjs
462
+ node _dev/test-preprocess.mjs
337
463
  node _dev/test-second-tier.mjs
338
464
  node _dev/test-docx-export.mjs
339
465
  node _dev/test-api.mjs
@@ -344,11 +470,20 @@ node _dev/test-libraries.mjs
344
470
  node _dev/test-mounts.mjs
345
471
  node _dev/test-ui-scale.mjs
346
472
  node _dev/test-mt.mjs
473
+ node _dev/test-mt-routes.mjs
474
+ node _dev/test-three-state.mjs
475
+ node _dev/test-pretranslate.mjs
476
+ node _dev/test-qa.mjs
477
+ node _dev/test-library-crud.mjs
478
+ node _dev/test-library-view.mjs
479
+ node _dev/test-pagination.mjs
480
+ node _dev/test-theme-tokens.mjs
481
+ node _dev/test-e2e-1.1.mjs
347
482
  ```
348
483
 
349
484
  The import/export fixtures are `_dev/sample.docx`, `_dev/sample-table.docx`, and
350
485
  `_dev/sample-format.docx`; regenerate them with the matching
351
- `python _dev/make-*.py` scripts. All 13 suites should pass.
486
+ `python _dev/make-*.py` scripts. All 29 suites should pass.
352
487
 
353
488
  ### Releasing
354
489
 
@@ -392,7 +527,10 @@ GitHub with a release.
392
527
 
393
528
  ## Known limits and roadmap
394
529
 
395
- - No PDF, EPUB, or image OCR import yet.
530
+ - No PDF import; PDF is intentionally out of scope (see
531
+ [PDF is not supported](#pdf-is-not-supported)). No image OCR yet.
532
+ - EPUB import follows the spine and body XHTML text blocks; DRM-protected,
533
+ fixed-layout, scripted, and MathML-heavy books are not supported.
396
534
  - DOCX import skips tables, headers, footnotes, fields, alt text, and tracked
397
535
  deletions. DOCX export leaves those regions in the source language.
398
536
  - Mixed-run DOCX/PPTX paragraphs inherit the first run's formatting.
@@ -402,23 +540,34 @@ GitHub with a release.
402
540
  - HTML/RTF export does not round-trip original styling; JSON translates string
403
541
  values only.
404
542
  - TM matching is lexical, not semantic; no stemming, synonyms, or embeddings.
405
- - Library rename/delete and per-tab mount state are not part of v1.0.0.
543
+ - One translation per source text per context: a repeated sentence keeps a
544
+ separate variant for each surrounding pair, capped at 8 variants per key, and
545
+ reuses the generic entry when the neighbours differ.
546
+ - Context is the two neighbouring source sentences only; document, customer, or
547
+ project metadata is not part of the match.
548
+ - TBX and JSON glossary exports are one-way; only TMX and CSV import back.
406
549
  - The workbench UI ships in Chinese, English, and Japanese, switchable in
407
550
  Settings; this README ships in English, Simplified Chinese, and Japanese, and
408
551
  the English version is the source of truth.
409
552
 
410
- Planned next: PDF and EPUB adapters, image/vision input through a multimodal DSH
411
- route, richer library management, style-preserving XLSX output, and XLIFF
412
- `<alt-trans>` / notes support.
553
+ Planned next: image/vision input through a multimodal DSH route,
554
+ style-preserving XLSX output, and XLIFF `<alt-trans>` / notes support.
413
555
 
414
556
  ## Changelog and versioning
415
557
 
416
558
  See [CHANGELOG.md](CHANGELOG.md). `v1.0.0` was the first public release;
417
559
  `v1.0.1` adds the Japanese UI and the in-app interface language switch,
418
560
  `v1.0.2` makes *Follow DSH language* honour the DSH locale, `v1.0.3`
419
- publishes the package to npm, and `v1.0.4` moves later releases to the
420
- provenance-publishing workflow. The project was developed as `0.1.0` and
421
- renumbered for the GitHub release.
561
+ publishes the package to npm, `v1.0.4` moves later releases to the
562
+ provenance-publishing workflow, `v1.0.5` adds EPUB, import preprocessing,
563
+ and the PDF policy, `v1.1.0` adds agent-driven pre-translation, the
564
+ three-state segment model, stacked review, and advisory QA, `v1.1.1` adds
565
+ the library workspace with TMX/TBX/CSV/JSON export, segment paging, and the
566
+ panel-to-library jump, `v1.1.2` adds context-aware memory with 101% (ICE)
567
+ matches, and `v1.1.3` adds two-file alignment, automatic propagation of
568
+ repeated segments, terminology mining, and the proposal primitive agents use.
569
+ The project
570
+ was developed as `0.1.0` and renumbered for the GitHub release.
422
571
 
423
572
  > **License:** Apache License 2.0 — see [LICENSE](LICENSE). Redistributions must
424
573
  > retain the attribution in [NOTICE](NOTICE).