Skip to content

Commit 7595a7d

Browse files
authored
Merge branch 'main' into release-socials-v0-3-0
2 parents fedf1f6 + 5574ffd commit 7595a7d

7 files changed

Lines changed: 2842 additions & 25 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ create the tools it needs based on how you actually work.
8080
- **Desktop app or browser.** A native desktop app, or the `thinkrail` CLI that opens the same app in your
8181
browser. Both embed the same engine host; app state lives under `~/.thinkrail`.
8282
- **Your language.** Settings → Language follows your system language or a language you pick; English,
83-
Japanese, Simplified Chinese, and Spanish are built in. Add a language ThinkRail doesn't ship yet by
83+
Japanese, Russian, Simplified Chinese, and Spanish are built in. Add a language ThinkRail doesn't ship yet by
8484
dropping a translated `en.json` into `~/.thinkrail/locales` — it applies as you save. Agent replies and
8585
tool output stay as the agent wrote them.
8686
- **Your themes.** Settings → Appearance ships dark, light, minimal and high-contrast themes. Make your own

‎biome.json‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@
2323
"linter": {
2424
"enabled": true,
2525
"rules": {
26-
"preset": "recommended"
26+
"preset": "recommended",
27+
"suspicious": {
28+
"noExplicitAny": "error"
29+
},
30+
"style": {
31+
"noNonNullAssertion": "error"
32+
}
2733
}
2834
},
2935
"javascript": {

‎e2e/workflows/harness/scenario.ts‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ export interface ScenarioResult {
4444
durationMs: number;
4545
}
4646

47+
function missingEntryError(def: ScenarioDef) {
48+
return new Error(`Scenario "${def.name}": needs an entry or a user simulator.`);
49+
}
50+
4751
export function defineScenario(def: ScenarioDef): ScenarioDef {
48-
if (!def.entry && !def.user)
49-
throw new Error(`Scenario "${def.name}": needs an entry or a user simulator.`);
52+
if (!def.entry && !def.user) throw missingEntryError(def);
5053
return def;
5154
}
5255

@@ -56,8 +59,8 @@ function entryText(def: ScenarioDef): Promise<string> {
5659
return Promise.resolve(
5760
`/skill:${def.entry.skill}${def.entry.args ? ` ${def.entry.args}` : ""}`,
5861
);
59-
// biome-ignore lint/style/noNonNullAssertion: defineScenario guarantees entry or user.
60-
return openingMessage(def.user!);
62+
if (def.user) return openingMessage(def.user);
63+
throw missingEntryError(def);
6164
}
6265

6366
export async function runScenario(def: ScenarioDef): Promise<ScenarioResult> {

‎packages/locales/SPEC.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ tags: [i18n]
1212

1313
The single owner of ThinkRail's UI strings and of the rules every locale source obeys
1414
([[architecture]] Decision 23). It ships the bundled catalogs — `en.json` is the English source of truth
15-
and the file translators start from, and each `<tag>.json` beside it is a translation — and the pure
16-
functions that validate a catalog, name a file's language, and pick the language to render. Its `./react`
15+
and the file translators start from, and each `<tag>.json` beside it is a translation (currently
16+
Spanish, Japanese, Russian, and Simplified Chinese) — and the pure functions that validate a catalog,
17+
name a file's language, and pick the language to render. Its `./react`
1718
entry holds the **one** i18next instance every browser surface (`apps/web`, `packages/ui`, extension web
1819
halves) renders through, so they cannot drift onto separate instances.
1920

@@ -94,8 +95,9 @@ so the files diff cleanly.
9495
- English output is the contract tests pin: a catalog edit that changes English wording is a product
9596
change, reviewed like one. Plural pairs carry real English singulars (`"1 group"`, never `"1 groups"`).
9697
- **A bundled translation is partial by design and guarded by a test, not at runtime.** A string it lacks
97-
renders English through the chain, so it can ship incomplete and fill in later; a new key lands in
98-
`en.json` first. `applyLocale` loads bundled catalogs as-is (`validateCatalog` and `completePlurals` run
98+
renders English through the chain, so it can ship incomplete and fill in later. The Russian catalog
99+
currently covers every key in `en.json` and all four CLDR categories for its plural families; a new
100+
key still lands in `en.json` first and should be translated in Russian in the same change. `applyLocale` loads bundled catalogs as-is (`validateCatalog` and `completePlurals` run
99101
only on local files), so a catalog test requires every bundled translation to pass `validateCatalog`
100102
with nothing dropped, to hold only sorted `en.json` keys — plus a plural form for a category English
101103
lacks when the language needs one — and to carry every plural form its language needs. Changing an

0 commit comments

Comments
 (0)