Skip to content
v0.9.13

LocaleKit Docs Enhancements — Design Spec

Date: 2026-03-18 Status: Draft

Overview

Enhance the LocaleKit VitePress documentation site with developer-focused features: brand typography, version/timestamp display, source links, navigation improvements, auth badges, engine/model icons, configuration reference, and accuracy improvements (JSON schemas, exit codes, env vars, shell completions, snapshot docs, Apple Intelligence caveat). All changes must be compatible with the existing generate-cli-docs.mjs automation.

1. Manrope Font

Load Manrope from Google Fonts (the same font family used in the macOS app via LocaleKitTheme.swift).

Implementation:

  • Add Google Fonts <link> to config.ts head with &display=swap to avoid flash of invisible text
  • Override VitePress font CSS variables in custom.css:
    • --vp-font-family-base: 'Manrope', sans-serif
    • --vp-font-family-mono stays as-is (monospace for code)

2. CLI Version + Last Updated Timestamp

The generation script reads CLIVersion.swift to extract the current version string, and stamps the generation date. This information appears in two places:

A. Index page badge — at the top of docs/index.md, below the title:

markdown
::: info
**CLI version: 1.2.0** · Documentation generated on Mar 18, 2026
:::

When the version is "dev" (local builds without CI tag), display:

markdown
::: info
**CLI version: dev** · Documentation generated on Mar 18, 2026
:::

This is accurate — "dev" tells the reader they're looking at docs generated from an unreleased build.

B. Footer — update config.ts footer message to include version dynamically. The generation script writes a small docs/.vitepress/generated-meta.ts file:

ts
export const cliVersion = '1.2.0'
export const generatedAt = '2026-03-18'

config.ts imports this and uses it in the footer. This file is committed to git (like generated-cli-sidebar.ts), so vitepress dev works without running generation first.

Source: CLIVersion.swiftstatic let current = "..." — parsed via regex from the Swift source.

Add a "View LocaleKit source" link on each page pointing to the LocaleKit repo.

Since generated pages come from Swift files (not editable markdown), a per-file :path mapping doesn't apply. Instead, use a custom nav link rather than VitePress's built-in editLink (which requires a :path template and would produce broken URLs).

Implementation: Add to config.ts nav:

ts
nav: [
  { text: 'Reference', link: '/' },
  { text: 'Source', link: 'https://github.com/hexagone-studio/LocaleKit' },
]

This is simpler and more correct than abusing editLink.

4. Right-Side Outline (Table of Contents)

VitePress has a built-in outline feature. Enable it to show h2 headings (Usage, Arguments, Options, Flags, Examples) in the right sidebar.

Implementation in config.ts:

ts
outline: {
  level: [2, 3],
  label: 'On this page'
}

No changes to generated markdown needed — it already uses ## Usage, ## Options, etc.

5. Prev/Next Navigation

VitePress auto-generates prev/next links from the sidebar order. The sidebar is grouped, so prev/next follows group order:

init → scan → status → translate → validate → diff (Localization) → export → convert (Export & Convert) → sync (GitHub) → login → logout → whoami (Auth) → mcp (AI)

Implementation: VitePress enables this by default with our sidebar structure. Verify it renders. Optionally customize labels via docFooter in config:

ts
docFooter: {
  prev: 'Previous',
  next: 'Next'
}

6. Custom 404 Page

Use VitePress's built-in not-found layout support. Create docs/404.md:

markdown
---
layout: page
title: Page Not Found
---

<div style="text-align: center; padding: 4rem 1rem;">
  <p style="font-size: 4rem; font-weight: 700; margin: 0; background: linear-gradient(135deg, #90ccf0, #00AAff); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">404</p>
  <p style="color: var(--vp-c-text-2); margin-top: 1rem;">This page doesn't exist.</p>
  <a href="/" style="color: var(--vp-c-brand-1);">Back to CLI Reference</a>
</div>

VitePress generates a 404.html from this. The existing nginx.conf already routes to 404.html via try_files ... /404.html, so no deployment changes are needed.

This is a manual file (not generated).

7. Code Groups in Generated Pages

For commands that have an --engine option (translate, sync), generate a tabbed "Quick Start" section with per-engine examples:

markdown
## Quick Start

