Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
256 commits
Select commit Hold shift + click to select a range
4fbc80a
feat(cli): apply --glossary to document translation
sjsyrek Aug 3, 2026
4e0ce43
docs: document glossary support for document translation
sjsyrek Aug 3, 2026
1733329
fix(docs): add the required --from to every --glossary example
sjsyrek Aug 3, 2026
a796988
docs(watch): note that --glossary needs --from
sjsyrek Aug 3, 2026
00219e2
fix(voice): fail when a session ends without a translation
sjsyrek Aug 3, 2026
f5b5c53
fix(watch): require --from when --glossary is used
sjsyrek Aug 3, 2026
d15bc89
refactor(cli): display language codes in lowercase everywhere
sjsyrek Aug 3, 2026
fab33e6
test(watch): recover the dropped fsevents add in the filesWatched test
sjsyrek Aug 3, 2026
49f1f6c
fix(languages): source formality from the v3 features matrix
sjsyrek Aug 3, 2026
f6507b3
feat(languages): add --features to show per-language feature support
sjsyrek Aug 3, 2026
ad28fe9
test(languages): cover --features end to end against the mock API
sjsyrek Aug 3, 2026
ac2e9a2
docs(languages): document --features and the formality fix
sjsyrek Aug 3, 2026
f21ab66
refactor(languages): generate the language list from the API
sjsyrek Aug 3, 2026
bdec6ff
fix(languages): let the API decide which language codes exist
sjsyrek Aug 3, 2026
e890645
fix(languages): list languages the API offers but the snapshot predates
sjsyrek Aug 3, 2026
2e35795
docs(languages): document API-as-authority and the 125-language list
sjsyrek Aug 3, 2026
253ccd9
test(languages): stop the regional-variant assertions depending on co…
sjsyrek Aug 3, 2026
c955ca2
docs(changelog): note the ten display names the API differs on
sjsyrek Aug 3, 2026
b69494a
feat(translate): preflight a named glossary against the requested pair
sjsyrek Aug 3, 2026
011ae19
refactor(write): generate the Write target languages from the API
sjsyrek Aug 3, 2026
2211352
feat(translate): pin tag_handling_version to v2 instead of the server…
sjsyrek Aug 3, 2026
7bbd58b
fix(glossary): treat a base-language glossary as covering regional ta…
sjsyrek Aug 3, 2026
5245ee5
fix(translate): honour --tag-handling-version outside text mode
sjsyrek Aug 3, 2026
34b947b
fix(glossary): resolve the source language from config before requiri…
sjsyrek Aug 3, 2026
9dff632
fix(services): key the translation cache on every parameter that chan…
sjsyrek Aug 3, 2026
2b22d12
refactor(types)!: derive the Language union from the generated snapshot
sjsyrek Aug 3, 2026
3ce520b
fix(scripts): guard the language generator against silent bad output
sjsyrek Aug 3, 2026
7798e9b
fix(languages): stop --features claiming knowledge it does not have
sjsyrek Aug 3, 2026
4975634
fix(voice): keep partial transcripts and match echoed languages case-…
sjsyrek Aug 3, 2026
8c699a9
fix(usage): stop reporting API-key usage as the account total
sjsyrek Aug 3, 2026
a7bb044
fix(translate): stop repeating a doomed request and say when a code i…
sjsyrek Aug 3, 2026
cd7005a
fix(write): defer an unknown Write language to the API instead of rej…
sjsyrek Aug 3, 2026
8449319
fix(glossary): dedupe IDs, check coverage in sync, and validate befor…
sjsyrek Aug 3, 2026
110a767
fix(config): normalize language codes and warn about ones the snapsho…
sjsyrek Aug 3, 2026
2e925c3
fix(api): compare glossary pair languages after normalization
sjsyrek Aug 3, 2026
f3e9af9
docs(changelog): record the review fixes and correct claims they inva…
sjsyrek Aug 3, 2026
8c26e1e
fix(languages): list the bundled snapshot in --format json without an…
sjsyrek Aug 3, 2026
66f5e55
docs(comments): describe current behaviour instead of how it got there
sjsyrek Aug 3, 2026
469f8be
fix(package)!: give the ESM entry point resolvable specifiers
sjsyrek Aug 3, 2026
d5e43f1
fix(scripts)!: validate the API response before writing it into TypeS…
sjsyrek Aug 3, 2026
559a89a
fix(cache): retire the translation entries the new key derivation orp…
sjsyrek Aug 3, 2026
a464fd9
fix(translate): extend the doomed-request abort past plain-text batches
sjsyrek Aug 3, 2026
fa5a6c4
fix(voice): keep the salvaged transcripts visible, and match casing i…
sjsyrek Aug 3, 2026
2fe564c
fix(languages): stop --features contradicting its own footer
sjsyrek Aug 3, 2026
fa721dd
fix: five defects the second review pass turned up
sjsyrek Aug 3, 2026
35b273b
fix: report a failed directory run, and accept voice codes in any casing
sjsyrek Aug 3, 2026
586085e
test: restore the guards the relational counts removed
sjsyrek Aug 3, 2026
83f54e7
docs(changelog): repair the Unreleased structure and the claims that …
sjsyrek Aug 3, 2026
af3bf4c
fix(usage): render a null count as unreported instead of throwing
sjsyrek Aug 4, 2026
ca9e6f5
fix(translate): validate languages in one place for every input mode
sjsyrek Aug 4, 2026
0789e10
fix(voice): validate options before resolving --glossary, and check c…
sjsyrek Aug 4, 2026
c4b5b0e
fix(sync): check override glossaries at startup, and validate during …
sjsyrek Aug 4, 2026
0fb522a
test(languages): pin the supportsFormality JSON contract
sjsyrek Aug 4, 2026
8e209fe
docs: correct example output, the language endpoint, and the glossary…
sjsyrek Aug 4, 2026
fa7b4eb
fix(watch): settle the glossary source language in the handler, not t…
sjsyrek Aug 4, 2026
e66f18a
fix(languages,voice): sanitize API-provided strings before printing them
sjsyrek Aug 4, 2026
e0f1854
fix(translate): report a directory run's rejection class in the exit …
sjsyrek Aug 4, 2026
dbebba4
fix(glossary): relax the coverage check on the requested side only
sjsyrek Aug 4, 2026
149cccf
fix(languages): stop inferring a tier, and a role, from a silent resp…
sjsyrek Aug 4, 2026
97e567c
fix(scripts): report a thrown fetch from the language generator as an…
sjsyrek Aug 4, 2026
24da5ec
docs(glossary): record the verified multipart glossary_ids semantics
sjsyrek Aug 4, 2026
c541e1a
fix(glossary): stop documenting flag order as resolving a conflicting…
sjsyrek Aug 4, 2026
193510c
docs(test): correct the nock leak comment's attribution and audit rule
sjsyrek Aug 4, 2026
8071739
docs: correct inaccuracies found in the pre-2.0 audit
sjsyrek Aug 5, 2026
ca19cf1
fix(watch): honour the documented 500ms debounce default and watch.de…
sjsyrek Aug 5, 2026
b627b42
refactor(exit-codes): consolidate on exitCodeForError
sjsyrek Aug 5, 2026
01ec9a3
style: apply prettier to src and tests
sjsyrek Aug 5, 2026
186870a
chore: prune dead .gitignore entries and un-ignore db fixtures
sjsyrek Aug 5, 2026
4c1c916
chore: prune redundant .prettierignore entries
sjsyrek Aug 5, 2026
4a6820e
ci: gate formatting and fail lint on warnings
sjsyrek Aug 5, 2026
1365d36
chore: guard test fixtures in .prettierignore
sjsyrek Aug 5, 2026
9d494fa
fix(test): restore coverage source maps in ts-jest transform
sjsyrek Aug 5, 2026
cf5e4b8
test: cover parsePositiveIntOption bounds and lenient parsing
sjsyrek Aug 5, 2026
52cae80
test: cover _describe and tm command registration
sjsyrek Aug 5, 2026
5c829b2
test(sync): wait on the outcome in the auto-commit watch-cycle test
sjsyrek Aug 5, 2026
a89f10b
test(sync): assert the bounded-integer parser is wired to --concurren…
sjsyrek Aug 5, 2026
fa1387b
style(test): trim comment justification from the watch-cycle flush he…
sjsyrek Aug 5, 2026
a7c78c2
ci: gate on coverage thresholds
sjsyrek Aug 5, 2026
460695b
test(sync): cover the process lock's failure and hand-off branches
sjsyrek Aug 5, 2026
b513f4e
test: file format regression suites with their parsers
sjsyrek Aug 5, 2026
61b1b27
test(usage): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
0ad1bc2
test(auth): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
791997e
test(detect): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
940bd3d
test(no-input): merge the --no-input suites and isolate the config dir
sjsyrek Aug 5, 2026
75c21c6
test(completion): keep the deeper suite and drop the shallow duplicate
sjsyrek Aug 5, 2026
da498eb
test(cache): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
162b9b3
test(config): merge the config suites, keeping the integration file's…
sjsyrek Aug 5, 2026
7468caa
test(languages): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
86ee9e9
test(voice): merge duplicate integration coverage into the E2E suite
sjsyrek Aug 5, 2026
5324d6a
test(glossary): assert the subcommand surface from a table
sjsyrek Aug 5, 2026
a9894f9
test(document): drop the CLI-surface half of the document integration…
sjsyrek Aug 5, 2026
349a89b
test(style-rules): split the CLI surface out and assert it from a table
sjsyrek Aug 5, 2026
6e3c97a
test: move subprocess-only CLI suites from integration to e2e
sjsyrek Aug 5, 2026
543ed84
test(cli): cover the auth stdin path and the watch registration branches
sjsyrek Aug 5, 2026
fb0a09c
docs(examples): renumber examples into their functional groups
sjsyrek Aug 5, 2026
848eeb2
fix(sync): resolve merge conflicts at the locale, not the entry
sjsyrek Aug 5, 2026
44def11
docs(examples): add sync resolve and sync audit examples
sjsyrek Aug 5, 2026
4a7dda3
test(docs): assert the argument surface and subcommand docs coverage …
sjsyrek Aug 5, 2026
3625e71
test(structured-file): drop the CLI-surface half of the integration file
sjsyrek Aug 5, 2026
1e2b91a
test(translate): split CLI flag coverage out of the integration file
sjsyrek Aug 5, 2026
85c26fd
test: name the watch service suite for what it tests
sjsyrek Aug 6, 2026
29aa376
fix(translate): resolve a directory --output for a single target lang…
sjsyrek Aug 6, 2026
440f02c
fix(examples): stop swallowing translate failures in batch processing
sjsyrek Aug 6, 2026
f660a07
test(sync): wait on the outcome in the last two fixed-drain watch tests
sjsyrek Aug 6, 2026
0f51bf5
test(docs): assert the option choice surface centrally
sjsyrek Aug 6, 2026
42d1eb3
test(completion): derive the expected completion vocabulary from _des…
sjsyrek Aug 6, 2026
90efa10
fix(git): separate pathspecs with -- and scope auto-commit to its own…
sjsyrek Aug 6, 2026
72149d7
fix(deps): pin brace-expansion to >=5.0.9 via overrides
sjsyrek Aug 6, 2026
60af011
fix(sync): bound glob brace expansion before it reaches fast-glob
sjsyrek Aug 6, 2026
2f42bf3
fix(sync): enforce .git/.github containment on resolved paths, not ju…
sjsyrek Aug 6, 2026
8533961
fix(sync): stop the stale-backup sweep from writing, and scope it hon…
sjsyrek Aug 6, 2026
1585a43
fix(cache): key translations and write results on the resolved API en…
sjsyrek Aug 6, 2026
1184998
fix(translate): make --no-cache reach the batch path used by structur…
sjsyrek Aug 6, 2026
631d477
fix(api): refuse a batch response that returns the submitted texts re…
sjsyrek Aug 6, 2026
4b3e895
fix(sync): stop one shared result from carrying another key's placeho…
sjsyrek Aug 6, 2026
b9ab98a
fix(sync): bound recursive parser walks and skip the one file, not th…
sjsyrek Aug 6, 2026
4fddedc
test(sync): guard the php-parser stack-overflow skip against regression
sjsyrek Aug 6, 2026
1a99187
fix(sync): restore overwritten targets on interrupt instead of deleti…
sjsyrek Aug 6, 2026
e3aea51
fix(sync): never overwrite a backup left by a run that did not finish
sjsyrek Aug 6, 2026
a997c64
fix(sync): fail the run on any failed key, not only a locale that fai…
sjsyrek Aug 7, 2026
a41ec44
fix(sync): stop a failed new-locale backfill from writing source text…
sjsyrek Aug 7, 2026
4b4c487
fix(sync): make the process lock actually exclusive
sjsyrek Aug 7, 2026
3efce0f
chore(tests): drop an unnecessary type assertion in the process-lock …
sjsyrek Aug 7, 2026
4a994e2
fix(cli): neutralize terminal control sequences before rendering untr…
sjsyrek Aug 7, 2026
98defb7
fix(sync): make sync export emit well-formed XLIFF for control charac…
sjsyrek Aug 7, 2026
f71d808
fix(api): bound response size and enforce a real wall-clock request d…
sjsyrek Aug 7, 2026
443a3fb
fix(sync): stop a __proto__ i18n key from vanishing from the lockfile
sjsyrek Aug 7, 2026
c786e52
fix(sync): stop a repo-supplied tms.server from exfiltrating the oper…
sjsyrek Aug 7, 2026
8d8dd68
fix(sync): refuse a sync target path whose first segment begins with "-"
sjsyrek Aug 7, 2026
4885493
fix(cli): announce a non-standard API endpoint before sending the key…
sjsyrek Aug 7, 2026
0e1a633
fix(api): validate the shape of translate and write response bodies
sjsyrek Aug 7, 2026
af1818e
fix(sync): make a translation entry the unit of merge in the lockfile
sjsyrek Aug 7, 2026
2a96546
fix(sync): name the failed-translation count in the sync summary
sjsyrek Aug 7, 2026
c92b0cd
fix(logger): redact the credential actually in use, and only real ones
sjsyrek Aug 7, 2026
bc610bd
fix(config): enforce the private mode on the key file rather than ass…
sjsyrek Aug 7, 2026
4b6799e
fix(hooks): confirm a hooks directory the repository put outside the …
sjsyrek Aug 7, 2026
bcb83f6
fix(hooks): report what a hook is, not that a marker appears in it
sjsyrek Aug 7, 2026
956eeac
fix(sync): check the shape of a lockfile before sync relies on it
sjsyrek Aug 7, 2026
be4d139
fix(formats): stop dropping an .arb key that collides with Object.pro…
sjsyrek Aug 7, 2026
f6c8079
fix(sync): decide a translation is usable before writing it, not after
sjsyrek Aug 7, 2026
a0fe1b0
fix(sync): refuse --force when nothing can confirm it, rather than as…
sjsyrek Aug 7, 2026
27f5505
fix(translate): tell a text that was never sent apart from one that f…
sjsyrek Aug 7, 2026
e8d2a2f
fix(sync): protect every ICU block in a message, not only the first
sjsyrek Aug 7, 2026
8e07ac0
fix(translate): refuse a translation that lost a placeholder, rather …
sjsyrek Aug 8, 2026
3890d32
fix(sync): stop sync pull writing source text and claiming a review i…
sjsyrek Aug 8, 2026
8923560
fix(sync): reject the tms fields that were documented but never wired up
sjsyrek Aug 8, 2026
b214faa
fix(api): refuse a document ID that would redirect the client's own r…
sjsyrek Aug 8, 2026
55ad694
fix(translate): bound the size of a structured file before parsing it
sjsyrek Aug 8, 2026
11b0070
fix(formats): refuse a file whose strings cannot be given distinct keys
sjsyrek Aug 8, 2026
7efc5b9
fix(formats): treat only an odd trailing backslash run as a .properti…
sjsyrek Aug 8, 2026
81a9624
fix(formats): stop six writers emitting raw C0 control bytes into rep…
sjsyrek Aug 8, 2026
13e74cc
fix(sync): read the translation, not the source, from a bilingual tar…
sjsyrek Aug 8, 2026
d615218
fix(formats): write a source key added after the first sync, not drop it
sjsyrek Aug 8, 2026
f1927b1
fix(sync): record a key as translated only once the write held it
sjsyrek Aug 8, 2026
2a1c310
fix(watch): translate one version of a file at a time
sjsyrek Aug 8, 2026
a20c227
fix(watch): scope the output-file loop guard to the output directory
sjsyrek Aug 8, 2026
ee75389
fix(watch): await onTranslate and queue the auto-commit git work
sjsyrek Aug 8, 2026
d00596d
fix(sync): hold the process lock in sync resolve and write the lockfi…
sjsyrek Aug 8, 2026
9d1245b
fix(sync): keep a stale backup whose target no longer holds its content
sjsyrek Aug 8, 2026
7d09239
fix(http): classify a response cut off mid-body as a transport failure
sjsyrek Aug 8, 2026
b8dbb22
fix(formats): end a PO entry where gettext ends it, not at a blank line
sjsyrek Aug 8, 2026
5789ee5
fix(sync): check a target file against what the lockfile claims about it
sjsyrek Aug 8, 2026
6605f99
fix(sync): refuse a target file that cannot be read instead of rebuil…
sjsyrek Aug 8, 2026
1e029db
fix(sync): say which URL spellings a plaintext TMS server may use
sjsyrek Aug 8, 2026
a30c573
fix(sync): report an unreachable TMS as a network failure, not an unc…
sjsyrek Aug 8, 2026
e039389
test(e2e): parse machine-readable output from a stream that carries o…
sjsyrek Aug 8, 2026
3308c5a
fix(sync): arbitrate a whole translation when one side has no timestamp
sjsyrek Aug 8, 2026
b2165f0
fix(sync): stop sync resolve warning about data loss on every lockfil…
sjsyrek Aug 8, 2026
e97d835
fix(watch): anchor git on the watched files, not on the CLI's own dir…
sjsyrek Aug 8, 2026
6072307
fix(watch): compare path spellings through their symlinked ancestors
sjsyrek Aug 8, 2026
57754a8
fix(sync): make --dry-run and the cost cap price the run, not the loc…
sjsyrek Aug 9, 2026
e7d0426
fix(sync): stop counting a fuzzy PO translation as a finished one
sjsyrek Aug 9, 2026
2bb3e27
fix(watch,sync): ignore in-flight atomic-write temps; call a failed k…
sjsyrek Aug 9, 2026
0df2a9b
fix(watch): give each watched source its own output directory
sjsyrek Aug 9, 2026
2fdd5d1
test(watch): wait for the named outputs, not for a file count
sjsyrek Aug 9, 2026
75d46fa
fix(sync): stop counting an XLIFF needs-review state as a finished tr…
sjsyrek Aug 9, 2026
defbd14
fix(sync): keep a carried-forward plural entry's forms instead of the…
sjsyrek Aug 9, 2026
39c640b
fix(sync): keep a PO #, fuzzy flag on an entry whose content the run …
sjsyrek Aug 9, 2026
f4a3fdb
fix(translate): restore nested preservation tokens instead of refusin…
sjsyrek Aug 9, 2026
c206d9a
fix(sync): report an unreadable target as a validate issue instead of…
sjsyrek Aug 9, 2026
7e841b2
fix(sync): write the --format json error envelope to stdout, the mach…
sjsyrek Aug 9, 2026
24dcfe1
fix(sync): stop deepl sync pull reading an inherited prototype member…
sjsyrek Aug 9, 2026
f66d5cb
fix(sync): pin the TMS request origin to the approved server origin
sjsyrek Aug 9, 2026
cbbac45
test(sync): parse sync status --format json from stdout alone, not me…
sjsyrek Aug 9, 2026
48bf5af
fix(sync): carry a reviewer translation forward on the new-key path
sjsyrek Aug 9, 2026
7dde7d3
fix(sync): keep a failed batch's existing translations instead of del…
sjsyrek Aug 9, 2026
a2e63ab
fix(sync): guard the audit read against lockfile keys that escape the…
sjsyrek Aug 9, 2026
b0e6f52
fix(sync): stop sync pull deleting tab, LF and CR from pulled transla…
sjsyrek Aug 9, 2026
6d7ac8a
fix(xliff): read a unit id containing the non-delimiting quote character
sjsyrek Aug 9, 2026
8ff4dea
fix(po): keep the continuation lines of a plural form being carried f…
sjsyrek Aug 9, 2026
f6b0894
fix(sync): identify a plural form by quantity, not by matching its value
sjsyrek Aug 9, 2026
1235293
fix(sync): refuse a bucket whose source files share one target path
sjsyrek Aug 9, 2026
4069bf7
fix(watch): restore an aborted pass's targets rather than deleting th…
sjsyrek Aug 9, 2026
a0c2f73
fix(android): read a single-quoted name or quantity attribute
sjsyrek Aug 9, 2026
9ed6b2b
fix(toml): quote a new key that is not a bare key
sjsyrek Aug 9, 2026
03cdaee
fix(toml): translate a quoted key containing a dot in place
sjsyrek Aug 9, 2026
c02c5c1
fix(po): decode an escaped carriage return
sjsyrek Aug 9, 2026
5816400
fix(po): concatenate adjacent string literals on one line
sjsyrek Aug 9, 2026
7093cd3
fix(po): write msgid_plural and msgstr[N] when appending a new plural…
sjsyrek Aug 9, 2026
fa28773
fix(android,xliff): guard and escape an appended resource's key
sjsyrek Aug 9, 2026
a5eac94
fix(properties): read a key whose separator is escaped
sjsyrek Aug 9, 2026
d631322
fix(xliff): locate the review state by attribute, not by first regex …
sjsyrek Aug 9, 2026
e4a81f1
fix(sync): judge staleness per locale, not from the whole lock entry
sjsyrek Aug 9, 2026
4b8caa1
fix(sync): refuse a glob whose extglob repetition wraps an unbounded …
sjsyrek Aug 9, 2026
89e5f7a
fix(sync): name the target-only keys a rewrite removes
sjsyrek Aug 9, 2026
bdbdbee
fix(sync): read the reconstruct template through the guarded target read
sjsyrek Aug 9, 2026
41d764c
fix(watch): key a path by inode so two spellings of one file compare …
sjsyrek Aug 9, 2026
45a54ea
perf(po,sync): make the comment backtrack linear and cap the target read
sjsyrek Aug 9, 2026
ab8e955
fix(translate): choose placeholder tokens the source does not already…
sjsyrek Aug 9, 2026
f0d61d4
fix(sync): treat msgid_plural alone as a plural entry on pull
sjsyrek Aug 9, 2026
52e11d6
fix(po): read a value containing U+2028 or U+2029
sjsyrek Aug 9, 2026
ca338ea
fix(watch): recognise a temp sibling by membership, not by its name a…
sjsyrek Aug 9, 2026
da28960
fix(watch): a no-op auto-commit is not a session failure
sjsyrek Aug 9, 2026
5029865
fix(android): route an entry by the element it names, not by its key …
sjsyrek Aug 9, 2026
fdf4bf1
fix(po): do not claim an obsolete #~ block as the next entry's comments
sjsyrek Aug 9, 2026
7ff8421
docs(changelog): record the low-severity guard red-team fixes
sjsyrek Aug 9, 2026
ee44dba
chore: remove two throwaway ReDoS measurement harnesses
sjsyrek Aug 9, 2026
12d2149
fix(sync): age out a lock holder this user cannot signal, and add --b…
sjsyrek Aug 9, 2026
77c1f90
fix(sync): refuse to rewrite a target another sync configuration writes
sjsyrek Aug 9, 2026
3515903
fix(cli): emit the JSON error envelope from every command with a JSON…
sjsyrek Aug 9, 2026
a447813
fix(write): give --check a JSON result shape and stop --format json c…
sjsyrek Aug 9, 2026
ce34638
feat(write): give --diff and --alternatives JSON payloads under --for…
sjsyrek Aug 9, 2026
db00c03
refactor(comments): trim narration from the api, storage and types la…
sjsyrek Aug 9, 2026
63a68c1
refactor(comments): state the format-parser invariants as rules, not …
sjsyrek Aug 9, 2026
eeb21c4
refactor(comments): keep the sync invariants, drop the defect narration
sjsyrek Aug 9, 2026
46a471f
refactor(comments): cut step-by-step narration from the service layer
sjsyrek Aug 9, 2026
48f5109
refactor(comments): trim the CLI layer to the comments that carry a r…
sjsyrek Aug 9, 2026
339ad09
refactor(comments): keep the adversarial-input rules in utils, drop t…
sjsyrek Aug 9, 2026
771af52
docs(comments): correct the test header docblocks that misdescribe th…
sjsyrek Aug 9, 2026
a9b5218
docs(migration): add a v2 migration guide and link it from the README
sjsyrek Aug 9, 2026
c54b013
docs(changelog): stop the glossary entry contradicting the lowercase …
sjsyrek Aug 9, 2026
8e7044e
docs(changelog): condense the v2 changeset and date the 2.0.0 release
sjsyrek Aug 10, 2026
7874cf7
docs(readme): correct fabricated output, the quiet-mode contract and …
sjsyrek Aug 10, 2026
5b11834
docs(api): correct the exit-code appendix and the sync JSON contracts
sjsyrek Aug 10, 2026
b7bbc39
docs(sync): correct validate output, the status contract and schema gaps
sjsyrek Aug 10, 2026
88b16af
docs(troubleshooting): fix the write flag advice, exit-8 scope and ad…
sjsyrek Aug 10, 2026
2a3a78b
docs(migration): complete the exit-code table and cover config and fo…
sjsyrek Aug 10, 2026
30fe0e1
fix(examples): pin the CI recipes to Node 24 and correct the tag-hand…
sjsyrek Aug 10, 2026
596f012
docs(contributing): correct the release procedure, the CI gate list a…
sjsyrek Aug 10, 2026
f840f7f
chore(release): set the version to 2.0.0 and finish the publish surface
sjsyrek Aug 10, 2026
dc0467f
docs(changelog): record the examples CI and tag-handling fixes
sjsyrek Aug 10, 2026
77583a7
fix(sync): apply the per-locale model_type override
sjsyrek Aug 10, 2026
a11ab82
fix(runtime)!: require Node 24.15.0, where node:sqlite stops being ex…
sjsyrek Aug 10, 2026
f2e9b5b
ci: verify the packaged artifact and exercise the engines floor
sjsyrek Aug 10, 2026
979dacd
docs: record the Node 24.15.0 floor and document the shipped install …
sjsyrek Aug 10, 2026
ba2586f
fix(sync): identify a reclaimed pidfile by payload, not inode alone
sjsyrek Aug 10, 2026
4b88ab4
fix(cli): escape backslashes in fish completion descriptions
sjsyrek Aug 10, 2026
3bbef60
docs(changelog): record the pidfile identity and fish escaping fixes
sjsyrek Aug 10, 2026
b0558a0
docs(ci): drop the release workflow's comments and the mirror-directi…
sjsyrek Aug 10, 2026
0360fad
test(cache): drive the fresh-entry eviction test with fake timers
sjsyrek Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A clear, concise description of the bug.
- **DeepL CLI version**: (run `deepl --version`)
- **Node.js version**: (run `node --version`)
- **Operating system**: (e.g., macOS 14.5, Ubuntu 22.04, Windows 11)
- **Install method**: (source, npm link, other)
- **Install method**: (npm global, npx, Homebrew, source checkout, npm link, other)

