* feat: add French locale runtime Add French to OpenChamber's shared i18n runtime, dictionaries, and parity tests so the existing language picker can load a complete fr locale across shared UI surfaces. * fix: localize shared UI formatting Remove remaining shared UI locale hardcodings so dates, numbers, and first-party helper copy follow the active app locale instead of leaking English on French surfaces. * feat: localize VS Code French surfaces Localize VS Code bootstrap, native runtime messages, panel titles, and manifest contribution strings so French users get consistent first-party copy across the extension experience. * fix: TASK-2026-05-30-008 correct French review findings Fix broken French relative-time and weekday strings reported on PR #1482 and restore proper import order in quota utils without broadening scope. * fix: TASK-2026-05-30-008 address final PR review comments Capture the localized More Info label once in the VS Code CLI-missing flow and replace the remaining inline French-only utility strings with dictionary-driven copy plus required locale keys. * fix: TASK-2026-05-30-008 normalize French glossary Correct glossary-level French terminology on the live PR branch, keeping canonical technical terms like PR, worktree, stash, HEAD, Mermaid, Markdown, remote, and session while replacing misleading literal translations. * fix: TASK-2026-05-30-008 refine French terminology pass Clean up remaining glossary mistakes on the French PR branch, especially around Mermaid, Markdown, PR, worktree, stash, branch, remote, and commit terminology, while keeping behavior unchanged. * fix: TASK-2026-05-30-008 clean remaining French false friends Correct the SOCKS5 mistranslation and a final small set of obvious false-friend technical nouns on the French branch without changing behavior. * fix: TASK-2026-05-30-008 correct French glossary terms Replace remaining false-friend translations in the French UI dictionaries and normalize technical labels for the French PR branch. * fix: TASK-2026-05-30-008 remove remaining French Mermaid false friend Replace the last confirmed Sirène translation with Mermaid and re-run the requested blacklist and build verification on the PR branch. * fix: TASK-2026-05-30-008 enforce French glossary policy Keep skill/PR/worktree/remote terminology developer-credible in French and remove remaining machine-translated Git and settings copy. * fix: TASK-2026-05-30-008 keep prompt terminology in French Replace remaining technical invite translations with prompt wording across scheduled tasks, multi-run, prompt templates, and Magic Prompts. * fix: TASK-2026-05-30-008 finalize French terminology cleanup Polish remaining worktree/remote wording, remove visible metadata leakage, and correct final Git and settings labels on the French PR branch. * fix: TASK-2026-05-30-008 polish final French strings Correct the last aria-like artifacts and awkward worktree/remote/GitHub URL phrasing in the French dictionaries. * fix: TASK-2026-05-30-008 normalize final French glossary framing Tighten the last worktree/remote/checkout wording and fix remaining French grammar around canonical technical terms. * fix: TASK-2026-05-30-008 align final developer glossary wording Normalize the last French framing around canonical developer terms like worktree, remote, prompt, and checkout. * fix: TASK-2026-05-30-008 harmonize final French sentence framing Replace the last raw franglais around checkout, remote, worktree, and prompt-facing labels with more natural French framing while keeping the chosen technical terms. * fix: TASK-2026-05-30-008 add compact relative date keys Replace French-specific prefix stripping in compact session date labels with dedicated i18n keys across locale dictionaries, preserving existing compact label output while making French wording robust. * docs: add French documentation * docs: mention French locale folder --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
320 lines
11 KiB
Markdown
320 lines
11 KiB
Markdown
# Docs Authoring Guide
|
|
|
|
This package is docs content source-of-truth for OpenChamber.
|
|
|
|
## Voice & style
|
|
|
|
Write for someone trying to get something done — not for an engineer reading a
|
|
spec. Assume the reader may be non-technical. A page should feel quick to read,
|
|
never like a separate chore just to get through one screen.
|
|
|
|
These rules describe how we already write the docs. Follow them so the style
|
|
stays the same no matter who is writing.
|
|
|
|
### Who you're writing for
|
|
|
|
- Assume curiosity, not expertise. The reader knows what they want to do, not
|
|
how OpenChamber works inside.
|
|
- One page = one job. If a page is answering two unrelated questions, split it.
|
|
|
|
### Keep it short
|
|
|
|
- Lead with the task, not background. The first line should say what the page is
|
|
for ("Use `openchamber tunnel` to expose a running OpenChamber instance.").
|
|
- Cut anything that doesn't change what the reader does next.
|
|
- A basic page should fit in a screen or two. Long, dense reference pages (like
|
|
Reverse Proxy) are the exception — and they say so in their first line ("Use
|
|
this page if you run OpenChamber behind...").
|
|
|
|
### Steps
|
|
|
|
- Number sequential actions; use bullets for options or unordered notes.
|
|
- Start each step with a verb: "Run", "Open", "Pick".
|
|
- End a procedure by telling the reader what success looks like, so they know
|
|
they did it right.
|
|
|
|
```mdx
|
|
3. Run `openchamber --ui-password be-creative-here`.
|
|
4. Open the printed URL (usually `http://localhost:3000`).
|
|
|
|
You should land on the OpenChamber session list. If you see it, the server is
|
|
running.
|
|
```
|
|
|
|
### Plain language
|
|
|
|
- Explain a term the first time it appears, in parentheses, in everyday words:
|
|
- good: start a tunnel (a public link to your local OpenChamber)
|
|
- bad: start a tunnel — the reader doesn't know what that is yet
|
|
- Prefer common words over internal ones. "App", "version", "page" beat
|
|
"surface", "instance", "route" when the meaning is the same. If an internal
|
|
term is unavoidable, define it once.
|
|
- Don't reach for `SSE`, `WebSocket`, `buffering`, or header names unless the
|
|
page is explicitly an advanced/operator page.
|
|
|
|
### Bullets and sentences
|
|
|
|
- Be consistent within a single list. Either all short fragments (lowercase, no
|
|
period) or all full sentences (capital letter, period) — don't mix the two in
|
|
one list.
|
|
- Use fragments for quick option lists; use full sentences for rules, warnings,
|
|
or anything the reader must not misread.
|
|
|
|
### Link out instead of re-explaining
|
|
|
|
- Where a step can realistically fail, link to
|
|
[Troubleshooting](/troubleshooting/) right there, not only at the bottom.
|
|
- Don't re-document something another page owns — link to it. (Quickstart points
|
|
at Install for the actual install command instead of copying it.)
|
|
|
|
### Show, don't only tell
|
|
|
|
- A screenshot beats a paragraph for anything visual (where a button is, what a
|
|
screen looks like). See [Images](#images) for how to add one.
|
|
- Always pair a screenshot with one line of text — the image supports the step,
|
|
it isn't the whole step.
|
|
|
|
### Commands and code
|
|
|
|
- Make code blocks copy-paste-ready: real, working values. Only use a
|
|
`<placeholder>` when the value is genuinely user-specific, and make that
|
|
obvious (e.g. `app.example.com`, `~/.secrets/cf-token`).
|
|
- One command per idea. Don't chain unrelated commands just to look compact.
|
|
|
|
## Add a new docs page
|
|
|
|
1. Create a new file in `packages/docs/content/docs/`.
|
|
- Example: `packages/docs/content/docs/remote-access.mdx`
|
|
2. Add frontmatter at top:
|
|
|
|
```mdx
|
|
---
|
|
title: Remote Access
|
|
description: Access OpenChamber from outside your local network.
|
|
---
|
|
```
|
|
|
|
3. Use route-safe naming:
|
|
- `foo.mdx` -> `/foo/`
|
|
- `folder/index.mdx` -> `/folder/`
|
|
- `folder/bar.mdx` -> `/folder/bar/`
|
|
4. Add translations for the page — see [Localization](#localization). New pages
|
|
must include translated files for every supported locale before they ship.
|
|
5. If the page is linked from the sidebar, add its localized labels too — see
|
|
[Translate the sidebar](#translate-the-sidebar).
|
|
6. Run validation:
|
|
|
|
```bash
|
|
bun run docs:validate
|
|
```
|
|
|
|
## Add a new sidebar section
|
|
|
|
Edit `packages/docs/sidebar.config.json`.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"label": "Advanced",
|
|
"items": [{ "label": "Remote Access", "link": "/remote-access/" }]
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- use trailing slash in links (`/page/`)
|
|
- every sidebar link must map to an existing MDX file
|
|
- keep section labels short and task-oriented
|
|
|
|
## Images
|
|
|
|
Images live inside the docs content tree so they sync to the website with the
|
|
pages (the sync copies all of `content/docs/`, not just `.mdx`). Reference them
|
|
with a **relative path**; Astro optimizes them at build time.
|
|
|
|
```
|
|
content/docs/
|
|
install.mdx -> 
|
|
images/
|
|
desktop.png
|
|
```
|
|
|
|
Rules:
|
|
|
|
- co-locate images under `content/docs/` (e.g. `content/docs/images/`); a
|
|
relative `./images/...` reference is resolved and optimized at build
|
|
- always set meaningful `alt` text (and translate it in localized pages)
|
|
- do **not** put docs images in the website repo's `public/` — it is not the
|
|
source of truth and the sync will not pick them up
|
|
- keep originals reasonably sized; the build generates responsive variants
|
|
|
|
For translations, reuse the same shared image when it carries no text. If a
|
|
screenshot contains localized UI text, add a per-locale copy under that locale's
|
|
folder (e.g. `uk/images/...`) and point the translated page at it.
|
|
|
|
`docs:validate` only checks `.mdx`, so images never block validation.
|
|
|
|
### Light / dark variants
|
|
|
|
To show a different screenshot per theme, add a `-light` / `-dark` pair and tag
|
|
each with `oc-light-only` / `oc-dark-only`. The website ships CSS for these
|
|
classes (keyed on Starlight's `data-theme`), so the right one shows and follows
|
|
the in-page theme toggle.
|
|
|
|
Use the `<Image>` component so the images stay optimized while taking a class.
|
|
Add the imports right under the frontmatter:
|
|
|
|
```mdx
|
|
---
|
|
title: Install
|
|
description: ...
|
|
---
|
|
|
|
import { Image } from "astro:assets";
|
|
import desktopLight from "./images/desktop-light.png";
|
|
import desktopDark from "./images/desktop-dark.png";
|
|
|
|
<Image src={desktopLight} alt="Desktop app" class="oc-light-only" />
|
|
<Image src={desktopDark} alt="Desktop app" class="oc-dark-only" />
|
|
```
|
|
|
|
Notes:
|
|
|
|
- both files live under `content/docs/` like any other image and sync normally
|
|
- give both the same `alt` (and translate it in localized pages)
|
|
- if you only have one image, just use the normal `` form
|
|
|
|
## Localization
|
|
|
|
The docs are translated into the same languages the OpenChamber app ships in.
|
|
English is the source of truth and lives at the root of `content/docs/`. Every
|
|
other language mirrors the English files under a locale folder.
|
|
|
|
### Supported locales
|
|
|
|
| Language | Content folder | Sidebar `translations` key |
|
|
| --- | --- | --- |
|
|
| English | _(root, no folder)_ | `en` |
|
|
| Ukrainian | `uk/` | `uk` |
|
|
| Chinese (Simplified) | `zh-cn/` | `zh-CN` |
|
|
| Spanish | `es/` | `es` |
|
|
| Brazilian Portuguese | `pt-br/` | `pt-BR` |
|
|
| Korean | `ko/` | `ko` |
|
|
| Polish | `pl/` | `pl` |
|
|
| French | `fr/` | `fr` |
|
|
|
|
> [!IMPORTANT]
|
|
> The **content folder** uses the lowercase locale key (`zh-cn`, `pt-br`); the
|
|
> **sidebar `translations`** key uses the BCP-47 language tag (`zh-CN`, `pt-BR`).
|
|
> They look similar but are not interchangeable — Starlight resolves them with
|
|
> different rules. Everything else (`uk`, `es`, `ko`, `pl`, `fr`, `en`) is identical
|
|
> in both columns.
|
|
|
|
This locale set is mirrored in the website at
|
|
`openchamber-website/apps/docs/astro.config.mjs` (`locales`). If a language is
|
|
added or removed, update both places.
|
|
|
|
### Translate a page
|
|
|
|
Mirror the English file under each locale folder, keeping the **exact same
|
|
filename and path**. Starlight matches a translation to its English page by path.
|
|
|
|
```
|
|
content/docs/
|
|
install.mdx # English (source of truth)
|
|
uk/install.mdx # Ukrainian
|
|
zh-cn/install.mdx # Chinese (Simplified)
|
|
es/install.mdx # Spanish
|
|
pt-br/install.mdx # Brazilian Portuguese
|
|
ko/install.mdx # Korean
|
|
pl/install.mdx # Polish
|
|
fr/install.mdx # French
|
|
|
|
guides/tunnels.mdx # nested English page
|
|
uk/guides/tunnels.mdx # its Ukrainian translation
|
|
```
|
|
|
|
Each translated file needs its **own translated frontmatter** (`title` and
|
|
`description` are required by validation):
|
|
|
|
```mdx
|
|
---
|
|
title: Встановлення
|
|
description: Встановіть OpenChamber для десктопа, вебу або VS Code.
|
|
---
|
|
```
|
|
|
|
Every new page must include translated files for all supported locales before it
|
|
ships. Starlight can fall back to English when a translation is missing, but do
|
|
not rely on that fallback for new docs pages.
|
|
|
|
### Translate the sidebar
|
|
|
|
Do **not** create separate sidebar entries per language and do **not** add a
|
|
locale prefix to `link` — Starlight prefixes the active locale automatically.
|
|
Instead, add a `translations` map (keyed by the BCP-47 tag from the table above)
|
|
to each section and item in `sidebar.config.json`:
|
|
|
|
```json
|
|
{
|
|
"label": "Start here",
|
|
"translations": {
|
|
"uk": "Почніть тут",
|
|
"zh-CN": "从这里开始",
|
|
"es": "Empieza aquí",
|
|
"pt-BR": "Comece aqui",
|
|
"ko": "여기서 시작",
|
|
"pl": "Zacznij tutaj",
|
|
"fr": "Commencer ici"
|
|
},
|
|
"items": [
|
|
{
|
|
"label": "Install",
|
|
"link": "/install/",
|
|
"translations": {
|
|
"uk": "Встановлення",
|
|
"zh-CN": "安装",
|
|
"es": "Instalación",
|
|
"pt-BR": "Instalação",
|
|
"ko": "설치",
|
|
"pl": "Instalacja",
|
|
"fr": "Installation"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
A label with no translation for the active locale falls back to the English
|
|
`label`.
|
|
|
|
### What not to translate
|
|
|
|
- brand and product nouns: OpenChamber, OpenCode, VS Code, PWA, GitHub, Discord,
|
|
macOS, SSH
|
|
- code blocks, shell commands, file paths, flags, and config keys
|
|
- the page filename and the sidebar `link` (these stay identical across locales)
|
|
|
|
### Validate
|
|
|
|
`bun run docs:validate` walks every `.mdx` under `content/docs/` — **including
|
|
translations** — and fails if any page is missing `title` or `description`
|
|
frontmatter, or if a sidebar `link` does not resolve to an English page. Run it
|
|
after adding or translating pages.
|
|
|
|
## Sync into openchamber-website
|
|
|
|
`openchamber-website` renders/deploys docs via Starlight in `apps/docs`.
|
|
|
|
After docs content updates here:
|
|
|
|
1. copy `packages/docs/content/docs/*` -> `openchamber-website/apps/docs/src/content/docs/*`
|
|
(this is recursive, so locale folders like `uk/` and `zh-cn/` carry over with
|
|
no extra steps)
|
|
2. map `packages/docs/sidebar.config.json` into `openchamber-website/apps/docs/astro.config.mjs` sidebar
|
|
(the `translations` maps carry over as-is)
|
|
3. run docs checks/build in website repo
|
|
|
|
Automation support exists in `.github/workflows/docs-source.yml` (release/manual packaging of docs source artifact).
|