Skip to content

Commit dc53086

Browse files
authored
wip(docs): i18n (anomalyco#12681)
1 parent f74c033 commit dc53086

File tree

642 files changed

+192742
-506
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

642 files changed

+192742
-506
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: docs-locale-sync
2+
3+
on:
4+
push:
5+
branches:
6+
- dev
7+
paths:
8+
- packages/web/src/content/docs/*.mdx
9+
10+
jobs:
11+
sync-locales:
12+
if: github.actor != 'opencode-agent[bot]'
13+
runs-on: blacksmith-4vcpu-ubuntu-2404
14+
permissions:
15+
id-token: write
16+
contents: write
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup Bun
24+
uses: ./.github/actions/setup-bun
25+
26+
- name: Setup git committer
27+
id: committer
28+
uses: ./.github/actions/setup-git-committer
29+
with:
30+
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
31+
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
32+
33+
- name: Compute changed English docs
34+
id: changes
35+
run: |
36+
FILES=$(git diff --name-only "${{ github.event.before }}" "${{ github.sha }}" -- 'packages/web/src/content/docs/*.mdx' || true)
37+
if [ -z "$FILES" ]; then
38+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
39+
echo "No English docs changed in push range"
40+
exit 0
41+
fi
42+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
43+
{
44+
echo "files<<EOF"
45+
echo "$FILES"
46+
echo "EOF"
47+
} >> "$GITHUB_OUTPUT"
48+
49+
- name: Sync locale docs with OpenCode
50+
if: steps.changes.outputs.has_changes == 'true'
51+
uses: sst/opencode/github@latest
52+
env:
53+
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
54+
with:
55+
model: opencode/gpt-5.2
56+
agent: docs
57+
prompt: |
58+
Update localized docs to match the latest English docs changes.
59+
60+
Changed English doc files:
61+
<changed_english_docs>
62+
${{ steps.changes.outputs.files }}
63+
</changed_english_docs>
64+
65+
Requirements:
66+
1. Update all relevant locale docs under packages/web/src/content/docs/<locale>/ so they reflect these English page changes.
67+
2. Preserve frontmatter keys, internal links, code blocks, and existing locale-specific metadata unless the English change requires an update.
68+
3. Keep locale docs structure aligned with their corresponding English pages.
69+
4. Do not modify English source docs in packages/web/src/content/docs/*.mdx.
70+
5. If no locale updates are needed, make no changes.
71+
72+
- name: Commit and push locale docs updates
73+
if: steps.changes.outputs.has_changes == 'true'
74+
run: |
75+
if [ -z "$(git status --porcelain)" ]; then
76+
echo "No locale docs changes to commit"
77+
exit 0
78+
fi
79+
git add -A
80+
git commit -m "docs(i18n): sync locale docs from english changes"
81+
git pull --rebase --autostash origin "$GITHUB_REF_NAME"
82+
git push origin HEAD:"$GITHUB_REF_NAME"

bun.lock

Lines changed: 118 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/console/app/src/routes/docs/[...path].ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import type { APIEvent } from "@solidjs/start/server"
2-
import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language"
2+
import { localeFromRequest, tag } from "~/lib/language"
33

44
async function handler(evt: APIEvent) {
55
const req = evt.request.clone()
66
const url = new URL(req.url)
77
const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}`
88

99
const headers = new Headers(req.headers)
10-
const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie"))
11-
if (locale) headers.set("accept-language", tag(locale))
10+
headers.set("accept-language", tag(localeFromRequest(req)))
1211

1312
const response = await fetch(targetUrl, {
1413
method: req.method,

packages/console/app/src/routes/docs/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import type { APIEvent } from "@solidjs/start/server"
2-
import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language"
2+
import { localeFromRequest, tag } from "~/lib/language"
33

44
async function handler(evt: APIEvent) {
55
const req = evt.request.clone()
66
const url = new URL(req.url)
77
const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}`
88

99
const headers = new Headers(req.headers)
10-
const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie"))
11-
if (locale) headers.set("accept-language", tag(locale))
10+
headers.set("accept-language", tag(localeFromRequest(req)))
1211

1312
const response = await fetch(targetUrl, {
1413
method: req.method,

packages/console/app/src/routes/download/index.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export default function Download() {
294294
</span>
295295
<span>VS Code</span>
296296
</div>
297-
<a href="https://opencode.ai/docs/ide/" data-component="action-button">
297+
<a href="/docs/ide/" data-component="action-button">
298298
{i18n.t("download.action.install")}
299299
</a>
300300
</div>
@@ -318,7 +318,7 @@ export default function Download() {
318318
</span>
319319
<span>Cursor</span>
320320
</div>
321-
<a href="https://opencode.ai/docs/ide/" data-component="action-button">
321+
<a href="/docs/ide/" data-component="action-button">
322322
{i18n.t("download.action.install")}
323323
</a>
324324
</div>
@@ -335,7 +335,7 @@ export default function Download() {
335335
</span>
336336
<span>Zed</span>
337337
</div>
338-
<a href="https://opencode.ai/docs/ide/" data-component="action-button">
338+
<a href="/docs/ide/" data-component="action-button">
339339
{i18n.t("download.action.install")}
340340
</a>
341341
</div>
@@ -352,7 +352,7 @@ export default function Download() {
352352
</span>
353353
<span>Windsurf</span>
354354
</div>
355-
<a href="https://opencode.ai/docs/ide/" data-component="action-button">
355+
<a href="/docs/ide/" data-component="action-button">
356356
{i18n.t("download.action.install")}
357357
</a>
358358
</div>
@@ -369,7 +369,7 @@ export default function Download() {
369369
</span>
370370
<span>VSCodium</span>
371371
</div>
372-
<a href="https://opencode.ai/docs/ide/" data-component="action-button">
372+
<a href="/docs/ide/" data-component="action-button">
373373
{i18n.t("download.action.install")}
374374
</a>
375375
</div>
@@ -393,7 +393,7 @@ export default function Download() {
393393
</span>
394394
<span>GitHub</span>
395395
</div>
396-
<a href="https://opencode.ai/docs/github/" data-component="action-button">
396+
<a href="/docs/github/" data-component="action-button">
397397
{i18n.t("download.action.install")}
398398
</a>
399399
</div>
@@ -410,7 +410,7 @@ export default function Download() {
410410
</span>
411411
<span>GitLab</span>
412412
</div>
413-
<a href="https://opencode.ai/docs/gitlab/" data-component="action-button">
413+
<a href="/docs/gitlab/" data-component="action-button">
414414
{i18n.t("download.action.install")}
415415
</a>
416416
</div>

packages/console/app/src/routes/s/[id].ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import type { APIEvent } from "@solidjs/start/server"
2-
import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language"
2+
import { localeFromRequest, tag } from "~/lib/language"
33

44
async function handler(evt: APIEvent) {
55
const req = evt.request.clone()
66
const url = new URL(req.url)
77
const targetUrl = `https://docs.opencode.ai/docs${url.pathname}${url.search}`
88

99
const headers = new Headers(req.headers)
10-
const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie"))
11-
if (locale) headers.set("accept-language", tag(locale))
10+
headers.set("accept-language", tag(localeFromRequest(req)))
1211

1312
const response = await fetch(targetUrl, {
1413
method: req.method,

packages/web/astro.config.mjs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,99 @@ export default defineConfig({
3232
solidJs(),
3333
starlight({
3434
title: "OpenCode",
35+
defaultLocale: "root",
36+
locales: {
37+
root: {
38+
label: "English",
39+
lang: "en",
40+
dir: "ltr",
41+
},
42+
ar: {
43+
label: "العربية",
44+
lang: "ar",
45+
dir: "rtl",
46+
},
47+
bs: {
48+
label: "Bosanski",
49+
lang: "bs-BA",
50+
dir: "ltr",
51+
},
52+
da: {
53+
label: "Dansk",
54+
lang: "da-DK",
55+
dir: "ltr",
56+
},
57+
de: {
58+
label: "Deutsch",
59+
lang: "de-DE",
60+
dir: "ltr",
61+
},
62+
es: {
63+
label: "Espa\u00f1ol",
64+
lang: "es-ES",
65+
dir: "ltr",
66+
},
67+
fr: {
68+
label: "Fran\u00e7ais",
69+
lang: "fr-FR",
70+
dir: "ltr",
71+
},
72+
it: {
73+
label: "Italiano",
74+
lang: "it-IT",
75+
dir: "ltr",
76+
},
77+
ja: {
78+
label: "日本語",
79+
lang: "ja-JP",
80+
dir: "ltr",
81+
},
82+
ko: {
83+
label: "한국어",
84+
lang: "ko-KR",
85+
dir: "ltr",
86+
},
87+
nb: {
88+
label: "Norsk Bokm\u00e5l",
89+
lang: "nb-NO",
90+
dir: "ltr",
91+
},
92+
pl: {
93+
label: "Polski",
94+
lang: "pl-PL",
95+
dir: "ltr",
96+
},
97+
"pt-br": {
98+
label: "Portugu\u00eas (Brasil)",
99+
lang: "pt-BR",
100+
dir: "ltr",
101+
},
102+
ru: {
103+
label: "Русский",
104+
lang: "ru-RU",
105+
dir: "ltr",
106+
},
107+
th: {
108+
label: "ไทย",
109+
lang: "th-TH",
110+
dir: "ltr",
111+
},
112+
tr: {
113+
label: "T\u00fcrk\u00e7e",
114+
lang: "tr-TR",
115+
dir: "ltr",
116+
},
117+
"zh-cn": {
118+
label: "简体中文",
119+
lang: "zh-CN",
120+
dir: "ltr",
121+
},
122+
"zh-tw": {
123+
label: "繁體中文",
124+
lang: "zh-TW",
125+
dir: "ltr",
126+
},
127+
},
35128
favicon: "/favicon-v3.svg",
36129
head: [
37130
{
@@ -89,11 +182,51 @@ export default defineConfig({
89182
"1-0",
90183
{
91184
label: "Usage",
185+
translations: {
186+
en: "Usage",
187+
ar: "الاستخدام",
188+
"bs-BA": "Korištenje",
189+
"da-DK": "Brug",
190+
"de-DE": "Nutzung",
191+
"es-ES": "Uso",
192+
"fr-FR": "Utilisation",
193+
"it-IT": "Utilizzo",
194+
"ja-JP": "使い方",
195+
"ko-KR": "사용",
196+
"nb-NO": "Bruk",
197+
"pl-PL": "Użycie",
198+
"pt-BR": "Uso",
199+
"ru-RU": "Использование",
200+
"th-TH": "การใช้งาน",
201+
"tr-TR": "Kullanım",
202+
"zh-CN": "使用",
203+
"zh-TW": "使用",
204+
},
92205
items: ["tui", "cli", "web", "ide", "zen", "share", "github", "gitlab"],
93206
},
94207

95208
{
96209
label: "Configure",
210+
translations: {
211+
en: "Configure",
212+
ar: "الإعداد",
213+
"bs-BA": "Podešavanje",
214+
"da-DK": "Konfiguration",
215+
"de-DE": "Konfiguration",
216+
"es-ES": "Configuración",
217+
"fr-FR": "Configuration",
218+
"it-IT": "Configurazione",
219+
"ja-JP": "設定",
220+
"ko-KR": "구성",
221+
"nb-NO": "Konfigurasjon",
222+
"pl-PL": "Konfiguracja",
223+
"pt-BR": "Configuração",
224+
"ru-RU": "Настройка",
225+
"th-TH": "การกำหนดค่า",
226+
"tr-TR": "Yapılandırma",
227+
"zh-CN": "配置",
228+
"zh-TW": "設定",
229+
},
97230
items: [
98231
"tools",
99232
"rules",
@@ -114,13 +247,34 @@ export default defineConfig({
114247

115248
{
116249
label: "Develop",
250+
translations: {
251+
en: "Develop",
252+
ar: "التطوير",
253+
"bs-BA": "Razvoj",
254+
"da-DK": "Udvikling",
255+
"de-DE": "Entwicklung",
256+
"es-ES": "Desarrollo",
257+
"fr-FR": "Développement",
258+
"it-IT": "Sviluppo",
259+
"ja-JP": "開発",
260+
"ko-KR": "개발",
261+
"nb-NO": "Utvikling",
262+
"pl-PL": "Rozwój",
263+
"pt-BR": "Desenvolvimento",
264+
"ru-RU": "Разработка",
265+
"th-TH": "การพัฒนา",
266+
"tr-TR": "Geliştirme",
267+
"zh-CN": "开发",
268+
"zh-TW": "開發",
269+
},
117270
items: ["sdk", "server", "plugins", "ecosystem"],
118271
},
119272
],
120273
components: {
121274
Hero: "./src/components/Hero.astro",
122275
Head: "./src/components/Head.astro",
123276
Header: "./src/components/Header.astro",
277+
Footer: "./src/components/Footer.astro",
124278
SiteTitle: "./src/components/SiteTitle.astro",
125279
},
126280
plugins: [

packages/web/config.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default {
88
github: "https://github.com/anomalyco/opencode",
99
discord: "https://opencode.ai/discord",
1010
headerLinks: [
11-
{ name: "Home", url: "/" },
12-
{ name: "Docs", url: "/docs/" },
11+
{ name: "app.header.home", url: "/" },
12+
{ name: "app.header.docs", url: "/docs/" },
1313
],
1414
}

0 commit comments

Comments
 (0)