::: code-group
```bash [DeepL]
localekit translate --engine deepl --api-key $DEEPL_API_KEY
bash
localekit translate --engine openai --api-key $OPENAI_API_KEY
bash
localekit translate --engine mlx --mlx-model mlx-community/Qwen3-4B-4bit

:::


**Implementation:** The generator checks if a command's options include one named `engine`. If so, it emits the code group after the description. The engine names and example flags are defined as static data in the script (not parsed from Swift), since help text for the `--engine` option varies between commands.

**Note:** `translate`'s help text says "openai, deepl" while `sync` says "openai, deepl, mlx" — but both commands actually support all three engines in code. The code group will show all three for both commands.

**Commands affected:** `translate`, `sync`.

## 8. Improved Index Page

The root index currently jumps straight into command tables. Add a practical header with install and quick-start sections.

**A. Version badge** (from Section 2) at the top.

**B. Install snippet** with code group:

```markdown
## Install

::: code-group
```bash [Homebrew]
brew tap hexagone-studio/localekit https://github.com/hexagone-studio/LocaleKit.git
brew install localekit-cli
bash
cd LocaleKitCore
swift build -c release
sudo cp .build/release/LocaleKitCLI /usr/local/bin/localekit

:::


**C. Quick start** — 3-line workflow:

```markdown
## Quick Start

```bash
localekit init ./MyApp          # Create .localekitrc.yml
localekit status                # Check translation coverage
localekit translate --engine deepl  # Translate missing keys

These sections are **static content** defined as constants in the generation script (not parsed from Swift). They are prepended to the generated command tables in the index. Future changes to install instructions require editing the script constants.

## 9. Auth/Tier Badges on Commands

Extract authentication requirements from the Swift source and display badges.

**Extraction logic** — scan each command's `run()` method body:
- `CLIAuthGuard.requireTier(.solo)` → badge: `Solo plan`
- `CLIAuthGuard.requireAuth()` → badge: `Requires login`
- `CLIAuthGuard.isExportLimited` or `CLIAuthGuard.isConvertLimited` → append: `Limited on free tier`
- No auth guard → no badge

**Commands and their tiers** (verified from Swift source):

| Tier | Commands |
|------|----------|
| No guard | login, logout, whoami, init, mcp |
| Requires login | scan, status, validate, diff |
| Requires login + limited on free | export, convert |
| Solo plan | translate, sync |

**Display — command page** (after the description, before Usage):

```markdown
<Badge type="warning" text="Solo plan" />

Display — index table — third column:

markdown
| Command | Description | |
|---------|-------------|-|
| [`localekit translate`](./cli/translate) | Translate missing localization keys | <Badge type="warning" text="Solo" /> |
| [`localekit export`](./cli/export) | Export localization file to another format | <Badge type="tip" text="Login" /> |

Commands with no badge get an empty third column.

10. Engine & Model Icons

Copy translation engine icons and MLX model family icons from localekit-macos into docs/public/icons/ for use in documentation pages.

Engine icons (from LocaleKitCore/Resources/Media.xcassets/):

EngineSource file (2x)Output
DeepLdeepL.imageset/deepl-color 4@2x.pngdocs/public/icons/deepl.png
OpenAIopenAI.imageset/chatgpt (2).pngdocs/public/icons/openai.png
MLXmlx.imageset/mlx-logo 1.pngdocs/public/icons/mlx.png
Apple IntelligenceAppleIntelligence.imageset/image 4@2x.pngdocs/public/icons/apple-intelligence.png

MLX model icons (from same xcassets):

ModelSource fileOutput
Qwenqwen.imageset/Qwen_logo.svgdocs/public/icons/qwen.svg
Mistralmistral.imageset/Mistral_AI_logo_(2025–).svg 1.pngdocs/public/icons/mistral.png
Gemmagemma.imageset/gemma-color 1.pngdocs/public/icons/gemma.png

Usage in docs:

A. Engine code groups (Section 7) — add icon before the tab label using inline HTML:

markdown
::: code-group
```bash [DeepL]
localekit translate --engine deepl --api-key $DEEPL_API_KEY
bash
localekit translate --engine openai --api-key $OPENAI_API_KEY
bash
localekit translate --engine mlx --mlx-model mlx-community/Qwen3-4B-4bit

:::


B. **MLX models table** — generate a table on the `translate` and `sync` command pages listing all available MLX models with their icons, parsed from `MLXModelOption.swift`:

```markdown
### MLX Models

