JSON contracts
x18n has one versioned JSON contract. The CLI prints it with --json. The LSP x18n/* requests, the UI RPC functions and the MCP tools use the same shapes.
The current contract version is 2. A breaking change to any shape increases it. A new optional field does not.
Envelope
With --json, every command prints one JSON document to stdout:
export interface Envelope<T> {
readonly x18n: number
readonly command: string
readonly data: T
readonly diagnostics: readonly WireDiagnostic[]
readonly errors: readonly ErrorInfo[]
}x18nis the contract version.commandis the command name, for examplekeysorprompt translate.datais the result of the command. It isnullwhen the command failed.errorsholds the errors. In JSON mode, errors appear only here, so stdout is always valid JSON.
/** JSON form of an error: the `toJSON()` of a nostics diagnostic, without `stack`, `cause` and `data`. */
export interface ErrorInfo {
/** The code, such as `X18N2002`, or the JS error name of an error without a code. */
readonly name: string
readonly why: string
readonly fix?: string | undefined
readonly docs?: string | undefined
}docs is the URL of the error page of the code.
Diagnostics
Checks report diagnostics. x18n check --json puts them in diagnostics of the envelope, and its data holds a summary and the coverage per project. x18n get --json puts the diagnostics of one key in data. Both use this shape:
export interface WireDiagnostic {
readonly project: string
readonly code: string
readonly severity: Severity
readonly message: string
readonly key: KeyString | undefined
readonly locale: LocaleCode | undefined
/** Path relative to the project root. */
readonly file: string | undefined
readonly range: WireRange | undefined
readonly fixes: readonly Fix[]
}
export interface WireRange {
/** 1-based. */
readonly line: number
/** 1-based, UTF-16 code units. */
readonly column: number
readonly endLine: number
readonly endColumn: number
/** 0-based UTF-16 offsets. */
readonly start: number
readonly end: number
}
export type Severity = 'error' | 'warning' | 'info' | 'hint'
export interface Fix {
readonly title: string
readonly ops: readonly EditOp[]
}
export type EditOp
= | { readonly type: 'set', readonly key: KeyString, readonly locale: LocaleCode, readonly value: MessageLeaf }
| { readonly type: 'rename', readonly from: KeyString, readonly to: KeyString, readonly usages?: boolean }
| { readonly type: 'rename-prefix', readonly from: KeyString, readonly to: KeyString, readonly usages?: boolean }
| { readonly type: 'delete', readonly key: KeyString, readonly locales?: 'all' | readonly LocaleCode[] }
| { readonly type: 'extract', readonly items: readonly ExtractItem[] }
/** Re-write resources with the configured sort and indent. */
| { readonly type: 'format', readonly paths?: readonly string[] }code is the check id, for example missing-key. See Checks.
Input of x18n apply
x18n apply and the MCP tool x18n_set_messages read messages per locale:
{
"de": {
"app.title": "Meine App",
"nav.home": "Start"
}
}Extraction plan
x18n extract --plan <file> writes this file, and x18n extract --apply <file> reads it back after you edit it:
export interface ExtractPlanFile {
readonly x18n: 1
readonly project: string
readonly items: readonly ExtractCandidate[]
}
export interface ExtractCandidate {
readonly path: string
/** 1-based line, for display. */
readonly line: number
readonly kind: string
readonly text: string
/** The text in the file at `range`, used to detect stale plans. */
readonly original: string
readonly range: TextRange
readonly attribute: string | undefined
readonly key: KeyString
/** True when an existing key with the same source value is reused. */
readonly reused: boolean
/** The message to store: template arguments become placeholders. */
readonly value: string
readonly replacement: string
readonly imports: readonly string[]
/** Other templates that also apply, for surfaces that let users choose. */
readonly alternatives: readonly string[]
}Exit codes
| Exit code | Meaning | Error codes |
|---|---|---|
0 | Success. For x18n check: no errors, and no more warnings than --max-warnings. | |
1 | x18n check found errors or too many warnings, x18n apply rejected values, or the command failed with one of these errors. | X18N2001, X18N2002, X18N2003, X18N2004, X18N3001, X18N4001, X18N4002, X18N4005, X18N4006, X18N4007, X18N4008 |
2 | Usage, config or plugin error. Errors without an x18n code also exit with 2. | X18N0001, X18N0002, X18N0003, X18N1001, X18N1002, X18N1003, X18N1004 |
3 | A decision is needed and no answer was given. Run again with --yes. | X18N4003 |
4 | Files changed while the command ran. Run it again. | X18N4004 |