Skip to content

Commit b4902fd

Browse files
authored
Merge branch 'dev' into fix/lsp-error-message-improvement
2 parents 5b5b4a5 + 2d348da commit b4902fd

18 files changed

Lines changed: 2346 additions & 25 deletions

File tree

packages/app/src/context/language.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type Locale =
1818
| "ja"
1919
| "pl"
2020
| "ru"
21+
| "uk"
2122
| "ar"
2223
| "no"
2324
| "br"
@@ -45,6 +46,7 @@ const LOCALES: readonly Locale[] = [
4546
"ja",
4647
"pl",
4748
"ru",
49+
"uk",
4850
"bs",
4951
"ar",
5052
"no",
@@ -65,6 +67,7 @@ const INTL: Record<Locale, string> = {
6567
ja: "ja",
6668
pl: "pl",
6769
ru: "ru",
70+
uk: "uk",
6871
ar: "ar",
6972
no: "nb-NO",
7073
br: "pt-BR",
@@ -85,6 +88,7 @@ const LABEL_KEY: Record<Locale, keyof Dictionary> = {
8588
ja: "language.ja",
8689
pl: "language.pl",
8790
ru: "language.ru",
91+
uk: "language.uk",
8892
ar: "language.ar",
8993
no: "language.no",
9094
br: "language.br",
@@ -110,6 +114,7 @@ const loaders: Record<Exclude<Locale, "en">, () => Promise<Dictionary>> = {
110114
ja: () => merge(import("@/i18n/ja"), import("@opencode-ai/ui/i18n/ja")),
111115
pl: () => merge(import("@/i18n/pl"), import("@opencode-ai/ui/i18n/pl")),
112116
ru: () => merge(import("@/i18n/ru"), import("@opencode-ai/ui/i18n/ru")),
117+
uk: () => merge(import("@/i18n/uk"), import("@opencode-ai/ui/i18n/uk")),
113118
ar: () => merge(import("@/i18n/ar"), import("@opencode-ai/ui/i18n/ar")),
114119
no: () => merge(import("@/i18n/no"), import("@opencode-ai/ui/i18n/no")),
115120
br: () => merge(import("@/i18n/br"), import("@opencode-ai/ui/i18n/br")),
@@ -145,6 +150,7 @@ const localeMatchers: Array<{ locale: Locale; match: (language: string) => boole
145150
{ locale: "ja", match: (language) => language.startsWith("ja") },
146151
{ locale: "pl", match: (language) => language.startsWith("pl") },
147152
{ locale: "ru", match: (language) => language.startsWith("ru") },
153+
{ locale: "uk", match: (language) => language.startsWith("uk") },
148154
{ locale: "ar", match: (language) => language.startsWith("ar") },
149155
{
150156
locale: "no",

packages/app/src/i18n/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ export const dict = {
416416
"language.no": "Norsk",
417417
"language.br": "Português (Brasil)",
418418
"language.bs": "Bosanski",
419+
"language.uk": "Українська",
419420
"language.th": "ไทย",
420421
"language.tr": "Türkçe",
421422

packages/app/src/i18n/parity.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ import { dict as ko } from "./ko"
1212
import { dict as no } from "./no"
1313
import { dict as pl } from "./pl"
1414
import { dict as ru } from "./ru"
15+
import { dict as uk } from "./uk"
1516
import { dict as th } from "./th"
1617
import { dict as zh } from "./zh"
1718
import { dict as zht } from "./zht"
1819
import { dict as tr } from "./tr"
1920

20-
const locales = [ar, br, bs, da, de, es, fr, ja, ko, no, pl, ru, th, tr, zh, zht]
21+
const locales = [ar, br, bs, da, de, es, fr, ja, ko, no, pl, ru, uk, th, tr, zh, zht]
2122
const keys = ["command.session.previous.unseen", "command.session.next.unseen"] as const
2223

2324
describe("i18n parity", () => {

packages/app/src/i18n/uk.ts

Lines changed: 970 additions & 0 deletions
Large diffs are not rendered by default.

packages/console/app/src/i18n/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { dict as da } from "~/i18n/da"
1111
import { dict as ja } from "~/i18n/ja"
1212
import { dict as pl } from "~/i18n/pl"
1313
import { dict as ru } from "~/i18n/ru"
14+
import { dict as uk } from "~/i18n/uk"
1415
import { dict as ar } from "~/i18n/ar"
1516
import { dict as no } from "~/i18n/no"
1617
import { dict as br } from "~/i18n/br"
@@ -35,6 +36,7 @@ export function i18n(locale: Locale): Dict {
3536
if (locale === "ja") return { ...base, ...ja }
3637
if (locale === "pl") return { ...base, ...pl }
3738
if (locale === "ru") return { ...base, ...ru }
39+
if (locale === "uk") return { ...base, ...uk }
3840
if (locale === "ar") return { ...base, ...ar }
3941
if (locale === "no") return { ...base, ...no }
4042
if (locale === "br") return { ...base, ...br }

packages/console/app/src/i18n/uk.ts

Lines changed: 785 additions & 0 deletions
Large diffs are not rendered by default.

packages/console/app/src/lib/language.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const LOCALES = [
1111
"ja",
1212
"pl",
1313
"ru",
14+
"uk",
1415
"ar",
1516
"no",
1617
"br",
@@ -41,6 +42,7 @@ const LABEL = {
4142
ja: "日本語",
4243
pl: "Polski",
4344
ru: "Русский",
45+
uk: "Українська",
4446
ar: "العربية",
4547
no: "Norsk",
4648
br: "Português (Brasil)",
@@ -61,6 +63,7 @@ const TAG = {
6163
ja: "ja",
6264
pl: "pl",
6365
ru: "ru",
66+
uk: "uk",
6467
ar: "ar",
6568
no: "no",
6669
br: "pt-BR",
@@ -81,6 +84,7 @@ const DOCS = {
8184
ja: "ja",
8285
pl: "pl",
8386
ru: "ru",
87+
uk: "uk",
8488
ar: "ar",
8589
no: "nb",
8690
br: "pt-br",
@@ -104,6 +108,7 @@ const DOCS_SEGMENT = new Set([
104108
"ru",
105109
"th",
106110
"tr",
111+
"uk",
107112
"zh-cn",
108113
"zh-tw",
109114
])
@@ -124,6 +129,7 @@ const DOCS_LOCALE = {
124129
ru: "ru",
125130
th: "th",
126131
tr: "tr",
132+
uk: "uk",
127133
"zh-cn": "zh",
128134
"zh-tw": "zht",
129135
} as const satisfies Record<string, Locale>
@@ -239,6 +245,7 @@ function match(input: string): Locale | null {
239245
if (value.startsWith("ja")) return "ja"
240246
if (value.startsWith("pl")) return "pl"
241247
if (value.startsWith("ru")) return "ru"
248+
if (value.startsWith("uk")) return "uk"
242249
if (value.startsWith("ar")) return "ar"
243250
if (value.startsWith("tr")) return "tr"
244251
if (value.startsWith("th")) return "th"

packages/desktop/src/renderer/i18n/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { dict as desktopDa } from "./da"
1111
import { dict as desktopJa } from "./ja"
1212
import { dict as desktopPl } from "./pl"
1313
import { dict as desktopRu } from "./ru"
14+
import { dict as desktopUk } from "./uk"
1415
import { dict as desktopAr } from "./ar"
1516
import { dict as desktopNo } from "./no"
1617
import { dict as desktopBr } from "./br"
@@ -27,6 +28,7 @@ import { dict as appDa } from "../../../../app/src/i18n/da"
2728
import { dict as appJa } from "../../../../app/src/i18n/ja"
2829
import { dict as appPl } from "../../../../app/src/i18n/pl"
2930
import { dict as appRu } from "../../../../app/src/i18n/ru"
31+
import { dict as appUk } from "../../../../app/src/i18n/uk"
3032
import { dict as appAr } from "../../../../app/src/i18n/ar"
3133
import { dict as appNo } from "../../../../app/src/i18n/no"
3234
import { dict as appBr } from "../../../../app/src/i18n/br"
@@ -44,6 +46,7 @@ export type Locale =
4446
| "ja"
4547
| "pl"
4648
| "ru"
49+
| "uk"
4750
| "ar"
4851
| "no"
4952
| "br"
@@ -64,6 +67,7 @@ const LOCALES: readonly Locale[] = [
6467
"ja",
6568
"pl",
6669
"ru",
70+
"uk",
6771
"bs",
6872
"ar",
6973
"no",
@@ -89,6 +93,7 @@ function detectLocale(): Locale {
8993
if (language.toLowerCase().startsWith("ja")) return "ja"
9094
if (language.toLowerCase().startsWith("pl")) return "pl"
9195
if (language.toLowerCase().startsWith("ru")) return "ru"
96+
if (language.toLowerCase().startsWith("uk")) return "uk"
9297
if (language.toLowerCase().startsWith("ar")) return "ar"
9398
if (
9499
language.toLowerCase().startsWith("no") ||
@@ -148,6 +153,7 @@ function build(locale: Locale): Dictionary {
148153
if (locale === "ja") return { ...base, ...i18n.flatten(appJa), ...i18n.flatten(desktopJa) }
149154
if (locale === "pl") return { ...base, ...i18n.flatten(appPl), ...i18n.flatten(desktopPl) }
150155
if (locale === "ru") return { ...base, ...i18n.flatten(appRu), ...i18n.flatten(desktopRu) }
156+
if (locale === "uk") return { ...base, ...i18n.flatten(appUk), ...i18n.flatten(desktopUk) }
151157
if (locale === "ar") return { ...base, ...i18n.flatten(appAr), ...i18n.flatten(desktopAr) }
152158
if (locale === "no") return { ...base, ...i18n.flatten(appNo), ...i18n.flatten(desktopNo) }
153159
if (locale === "br") return { ...base, ...i18n.flatten(appBr), ...i18n.flatten(desktopBr) }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export const dict = {
2+
"desktop.menu.checkForUpdates": "Перевірити оновлення...",
3+
"desktop.menu.installCli": "Встановити CLI...",
4+
"desktop.menu.reloadWebview": "Перезавантажити Webview",
5+
"desktop.menu.restart": "Перезапустити",
6+
7+
"desktop.dialog.chooseFolder": "Виберіть теку",
8+
"desktop.dialog.chooseFile": "Виберіть файл",
9+
"desktop.dialog.saveFile": "Зберегти файл",
10+
11+
"desktop.updater.checkFailed.title": "Не вдалося перевірити оновлення",
12+
"desktop.updater.checkFailed.message": "Не вдалося перевірити наявність оновлень",
13+
"desktop.updater.none.title": "Немає доступних оновлень",
14+
"desktop.updater.none.message": "Ви вже використовуєте найновішу версію OpenCode",
15+
"desktop.updater.downloadFailed.title": "Помилка оновлення",
16+
"desktop.updater.downloadFailed.message": "Не вдалося завантажити оновлення",
17+
"desktop.updater.downloaded.title": "Оновлення завантажено",
18+
"desktop.updater.downloaded.prompt":
19+
"Версію {{version}} OpenCode завантажено. Бажаєте встановити її та перезапустити?",
20+
"desktop.updater.installFailed.title": "Помилка оновлення",
21+
"desktop.updater.installFailed.message": "Не вдалося встановити оновлення",
22+
23+
"desktop.cli.installed.title": "CLI встановлено",
24+
"desktop.cli.installed.message":
25+
"CLI встановлено до {{path}}\n\nПерезапустіть термінал, щоб використовувати команду 'opencode'.",
26+
"desktop.cli.failed.title": "Не вдалося встановити",
27+
"desktop.cli.failed.message": "Не вдалося встановити CLI: {{error}}",
28+
}

packages/opencode/src/server/routes/instance/httpapi/errors.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,127 @@
11
import { Schema } from "effect"
22

3+
export class InvalidRequestError extends Schema.TaggedErrorClass<InvalidRequestError>()(
4+
"InvalidRequestError",
5+
{
6+
message: Schema.String,
7+
kind: Schema.optional(Schema.String),
8+
field: Schema.optional(Schema.String),
9+
},
10+
{ httpApiStatus: 400 },
11+
) {}
12+
13+
export class UnauthorizedError extends Schema.TaggedErrorClass<UnauthorizedError>()(
14+
"UnauthorizedError",
15+
{ message: Schema.String },
16+
{ httpApiStatus: 401 },
17+
) {}
18+
19+
export class ForbiddenError extends Schema.TaggedErrorClass<ForbiddenError>()(
20+
"ForbiddenError",
21+
{ message: Schema.String },
22+
{ httpApiStatus: 403 },
23+
) {}
24+
25+
export class ConflictError extends Schema.TaggedErrorClass<ConflictError>()(
26+
"ConflictError",
27+
{
28+
message: Schema.String,
29+
resource: Schema.optional(Schema.String),
30+
},
31+
{ httpApiStatus: 409 },
32+
) {}
33+
34+
export class UpstreamError extends Schema.TaggedErrorClass<UpstreamError>()(
35+
"UpstreamError",
36+
{
37+
message: Schema.String,
38+
service: Schema.optional(Schema.String),
39+
status: Schema.optional(Schema.Number),
40+
},
41+
{ httpApiStatus: 502 },
42+
) {}
43+
44+
export class ServiceUnavailableError extends Schema.TaggedErrorClass<ServiceUnavailableError>()(
45+
"ServiceUnavailableError",
46+
{
47+
message: Schema.String,
48+
service: Schema.optional(Schema.String),
49+
},
50+
{ httpApiStatus: 503 },
51+
) {}
52+
53+
export class TimeoutError extends Schema.TaggedErrorClass<TimeoutError>()(
54+
"TimeoutError",
55+
{
56+
message: Schema.String,
57+
operation: Schema.optional(Schema.String),
58+
},
59+
{ httpApiStatus: 504 },
60+
) {}
61+
62+
export class UnknownError extends Schema.TaggedErrorClass<UnknownError>()(
63+
"UnknownError",
64+
{
65+
message: Schema.String,
66+
ref: Schema.optional(Schema.String),
67+
},
68+
{ httpApiStatus: 500 },
69+
) {}
70+
71+
export class ProviderNotFoundError extends Schema.TaggedErrorClass<ProviderNotFoundError>()(
72+
"ProviderNotFoundError",
73+
{
74+
providerID: Schema.String,
75+
message: Schema.String,
76+
},
77+
{ httpApiStatus: 404 },
78+
) {}
79+
80+
export class ModelNotFoundError extends Schema.TaggedErrorClass<ModelNotFoundError>()(
81+
"ModelNotFoundError",
82+
{
83+
providerID: Schema.String,
84+
modelID: Schema.String,
85+
suggestions: Schema.Array(Schema.String),
86+
message: Schema.String,
87+
},
88+
{ httpApiStatus: 404 },
89+
) {}
90+
91+
export class SessionNotFoundError extends Schema.TaggedErrorClass<SessionNotFoundError>()(
92+
"SessionNotFoundError",
93+
{
94+
sessionID: Schema.String,
95+
message: Schema.String,
96+
},
97+
{ httpApiStatus: 404 },
98+
) {}
99+
100+
export class MessageNotFoundError extends Schema.TaggedErrorClass<MessageNotFoundError>()(
101+
"MessageNotFoundError",
102+
{
103+
sessionID: Schema.String,
104+
messageID: Schema.String,
105+
message: Schema.String,
106+
},
107+
{ httpApiStatus: 404 },
108+
) {}
109+
110+
export class InvalidCursorError extends Schema.TaggedErrorClass<InvalidCursorError>()(
111+
"InvalidCursorError",
112+
{ message: Schema.String },
113+
{ httpApiStatus: 400 },
114+
) {}
115+
116+
export class SessionBusyError extends Schema.TaggedErrorClass<SessionBusyError>()(
117+
"SessionBusyError",
118+
{
119+
sessionID: Schema.String,
120+
message: Schema.String,
121+
},
122+
{ httpApiStatus: 409 },
123+
) {}
124+
3125
export class ApiNotFoundError extends Schema.ErrorClass<ApiNotFoundError>("NotFoundError")(
4126
{
5127
name: Schema.Literal("NotFoundError"),

0 commit comments

Comments
 (0)