| | Model | Parameters | Size | RAM | Languages |
|-|-------|------------|------|-----|-----------|
| <img src="/icons/qwen.svg" width="20"> | Qwen3 4B | 4B | 2.5 GB | 8 GB | 119 |
| <img src="/icons/mistral.png" width="20"> | Mistral 7B | 7B | 4.1 GB | 8 GB | 15 |
| <img src="/icons/qwen.svg" width="20"> | Qwen3 8B | 8B | 5.0 GB | 16 GB | 119 |
| <img src="/icons/gemma.png" width="20"> | Gemma 3 12B | 12B | 8.0 GB | 16 GB | 35 |
| <img src="/icons/qwen.svg" width="20"> | Qwen3 30B-A3B | 30B (3B MoE) | 16.0 GB | 16 GB | 119 |
| <img src="/icons/qwen.svg" width="20"> | Qwen3 32B | 32B | 18.0 GB | 32 GB | 119 |

Extraction: The generator parses MLXModelOption.swift for the allModels static array, extracting: id, displayName, parameterCount, activeParameters, minimumRAMGB, sizeOnDiskGB, languageCount, isMoE, and family. The family maps to the icon filename.

Default model indicator: Qwen3 4B is marked as default with a badge: <Badge type="tip" text="default" />

C. Engine overview on index page — add a visual engines section before the command tables:

markdown
## Translation Engines

| | Engine | Type | API Key |
|-|--------|------|---------|
| <img src="/icons/deepl.png" width="20"> | DeepL | Cloud | `DEEPL_API_KEY` |
| <img src="/icons/openai.png" width="20"> | OpenAI | Cloud | `OPENAI_API_KEY` |
| <img src="/icons/mlx.png" width="20"> | MLX | On-device (Apple Silicon) | — |
| <img src="/icons/apple-intelligence.png" width="20"> | Apple Intelligence | On-device (macOS 15.1+) | — |

Icons are static assets (copied once, not generated). The copy step runs as part of the generation script if the icons don't already exist in docs/public/icons/.

11. Configuration Reference Page

Generate a .localekitrc.yml reference page at docs/cli/configuration.md from the example config file at ../localekit-macos/docs/localekitrc.example.yml.

Content:

  • Full annotated YAML example (copied from the source file)
  • Field-by-field reference table explaining each option
  • Environment variable substitution syntax (${ENV_VAR})
  • Engine-specific settings (DeepL key, OpenAI key, MLX model)
  • GitHub integration settings

Generated page structure:

markdown
# Configuration

LocaleKit is configured via a `.localekitrc.yml` file in your project root.
Create one with `localekit init` or manually.

## Example

```yaml
{full contents of localekitrc.example.yml}

Reference

FieldTypeDescriptionDefault
workspacestringProject directory to scan.
sourceLanguagestringBase language (BCP 47)en-US
targetLanguagesstring[]Target languages
enginestringTranslation engine: deepl, openai, mlxdeepl
deeplApiKeystringDeepL API key (supports ${ENV_VAR})
openaiApiKeystringOpenAI API key (supports ${ENV_VAR})
mlxModelstringMLX model ID from Hugging Facemlx-community/Qwen3-4B-4bit
verboseboolShow detailed outputfalse
dryRunboolPreview without writing filesfalse
github.repostringRepository in owner/repo format
github.baseBranchstringBase branch for PRsmain
github.tokenstringGitHub token (or use GITHUB_TOKEN env)

**Source:** The YAML example is read from `../localekit-macos/docs/localekitrc.example.yml`. The reference table is static content in the script (the example file contains all the documentation needed as YAML comments).

**Sidebar:** Add "Configuration" to the sidebar under a new "Setup" group, before the Localization commands.

## 12. Configuration Page Additions

In addition to the `.localekitrc.yml` reference (Section 11), the configuration page should include:

### A. Shell Completions

Shell completions (bash, zsh, fish) auto-complete command and flag names when pressing Tab.

**Homebrew users** get completions automatically — the formula has been updated to use `generate_completions_from_executable` which installs them on `brew install`. Change made in `localekit-macos/homebrew/localekit-cli.rb`.

**Manual install** users need to generate them. Document on the configuration page:

```markdown
## Shell Completions

Homebrew installs completions automatically. For manual installs:

::: code-group
```bash [Zsh]
localekit --generate-completion-script zsh > ~/.zsh/completions/_localekit
bash
localekit --generate-completion-script bash > /etc/bash_completion.d/localekit
bash
localekit --generate-completion-script fish > ~/.config/fish/completions/localekit.fish

:::


This is static content in the generation script.

### B. Environment Variables Reference

Collected from all commands:

```markdown
## Environment Variables

| Variable | Used By | Description |
|----------|---------|-------------|
| `DEEPL_API_KEY` | translate, sync | DeepL API key |
| `OPENAI_API_KEY` | translate, sync | OpenAI API key |
| `LOCALEKIT_API_KEY` | translate, sync | Fallback API key (any engine) |
| `GITHUB_TOKEN` | sync | GitHub personal access token |

C. Exit Codes

markdown
## Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Validation error, auth failure, or warnings in strict mode |
| `2` | Invalid command-line arguments |

These are all static tables defined in the generation script.

13. Generator Improvements for Accuracy

Several accuracy improvements to the generation script output:

A. Apple Intelligence caveat

The CLITranslationEngine enum includes .appleIntelligence, but TranslateCommand and SyncCommand both throw:

"Apple Intelligence is not available in CLI mode. Use --engine deepl, openai, or mlx instead."

The engines table on the index page must note this: Apple Intelligence — macOS app only (not available in CLI).

The code groups on translate/sync should only show DeepL, OpenAI, and MLX — not Apple Intelligence.

B. JSON output schemas

Commands with --json output (scan, status, validate, diff, whoami) should have a "JSON Output" section showing the schema. The generation script can detect --json flags and append a static schema block per command. The schemas are defined as constants in the script (derived from reading the Swift code).

C. Snapshot file documentation

The translate command creates .localekit-snapshot.json and the diff command requires it. Add a note on the translate page:

After translating, a .localekit-snapshot.json file is saved. This is used by localekit diff to detect changes.

And on the diff page:

Requires a .localekit-snapshot.json file created by a previous localekit translate run.

These notes are added by the generation script as static content, keyed by command name.

14. Sitemap

VitePress has built-in sitemap generation. Enable it only when a confirmed hostname is set via environment variable, to avoid publishing sitemaps with placeholder domains.

Implementation in config.ts:

ts
...(process.env.SITE_URL ? { sitemap: { hostname: process.env.SITE_URL } } : {}),

In Coolify, set SITE_URL=https://docs.localekit.app (or the actual domain). Locally and in CI without the variable, no sitemap is generated.

Files Changed

FileChange Type
docs/.vitepress/config.tsModified — font, nav source link, outline, sitemap, footer with version
docs/.vitepress/theme/custom.cssModified — Manrope font variable
docs/.vitepress/generated-meta.tsNew (generated, committed) — CLI version + timestamp
docs/.vitepress/generated-cli-sidebar.tsModified (generated) — new "Setup" group with configuration page
docs/index.mdModified (generated) — install, quick start, version badge, engines table, badge column
docs/cli/*.mdModified (generated) — auth badges, code groups + MLX models on translate/sync, JSON schemas, snapshot notes
docs/cli/configuration.mdNew (generated) — config reference, shell completions, env vars, exit codes
docs/public/icons/*.png + *.svgNew (copied) — engine icons (deepl, openai, mlx, apple-intelligence) + model icons (qwen, mistral, gemma)
docs/404.mdNew (manual) — custom 404 page
scripts/generate-cli-docs.mjsModified — version extraction, badges, code groups, MLX models parsing, config page, icon copy, improved index
scripts/update-docs.shModified — include generated-meta.ts + configuration.md in diff/stage paths
package.jsonModified — include generated-meta.ts + configuration.md in check script paths
.git/hooks/pre-commitModified — include generated-meta.ts + configuration.md in diff paths

Files NOT Changed

  • Dockerfile, nginx.conf — no deployment changes
  • docs/.vitepress/theme/index.ts — no structural theme changes

Constraints

  • All changes to generated files go through generate-cli-docs.mjs — never edit generated files manually
  • The generation script must remain idempotent and deterministic (same input → same output, except for the date in generatedAt which uses the generation date)
  • The pre-commit hook and check:cli-docs script must cover all generated files including generated-meta.ts
  • Static content in the index (install, quick start) is defined as constants in the script, not parsed from Swift

LocaleKit CLI 0.9.13 · Built by Hexagone Studio