## Reproduction Steps

Expand Down
60 changes: 58 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ jobs:

strategy:
matrix:
node-version: [24]
# 24.15.0 is the `engines.node` floor — the release where node:sqlite
# stopped emitting an ExperimentalWarning. Bare `24` resolves to the
# latest 24.x, so without the pin the declared floor is never exercised.
node-version: ['24.15.0', '24']

steps:
- uses: actions/checkout@v7
Expand All @@ -27,8 +30,61 @@ jobs:
cache: npm

- run: npm ci
# Ahead of lint: reformatting can move an eslint-disable directive off the
# line it suppresses, so drift should be reported as formatting rather
# than as the lint failures it goes on to cause.
- run: npm run format:check
- run: npm run lint
- run: npm run type-check
- run: npm run check-deps
- run: npm run build
- run: npm test
- run: npm run test:coverage

# The suites run from the working tree, so nothing above proves the published
# artifact works. `bin` and the package entry have separate module graphs — a
# broken entry point ships while the CLI still passes every test.
package:
name: Packaged artifact
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: '24'
cache: npm

- run: npm ci
- run: npm run build

- name: Pack
id: pack
run: echo "tarball=$(npm pack --silent)" >> "$GITHUB_OUTPUT"

- name: Install globally and run the CLI
env:
TARBALL: ${{ steps.pack.outputs.tarball }}
run: |
npm install -g "./$TARBALL"
deepl --version

# From a throwaway consumer package, because Node does not resolve
# bare specifiers out of the global prefix.
- name: Import the package entry as a dependency
env:
TARBALL: ${{ steps.pack.outputs.tarball }}
run: |
tarball_path="$PWD/$TARBALL"
consumer="$(mktemp -d)"
cd "$consumer"
npm init -y >/dev/null
npm install "$tarball_path"
node --input-type=module -e "
const m = await import('@deepl/cli');
const keys = Object.keys(m);
if (keys.length === 0) {
throw new Error('package entry resolved but exported nothing');
}
console.log('package entry exports:', keys.join(', '));
"
8 changes: 0 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
name: Release

# This workflow only records the GitHub Release for a tag. Publishing to npm
# happens from GitLab, so no `npm publish` step or NPM_TOKEN secret belongs in
# this repository.
on:
push:
tags:
Expand All @@ -18,8 +15,6 @@ jobs:
steps:
- uses: actions/checkout@v7

# A tag can be pushed at any commit, so a mislabelled tag would otherwise
# mint a Release whose title disagrees with the version it contains.
- name: Verify tag matches package version
run: |
tag_version="${GITHUB_REF_NAME#v}"
Expand All @@ -29,8 +24,6 @@ jobs:
exit 1
fi

# Release notes come from the tag's CHANGELOG section; releases are
# immutable once published, but notes stay editable afterwards.
- name: Extract changelog section
id: notes
run: |
Expand All @@ -44,7 +37,6 @@ jobs:
echo "has_notes=true" >> "$GITHUB_OUTPUT"
fi

# Skipped when the release exists, so re-runs are idempotent.
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
Expand Down
44 changes: 4 additions & 40 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
# Dependencies
node_modules/
.npm

# Build outputs
dist/
build/
lib/
*.tsbuildinfo

# Testing
coverage/
.nyc_output/

# Environment variables
.env
Expand All @@ -19,11 +15,6 @@ coverage/
# Secrets and credentials
*.pem
*.key
*.p12
*.pfx
*.cert
*.crt
credentials.json

# IDEs and editors
.vscode/
Expand All @@ -34,47 +25,20 @@ credentials.json

# OS files
.DS_Store
Thumbs.db
Desktop.ini

# Debug logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Runtime data
*.pid
*.seed
*.pid.lock

# Logs
logs/
*.log

# Cache and temporary files
.cache/
.temp/
.tmp/
*.tmp
# Caches
.eslintcache

# DeepL CLI specific
.deepl-cli/
# SQLite databases; the cache lives outside the repo, but a stray
# DEEPL_CONFIG_DIR could land one here. Fixture databases are committed.
*.db
!tests/fixtures/*.db
*.db-journal
*.db-wal
*.db-shm

# Claude Code local tooling (settings, hooks, agent worktrees, session state)
.claude/

# Playwright MCP local state
.playwright-mcp/

# Beads issue tracking (local)
.beads/
issues.jsonl

# QA harness
qa/
16 changes: 13 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
node_modules
# The format scripts only cover src/ and tests/, but prettier reaches
# everything below when pointed at the repo root.

# Build and coverage output
dist
coverage
*.log
.DS_Store

# Generated from GET /v3/languages; check:languages compares the raw text, so
# reformatting it would report permanent drift.
src/data/language-entries.ts

# Fixtures are byte-exact test inputs. Some encode the very thing under test:
# en-reserved-words.yaml quotes "yes"/"no" so YAML 1.1 cannot read them as
# booleans, and prettier rewrites those quotes.
tests/fixtures/
Loading
Loading