From 5e5823ed85ff83e1e3461b861fb582f27cc38969 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Wed, 25 Feb 2026 14:26:38 +0000 Subject: [PATCH 01/23] chore: generate --- packages/sdk/openapi.json | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 2741c2362ec..80a4a8d72ae 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -2630,6 +2630,76 @@ "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.message({\n ...\n})" } ] + }, + "delete": { + "operationId": "session.deleteMessage", + "parameters": [ + { + "in": "query", + "name": "directory", + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "sessionID", + "schema": { + "type": "string" + }, + "required": true, + "description": "Session ID" + }, + { + "in": "path", + "name": "messageID", + "schema": { + "type": "string" + }, + "required": true, + "description": "Message ID" + } + ], + "summary": "Delete message", + "description": "Permanently delete a specific message (and all of its parts) from a session. This does not revert any file changes that may have been made while processing the message.", + "responses": { + "200": { + "description": "Successfully deleted message", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestError" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundError" + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.deleteMessage({\n ...\n})" + } + ] } }, "/session/{sessionID}/message/{messageID}/part/{partID}": { From e48c1ccf0714a2a78a8bbf27e8ade0b8bcbdcf3b Mon Sep 17 00:00:00 2001 From: Ryan Vogel Date: Wed, 25 Feb 2026 09:42:52 -0500 Subject: [PATCH 02/23] chore(workflows): label vouched users and restrict vouch managers (#15075) --- .github/workflows/vouch-check-issue.yml | 58 ++++++++++++++------- .github/workflows/vouch-check-pr.yml | 55 +++++++++++++------ .github/workflows/vouch-manage-by-issue.yml | 1 + 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/.github/workflows/vouch-check-issue.yml b/.github/workflows/vouch-check-issue.yml index 94569f47312..4c2aa960b2a 100644 --- a/.github/workflows/vouch-check-issue.yml +++ b/.github/workflows/vouch-check-issue.yml @@ -42,15 +42,17 @@ jobs: throw error; } - // Parse the .td file for denounced users + // Parse the .td file for vouched and denounced users + const vouched = new Set(); const denounced = new Map(); for (const line of content.split('\n')) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; - if (!trimmed.startsWith('-')) continue; - const rest = trimmed.slice(1).trim(); + const isDenounced = trimmed.startsWith('-'); + const rest = isDenounced ? trimmed.slice(1).trim() : trimmed; if (!rest) continue; + const spaceIdx = rest.indexOf(' '); const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx); const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim(); @@ -65,32 +67,50 @@ jobs: const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1); if (!username) continue; - denounced.set(username.toLowerCase(), reason); + if (isDenounced) { + denounced.set(username.toLowerCase(), reason); + continue; + } + + vouched.add(username.toLowerCase()); } // Check if the author is denounced const reason = denounced.get(author.toLowerCase()); - if (reason === undefined) { - core.info(`User ${author} is not denounced. Allowing issue.`); + if (reason !== undefined) { + // Author is denounced — close the issue + const body = 'This issue has been automatically closed.'; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body, + }); + + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + state: 'closed', + state_reason: 'not_planned', + }); + + core.info(`Closed issue #${issueNumber} from denounced user ${author}`); return; } - // Author is denounced — close the issue - const body = 'This issue has been automatically closed.'; + // Author is positively vouched — add label + if (!vouched.has(author.toLowerCase())) { + core.info(`User ${author} is not denounced or vouched. Allowing issue.`); + return; + } - await github.rest.issues.createComment({ + await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNumber, - body, + labels: ['Vouched'], }); - await github.rest.issues.update({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issueNumber, - state: 'closed', - state_reason: 'not_planned', - }); - - core.info(`Closed issue #${issueNumber} from denounced user ${author}`); + core.info(`Added vouched label to issue #${issueNumber} from ${author}`); diff --git a/.github/workflows/vouch-check-pr.yml b/.github/workflows/vouch-check-pr.yml index 470b8e0a5ad..51816dfb759 100644 --- a/.github/workflows/vouch-check-pr.yml +++ b/.github/workflows/vouch-check-pr.yml @@ -6,6 +6,7 @@ on: permissions: contents: read + issues: write pull-requests: write jobs: @@ -42,15 +43,17 @@ jobs: throw error; } - // Parse the .td file for denounced users + // Parse the .td file for vouched and denounced users + const vouched = new Set(); const denounced = new Map(); for (const line of content.split('\n')) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; - if (!trimmed.startsWith('-')) continue; - const rest = trimmed.slice(1).trim(); + const isDenounced = trimmed.startsWith('-'); + const rest = isDenounced ? trimmed.slice(1).trim() : trimmed; if (!rest) continue; + const spaceIdx = rest.indexOf(' '); const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx); const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim(); @@ -65,29 +68,47 @@ jobs: const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1); if (!username) continue; - denounced.set(username.toLowerCase(), reason); + if (isDenounced) { + denounced.set(username.toLowerCase(), reason); + continue; + } + + vouched.add(username.toLowerCase()); } // Check if the author is denounced const reason = denounced.get(author.toLowerCase()); - if (reason === undefined) { - core.info(`User ${author} is not denounced. Allowing PR.`); + if (reason !== undefined) { + // Author is denounced — close the PR + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: 'This pull request has been automatically closed.', + }); + + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + state: 'closed', + }); + + core.info(`Closed PR #${prNumber} from denounced user ${author}`); return; } - // Author is denounced — close the PR - await github.rest.issues.createComment({ + // Author is positively vouched — add label + if (!vouched.has(author.toLowerCase())) { + core.info(`User ${author} is not denounced or vouched. Allowing PR.`); + return; + } + + await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, - body: 'This pull request has been automatically closed.', + labels: ['Vouched'], }); - await github.rest.pulls.update({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: prNumber, - state: 'closed', - }); - - core.info(`Closed PR #${prNumber} from denounced user ${author}`); + core.info(`Added vouched label to PR #${prNumber} from ${author}`); diff --git a/.github/workflows/vouch-manage-by-issue.yml b/.github/workflows/vouch-manage-by-issue.yml index cf0524c21a8..9604bf87f37 100644 --- a/.github/workflows/vouch-manage-by-issue.yml +++ b/.github/workflows/vouch-manage-by-issue.yml @@ -33,5 +33,6 @@ jobs: with: issue-id: ${{ github.event.issue.number }} comment-id: ${{ github.event.comment.id }} + roles: admin,maintain env: GITHUB_TOKEN: ${{ steps.committer.outputs.token }} From 286992269623bcb410f0de89e128ff14361d5e97 Mon Sep 17 00:00:00 2001 From: Oleksii Pavliuk <71220725+Oleksii-Pavliuk@users.noreply.github.com> Date: Thu, 26 Feb 2026 01:54:15 +1100 Subject: [PATCH 03/23] fix(app): correct Copilot provider description in i18n files (#15071) --- packages/app/src/i18n/bs.ts | 2 +- packages/app/src/i18n/da.ts | 2 +- packages/app/src/i18n/en.ts | 2 +- packages/app/src/i18n/es.ts | 2 +- packages/app/src/i18n/no.ts | 2 +- packages/app/src/i18n/pl.ts | 2 +- packages/app/src/i18n/ru.ts | 2 +- packages/app/src/i18n/th.ts | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index d658926268e..cb0274042ed 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "Preporučeno", "dialog.provider.opencode.note": "Kurirani modeli uključujući Claude, GPT, Gemini i druge", "dialog.provider.anthropic.note": "Direktan pristup Claude modelima, uključujući Pro i Max", - "dialog.provider.copilot.note": "Claude modeli za pomoć pri kodiranju", + "dialog.provider.copilot.note": "AI modeli za pomoć pri kodiranju putem GitHub Copilot", "dialog.provider.openai.note": "GPT modeli za brze, sposobne opšte AI zadatke", "dialog.provider.google.note": "Gemini modeli za brze, strukturirane odgovore", "dialog.provider.openrouter.note": "Pristup svim podržanim modelima preko jednog provajdera", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index fabefcab756..30cc555eb1a 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "Anbefalet", "dialog.provider.opencode.note": "Udvalgte modeller inklusive Claude, GPT, Gemini og flere", "dialog.provider.anthropic.note": "Direkte adgang til Claude-modeller, inklusive Pro og Max", - "dialog.provider.copilot.note": "Claude-modeller til kodningsassistance", + "dialog.provider.copilot.note": "AI-modeller til kodningsassistance via GitHub Copilot", "dialog.provider.openai.note": "GPT-modeller til hurtige, kompetente generelle AI-opgaver", "dialog.provider.google.note": "Gemini-modeller til hurtige, strukturerede svar", "dialog.provider.openrouter.note": "Få adgang til alle understøttede modeller fra én udbyder", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index 992509fcfa4..0b4388ceb19 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "Recommended", "dialog.provider.opencode.note": "Curated models including Claude, GPT, Gemini and more", "dialog.provider.anthropic.note": "Direct access to Claude models, including Pro and Max", - "dialog.provider.copilot.note": "Claude models for coding assistance", + "dialog.provider.copilot.note": "AI models for coding assistance via GitHub Copilot", "dialog.provider.openai.note": "GPT models for fast, capable general AI tasks", "dialog.provider.google.note": "Gemini models for fast, structured responses", "dialog.provider.openrouter.note": "Access all supported models from one provider", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index b55d54c0ca5..3566226d7bf 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "Recomendado", "dialog.provider.opencode.note": "Modelos seleccionados incluyendo Claude, GPT, Gemini y más", "dialog.provider.anthropic.note": "Acceso directo a modelos Claude, incluyendo Pro y Max", - "dialog.provider.copilot.note": "Modelos Claude para asistencia de codificación", + "dialog.provider.copilot.note": "Modelos de IA para asistencia de codificación a través de GitHub Copilot", "dialog.provider.openai.note": "Modelos GPT para tareas de IA generales rápidas y capaces", "dialog.provider.google.note": "Modelos Gemini para respuestas rápidas y estructuradas", "dialog.provider.openrouter.note": "Accede a todos los modelos soportados desde un solo proveedor", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 8e1b1ce629d..3fbe75716d0 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -103,7 +103,7 @@ export const dict = { "dialog.provider.tag.recommended": "Anbefalt", "dialog.provider.opencode.note": "Utvalgte modeller inkludert Claude, GPT, Gemini og mer", "dialog.provider.anthropic.note": "Direkte tilgang til Claude-modeller, inkludert Pro og Max", - "dialog.provider.copilot.note": "Claude-modeller for kodeassistanse", + "dialog.provider.copilot.note": "AI-modeller for kodeassistanse via GitHub Copilot", "dialog.provider.openai.note": "GPT-modeller for raske, dyktige generelle AI-oppgaver", "dialog.provider.google.note": "Gemini-modeller for raske, strukturerte svar", "dialog.provider.openrouter.note": "Tilgang til alle støttede modeller fra én leverandør", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index 9b924fd642e..d8ae150d7cb 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -92,7 +92,7 @@ export const dict = { "dialog.provider.tag.recommended": "Zalecane", "dialog.provider.opencode.note": "Wyselekcjonowane modele, w tym Claude, GPT, Gemini i inne", "dialog.provider.anthropic.note": "Bezpośredni dostęp do modeli Claude, w tym Pro i Max", - "dialog.provider.copilot.note": "Modele Claude do pomocy w kodowaniu", + "dialog.provider.copilot.note": "Modele AI do pomocy w kodowaniu przez GitHub Copilot", "dialog.provider.openai.note": "Modele GPT do szybkich i wszechstronnych zadań AI", "dialog.provider.google.note": "Modele Gemini do szybkich i ustrukturyzowanych odpowiedzi", "dialog.provider.openrouter.note": "Dostęp do wszystkich obsługiwanych modeli od jednego dostawcy", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index cf02285821e..a7d328924a4 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "Рекомендуемые", "dialog.provider.opencode.note": "Отобранные модели, включая Claude, GPT, Gemini и другие", "dialog.provider.anthropic.note": "Прямой доступ к моделям Claude, включая Pro и Max", - "dialog.provider.copilot.note": "Модели Claude для помощи в кодировании", + "dialog.provider.copilot.note": "ИИ-модели для помощи в кодировании через GitHub Copilot", "dialog.provider.openai.note": "Модели GPT для быстрых и мощных задач общего ИИ", "dialog.provider.google.note": "Модели Gemini для быстрых и структурированных ответов", "dialog.provider.openrouter.note": "Доступ ко всем поддерживаемым моделям через одного провайдера", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 1b8abe953b7..1e9773bf021 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -100,7 +100,7 @@ export const dict = { "dialog.provider.tag.recommended": "แนะนำ", "dialog.provider.opencode.note": "โมเดลที่คัดสรร รวมถึง Claude, GPT, Gemini และอื่น ๆ", "dialog.provider.anthropic.note": "เข้าถึงโมเดล Claude โดยตรง รวมถึง Pro และ Max", - "dialog.provider.copilot.note": "โมเดล Claude สำหรับการช่วยเหลือในการเขียนโค้ด", + "dialog.provider.copilot.note": "โมเดล AI สำหรับการช่วยเหลือในการเขียนโค้ดผ่าน GitHub Copilot", "dialog.provider.openai.note": "โมเดล GPT สำหรับงาน AI ทั่วไปที่รวดเร็วและมีความสามารถ", "dialog.provider.google.note": "โมเดล Gemini สำหรับการตอบสนองที่รวดเร็วและมีโครงสร้าง", "dialog.provider.openrouter.note": "เข้าถึงโมเดลที่รองรับทั้งหมดจากผู้ให้บริการเดียว", From 45191ad144f6546c051fb3a94f9f3cb1e2c00ed3 Mon Sep 17 00:00:00 2001 From: Filip <34747899+neriousy@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:57:13 +0100 Subject: [PATCH 04/23] fix(app): keyboard navigation previous/next message (#15047) --- packages/app/src/pages/session.tsx | 11 ++++++----- packages/app/src/pages/session/message-timeline.tsx | 1 + .../app/src/pages/session/use-session-hash-scroll.ts | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index e0ef92682d9..2e440a6b036 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -254,12 +254,13 @@ export default function Page() { const msgs = visibleUserMessages() if (msgs.length === 0) return - const current = activeMessage() - const currentIndex = current ? msgs.findIndex((m) => m.id === current.id) : -1 - const targetIndex = currentIndex === -1 ? (offset > 0 ? 0 : msgs.length - 1) : currentIndex + offset - if (targetIndex < 0 || targetIndex >= msgs.length) return + const current = store.messageId + const base = current ? msgs.findIndex((m) => m.id === current) : msgs.length + const currentIndex = base === -1 ? msgs.length : base + const targetIndex = currentIndex + offset + if (targetIndex < 0 || targetIndex > msgs.length) return - if (targetIndex === msgs.length - 1) { + if (targetIndex === msgs.length) { resumeScroll() return } diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index 615d1a0bea4..b8410903550 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -376,6 +376,7 @@ export function MessageTimeline(props: { >
Date: Fri, 20 Feb 2026 01:46:21 +0000 Subject: [PATCH 05/23] tweak(ui): keep reasoning inline code subdued in dark mode --- packages/ui/src/components/message-part.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index ce76d8e1887..f063076e079 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -252,6 +252,12 @@ } } +@media (prefers-color-scheme: dark) { + [data-component="reasoning-part"] [data-component="markdown"] :not(pre) > code { + opacity: 0.6; + } +} + [data-component="tool-error"] { display: flex; align-items: start; From b368181ac90b0365af535b3d0bd8284c2032240c Mon Sep 17 00:00:00 2001 From: adamelmore <2363879+adamdottv@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:29:02 -0600 Subject: [PATCH 06/23] chore: move glossary --- .github/workflows/docs-locale-sync.yml | 8 ++++---- .opencode/agent/translator.md | 2 +- .opencode/{agent => }/glossary/README.md | 0 .opencode/{agent => }/glossary/ar.md | 0 .opencode/{agent => }/glossary/br.md | 0 .opencode/{agent => }/glossary/bs.md | 0 .opencode/{agent => }/glossary/da.md | 0 .opencode/{agent => }/glossary/de.md | 0 .opencode/{agent => }/glossary/es.md | 0 .opencode/{agent => }/glossary/fr.md | 0 .opencode/{agent => }/glossary/ja.md | 0 .opencode/{agent => }/glossary/ko.md | 0 .opencode/{agent => }/glossary/no.md | 0 .opencode/{agent => }/glossary/pl.md | 0 .opencode/{agent => }/glossary/ru.md | 0 .opencode/{agent => }/glossary/th.md | 0 .opencode/{agent => }/glossary/zh-cn.md | 0 .opencode/{agent => }/glossary/zh-tw.md | 0 18 files changed, 5 insertions(+), 5 deletions(-) rename .opencode/{agent => }/glossary/README.md (100%) rename .opencode/{agent => }/glossary/ar.md (100%) rename .opencode/{agent => }/glossary/br.md (100%) rename .opencode/{agent => }/glossary/bs.md (100%) rename .opencode/{agent => }/glossary/da.md (100%) rename .opencode/{agent => }/glossary/de.md (100%) rename .opencode/{agent => }/glossary/es.md (100%) rename .opencode/{agent => }/glossary/fr.md (100%) rename .opencode/{agent => }/glossary/ja.md (100%) rename .opencode/{agent => }/glossary/ko.md (100%) rename .opencode/{agent => }/glossary/no.md (100%) rename .opencode/{agent => }/glossary/pl.md (100%) rename .opencode/{agent => }/glossary/ru.md (100%) rename .opencode/{agent => }/glossary/th.md (100%) rename .opencode/{agent => }/glossary/zh-cn.md (100%) rename .opencode/{agent => }/glossary/zh-tw.md (100%) diff --git a/.github/workflows/docs-locale-sync.yml b/.github/workflows/docs-locale-sync.yml index 1aafc5d1e3b..f62afae4b9f 100644 --- a/.github/workflows/docs-locale-sync.yml +++ b/.github/workflows/docs-locale-sync.yml @@ -65,9 +65,9 @@ jobs: "packages/web/src/content/docs/*/*.mdx": "allow", ".opencode": "allow", ".opencode/agent": "allow", - ".opencode/agent/glossary": "allow", + ".opencode/glossary": "allow", ".opencode/agent/translator.md": "allow", - ".opencode/agent/glossary/*.md": "allow" + ".opencode/glossary/*.md": "allow" }, "edit": { "*": "deny", @@ -76,7 +76,7 @@ jobs: "glob": { "*": "deny", "packages/web/src/content/docs*": "allow", - ".opencode/agent/glossary*": "allow" + ".opencode/glossary*": "allow" }, "task": { "*": "deny", @@ -90,7 +90,7 @@ jobs: "read": { "*": "deny", ".opencode/agent/translator.md": "allow", - ".opencode/agent/glossary/*.md": "allow" + ".opencode/glossary/*.md": "allow" } } } diff --git a/.opencode/agent/translator.md b/.opencode/agent/translator.md index f0b3f8e9270..6ef6d0847a3 100644 --- a/.opencode/agent/translator.md +++ b/.opencode/agent/translator.md @@ -13,7 +13,7 @@ Requirements: - Preserve meaning, intent, tone, and formatting (including Markdown/MDX structure). - Preserve all technical terms and artifacts exactly: product/company names, API names, identifiers, code, commands/flags, file paths, URLs, versions, error messages, config keys/values, and anything inside inline code or code blocks. - Also preserve every term listed in the Do-Not-Translate glossary below. -- Also apply locale-specific guidance from `.opencode/agent/glossary/.md` when available (for example, `zh-cn.md`). +- Also apply locale-specific guidance from `.opencode/glossary/.md` when available (for example, `zh-cn.md`). - Do not modify fenced code blocks. - Output ONLY the translation (no commentary). diff --git a/.opencode/agent/glossary/README.md b/.opencode/glossary/README.md similarity index 100% rename from .opencode/agent/glossary/README.md rename to .opencode/glossary/README.md diff --git a/.opencode/agent/glossary/ar.md b/.opencode/glossary/ar.md similarity index 100% rename from .opencode/agent/glossary/ar.md rename to .opencode/glossary/ar.md diff --git a/.opencode/agent/glossary/br.md b/.opencode/glossary/br.md similarity index 100% rename from .opencode/agent/glossary/br.md rename to .opencode/glossary/br.md diff --git a/.opencode/agent/glossary/bs.md b/.opencode/glossary/bs.md similarity index 100% rename from .opencode/agent/glossary/bs.md rename to .opencode/glossary/bs.md diff --git a/.opencode/agent/glossary/da.md b/.opencode/glossary/da.md similarity index 100% rename from .opencode/agent/glossary/da.md rename to .opencode/glossary/da.md diff --git a/.opencode/agent/glossary/de.md b/.opencode/glossary/de.md similarity index 100% rename from .opencode/agent/glossary/de.md rename to .opencode/glossary/de.md diff --git a/.opencode/agent/glossary/es.md b/.opencode/glossary/es.md similarity index 100% rename from .opencode/agent/glossary/es.md rename to .opencode/glossary/es.md diff --git a/.opencode/agent/glossary/fr.md b/.opencode/glossary/fr.md similarity index 100% rename from .opencode/agent/glossary/fr.md rename to .opencode/glossary/fr.md diff --git a/.opencode/agent/glossary/ja.md b/.opencode/glossary/ja.md similarity index 100% rename from .opencode/agent/glossary/ja.md rename to .opencode/glossary/ja.md diff --git a/.opencode/agent/glossary/ko.md b/.opencode/glossary/ko.md similarity index 100% rename from .opencode/agent/glossary/ko.md rename to .opencode/glossary/ko.md diff --git a/.opencode/agent/glossary/no.md b/.opencode/glossary/no.md similarity index 100% rename from .opencode/agent/glossary/no.md rename to .opencode/glossary/no.md diff --git a/.opencode/agent/glossary/pl.md b/.opencode/glossary/pl.md similarity index 100% rename from .opencode/agent/glossary/pl.md rename to .opencode/glossary/pl.md diff --git a/.opencode/agent/glossary/ru.md b/.opencode/glossary/ru.md similarity index 100% rename from .opencode/agent/glossary/ru.md rename to .opencode/glossary/ru.md diff --git a/.opencode/agent/glossary/th.md b/.opencode/glossary/th.md similarity index 100% rename from .opencode/agent/glossary/th.md rename to .opencode/glossary/th.md diff --git a/.opencode/agent/glossary/zh-cn.md b/.opencode/glossary/zh-cn.md similarity index 100% rename from .opencode/agent/glossary/zh-cn.md rename to .opencode/glossary/zh-cn.md diff --git a/.opencode/agent/glossary/zh-tw.md b/.opencode/glossary/zh-tw.md similarity index 100% rename from .opencode/agent/glossary/zh-tw.md rename to .opencode/glossary/zh-tw.md From 1172fa418e9aa5e0fcfccea326c6c9d35e1d57fd Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 25 Feb 2026 12:39:48 -0500 Subject: [PATCH 07/23] wip: zen go --- infra/console.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/console.ts b/infra/console.ts index 283fe2c37ca..de72cb072ee 100644 --- a/infra/console.ts +++ b/infra/console.ts @@ -101,7 +101,7 @@ export const stripeWebhook = new stripe.WebhookEndpoint("StripeWebhookEndpoint", }) const zenLiteProduct = new stripe.Product("ZenLite", { - name: "OpenCode Lite", + name: "OpenCode Go", }) const zenLitePrice = new stripe.Price("ZenLitePrice", { product: zenLiteProduct.id, From 9d29d692c6d93322f5894cca4232d80106e7c81a Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 25 Feb 2026 23:53:09 +0100 Subject: [PATCH 08/23] split tui/server config (#13968) --- packages/console/app/package.json | 2 +- packages/opencode/script/schema.ts | 88 +-- packages/opencode/src/cli/cmd/tui/app.tsx | 63 ++- packages/opencode/src/cli/cmd/tui/attach.ts | 8 + .../cli/cmd/tui/component/dialog-command.tsx | 5 +- .../src/cli/cmd/tui/component/tips.tsx | 8 +- .../src/cli/cmd/tui/context/keybind.tsx | 16 +- .../src/cli/cmd/tui/context/theme.tsx | 8 +- .../src/cli/cmd/tui/context/tui-config.tsx | 9 + .../src/cli/cmd/tui/routes/session/index.tsx | 10 +- .../cli/cmd/tui/routes/session/permission.tsx | 5 +- packages/opencode/src/cli/cmd/tui/thread.ts | 8 + packages/opencode/src/config/config.ts | 182 ++----- .../opencode/src/config/migrate-tui-config.ts | 155 ++++++ packages/opencode/src/config/paths.ts | 174 ++++++ packages/opencode/src/config/tui-schema.ts | 34 ++ packages/opencode/src/config/tui.ts | 118 ++++ packages/opencode/src/flag/flag.ts | 12 + packages/opencode/test/config/config.test.ts | 54 +- packages/opencode/test/config/tui.test.ts | 510 ++++++++++++++++++ packages/sdk/js/src/v2/gen/types.gen.ts | 409 -------------- packages/web/astro.config.mjs | 2 +- packages/web/src/content/docs/cli.mdx | 1 + packages/web/src/content/docs/config.mdx | 57 +- packages/web/src/content/docs/keybinds.mdx | 12 +- packages/web/src/content/docs/themes.mdx | 6 +- packages/web/src/content/docs/tui.mdx | 32 +- 27 files changed, 1283 insertions(+), 705 deletions(-) create mode 100644 packages/opencode/src/cli/cmd/tui/context/tui-config.tsx create mode 100644 packages/opencode/src/config/migrate-tui-config.ts create mode 100644 packages/opencode/src/config/paths.ts create mode 100644 packages/opencode/src/config/tui-schema.ts create mode 100644 packages/opencode/src/config/tui.ts create mode 100644 packages/opencode/test/config/tui.test.ts diff --git a/packages/console/app/package.json b/packages/console/app/package.json index adf2d2d28da..05d2309a423 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -7,7 +7,7 @@ "typecheck": "tsgo --noEmit", "dev": "vite dev --host 0.0.0.0", "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51RtuLNE7fOCwHSD4mewwzFejyytjdGoSDK7CAvhbffwaZnPbNb2rwJICw6LTOXCmWO320fSNXvb5NzI08RZVkAxd00syfqrW7t bun sst shell --stage=dev bun dev", - "build": "bun ./script/generate-sitemap.ts && vite build && bun ../../opencode/script/schema.ts ./.output/public/config.json", + "build": "bun ./script/generate-sitemap.ts && vite build && bun ../../opencode/script/schema.ts ./.output/public/config.json ./.output/public/tui.json", "start": "vite start" }, "dependencies": { diff --git a/packages/opencode/script/schema.ts b/packages/opencode/script/schema.ts index 585701c9518..61d11ea7c93 100755 --- a/packages/opencode/script/schema.ts +++ b/packages/opencode/script/schema.ts @@ -2,46 +2,62 @@ import { z } from "zod" import { Config } from "../src/config/config" +import { TuiConfig } from "../src/config/tui" -const file = process.argv[2] -console.log(file) +function generate(schema: z.ZodType) { + const result = z.toJSONSchema(schema, { + io: "input", // Generate input shape (treats optional().default() as not required) + /** + * We'll use the `default` values of the field as the only value in `examples`. + * This will ensure no docs are needed to be read, as the configuration is + * self-documenting. + * + * See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5 + */ + override(ctx) { + const schema = ctx.jsonSchema -const result = z.toJSONSchema(Config.Info, { - io: "input", // Generate input shape (treats optional().default() as not required) - /** - * We'll use the `default` values of the field as the only value in `examples`. - * This will ensure no docs are needed to be read, as the configuration is - * self-documenting. - * - * See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5 - */ - override(ctx) { - const schema = ctx.jsonSchema - - // Preserve strictness: set additionalProperties: false for objects - if (schema && typeof schema === "object" && schema.type === "object" && schema.additionalProperties === undefined) { - schema.additionalProperties = false - } - - // Add examples and default descriptions for string fields with defaults - if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) { - if (!schema.examples) { - schema.examples = [schema.default] + // Preserve strictness: set additionalProperties: false for objects + if ( + schema && + typeof schema === "object" && + schema.type === "object" && + schema.additionalProperties === undefined + ) { + schema.additionalProperties = false } - schema.description = [schema.description || "", `default: \`${schema.default}\``] - .filter(Boolean) - .join("\n\n") - .trim() - } - }, -}) as Record & { - allowComments?: boolean - allowTrailingCommas?: boolean + // Add examples and default descriptions for string fields with defaults + if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) { + if (!schema.examples) { + schema.examples = [schema.default] + } + + schema.description = [schema.description || "", `default: \`${schema.default}\``] + .filter(Boolean) + .join("\n\n") + .trim() + } + }, + }) as Record & { + allowComments?: boolean + allowTrailingCommas?: boolean + } + + // used for json lsps since config supports jsonc + result.allowComments = true + result.allowTrailingCommas = true + + return result } -// used for json lsps since config supports jsonc -result.allowComments = true -result.allowTrailingCommas = true +const configFile = process.argv[2] +const tuiFile = process.argv[3] -await Bun.write(file, JSON.stringify(result, null, 2)) +console.log(configFile) +await Bun.write(configFile, JSON.stringify(generate(Config.Info), null, 2)) + +if (tuiFile) { + console.log(tuiFile) + await Bun.write(tuiFile, JSON.stringify(generate(TuiConfig.Info), null, 2)) +} diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index ab3d0968925..97c910a47d4 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -38,6 +38,8 @@ import { ArgsProvider, useArgs, type Args } from "./context/args" import open from "open" import { writeHeapSnapshot } from "v8" import { PromptRefProvider, usePromptRef } from "./context/prompt" +import { TuiConfigProvider } from "./context/tui-config" +import { TuiConfig } from "@/config/tui" async function getTerminalBackgroundColor(): Promise<"dark" | "light"> { // can't set raw mode if not a TTY @@ -104,6 +106,7 @@ import type { EventSource } from "./context/sdk" export function tui(input: { url: string args: Args + config: TuiConfig.Info directory?: string fetch?: typeof fetch headers?: RequestInit["headers"] @@ -138,35 +141,37 @@ export function tui(input: { - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/opencode/src/cli/cmd/tui/attach.ts b/packages/opencode/src/cli/cmd/tui/attach.ts index a2559cfce67..e892f9922d1 100644 --- a/packages/opencode/src/cli/cmd/tui/attach.ts +++ b/packages/opencode/src/cli/cmd/tui/attach.ts @@ -2,6 +2,9 @@ import { cmd } from "../cmd" import { UI } from "@/cli/ui" import { tui } from "./app" import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32" +import { TuiConfig } from "@/config/tui" +import { Instance } from "@/project/instance" +import { existsSync } from "fs" export const AttachCommand = cmd({ command: "attach ", @@ -63,8 +66,13 @@ export const AttachCommand = cmd({ const auth = `Basic ${Buffer.from(`opencode:${password}`).toString("base64")}` return { Authorization: auth } })() + const config = await Instance.provide({ + directory: directory && existsSync(directory) ? directory : process.cwd(), + fn: () => TuiConfig.get(), + }) await tui({ url: args.url, + config, args: { continue: args.continue, sessionID: args.session, diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx index 38dc402758b..be031296e90 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx @@ -10,8 +10,7 @@ import { type ParentProps, } from "solid-js" import { useKeyboard } from "@opentui/solid" -import { useKeybind } from "@tui/context/keybind" -import type { KeybindsConfig } from "@opencode-ai/sdk/v2" +import { type KeybindKey, useKeybind } from "@tui/context/keybind" type Context = ReturnType const ctx = createContext() @@ -22,7 +21,7 @@ export type Slash = { } export type CommandOption = DialogSelectOption & { - keybind?: keyof KeybindsConfig + keybind?: KeybindKey suggested?: boolean slash?: Slash hidden?: boolean diff --git a/packages/opencode/src/cli/cmd/tui/component/tips.tsx b/packages/opencode/src/cli/cmd/tui/component/tips.tsx index d0a7e5b44ec..73d82248adb 100644 --- a/packages/opencode/src/cli/cmd/tui/component/tips.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/tips.tsx @@ -80,11 +80,11 @@ const TIPS = [ "Switch to {highlight}Plan{/highlight} agent to get suggestions without making actual changes", "Use {highlight}@agent-name{/highlight} in prompts to invoke specialized subagents", "Press {highlight}Ctrl+X Right/Left{/highlight} to cycle through parent and child sessions", - "Create {highlight}opencode.json{/highlight} in project root for project-specific settings", - "Place settings in {highlight}~/.config/opencode/opencode.json{/highlight} for global config", + "Create {highlight}opencode.json{/highlight} for server settings and {highlight}tui.json{/highlight} for TUI settings", + "Place TUI settings in {highlight}~/.config/opencode/tui.json{/highlight} for global config", "Add {highlight}$schema{/highlight} to your config for autocomplete in your editor", "Configure {highlight}model{/highlight} in config to set your default model", - "Override any keybind in config via the {highlight}keybinds{/highlight} section", + "Override any keybind in {highlight}tui.json{/highlight} via the {highlight}keybinds{/highlight} section", "Set any keybind to {highlight}none{/highlight} to disable it completely", "Configure local or remote MCP servers in the {highlight}mcp{/highlight} config section", "OpenCode auto-handles OAuth for remote MCP servers requiring auth", @@ -140,7 +140,7 @@ const TIPS = [ "Press {highlight}Ctrl+X G{/highlight} or {highlight}/timeline{/highlight} to jump to specific messages", "Press {highlight}Ctrl+X H{/highlight} to toggle code block visibility in messages", "Press {highlight}Ctrl+X S{/highlight} or {highlight}/status{/highlight} to see system status info", - "Enable {highlight}tui.scroll_acceleration{/highlight} for smooth macOS-style scrolling", + "Enable {highlight}scroll_acceleration{/highlight} in {highlight}tui.json{/highlight} for smooth macOS-style scrolling", "Toggle username display in chat via command palette ({highlight}Ctrl+P{/highlight})", "Run {highlight}docker run -it --rm ghcr.io/anomalyco/opencode{/highlight} for containerized use", "Use {highlight}/connect{/highlight} with OpenCode Zen for curated, tested models", diff --git a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx index 0dbbbc6f9ee..566d66ade50 100644 --- a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx @@ -1,20 +1,22 @@ import { createMemo } from "solid-js" -import { useSync } from "@tui/context/sync" import { Keybind } from "@/util/keybind" import { pipe, mapValues } from "remeda" -import type { KeybindsConfig } from "@opencode-ai/sdk/v2" +import type { TuiConfig } from "@/config/tui" import type { ParsedKey, Renderable } from "@opentui/core" import { createStore } from "solid-js/store" import { useKeyboard, useRenderer } from "@opentui/solid" import { createSimpleContext } from "./helper" +import { useTuiConfig } from "./tui-config" + +export type KeybindKey = keyof NonNullable & string export const { use: useKeybind, provider: KeybindProvider } = createSimpleContext({ name: "Keybind", init: () => { - const sync = useSync() - const keybinds = createMemo(() => { + const config = useTuiConfig() + const keybinds = createMemo>(() => { return pipe( - sync.data.config.keybinds ?? {}, + (config.keybinds ?? {}) as Record, mapValues((value) => Keybind.parse(value)), ) }) @@ -78,7 +80,7 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex } return Keybind.fromParsedKey(evt, store.leader) }, - match(key: keyof KeybindsConfig, evt: ParsedKey) { + match(key: KeybindKey, evt: ParsedKey) { const keybind = keybinds()[key] if (!keybind) return false const parsed: Keybind.Info = result.parse(evt) @@ -88,7 +90,7 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex } } }, - print(key: keyof KeybindsConfig) { + print(key: KeybindKey) { const first = keybinds()[key]?.at(0) if (!first) return "" const result = Keybind.toString(first) diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index 465ed805ea1..2320c08ccc6 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -1,7 +1,6 @@ import { SyntaxStyle, RGBA, type TerminalColors } from "@opentui/core" import path from "path" import { createEffect, createMemo, onMount } from "solid-js" -import { useSync } from "@tui/context/sync" import { createSimpleContext } from "./helper" import { Glob } from "../../../../util/glob" import aura from "./theme/aura.json" with { type: "json" } @@ -42,6 +41,7 @@ import { useRenderer } from "@opentui/solid" import { createStore, produce } from "solid-js/store" import { Global } from "@/global" import { Filesystem } from "@/util/filesystem" +import { useTuiConfig } from "./tui-config" type ThemeColors = { primary: RGBA @@ -280,17 +280,17 @@ function ansiToRgba(code: number): RGBA { export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ name: "Theme", init: (props: { mode: "dark" | "light" }) => { - const sync = useSync() + const config = useTuiConfig() const kv = useKV() const [store, setStore] = createStore({ themes: DEFAULT_THEMES, mode: kv.get("theme_mode", props.mode), - active: (sync.data.config.theme ?? kv.get("theme", "opencode")) as string, + active: (config.theme ?? kv.get("theme", "opencode")) as string, ready: false, }) createEffect(() => { - const theme = sync.data.config.theme + const theme = config.theme if (theme) setStore("active", theme) }) diff --git a/packages/opencode/src/cli/cmd/tui/context/tui-config.tsx b/packages/opencode/src/cli/cmd/tui/context/tui-config.tsx new file mode 100644 index 00000000000..62dbf1ebd1b --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/context/tui-config.tsx @@ -0,0 +1,9 @@ +import { TuiConfig } from "@/config/tui" +import { createSimpleContext } from "./helper" + +export const { use: useTuiConfig, provider: TuiConfigProvider } = createSimpleContext({ + name: "TuiConfig", + init: (props: { config: TuiConfig.Info }) => { + return props.config + }, +}) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 365eb331472..f20267e0820 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -78,6 +78,7 @@ import { QuestionPrompt } from "./question" import { DialogExportOptions } from "../../ui/dialog-export-options" import { formatTranscript } from "../../util/transcript" import { UI } from "@/cli/ui.ts" +import { useTuiConfig } from "../../context/tui-config" addDefaultParsers(parsers.parsers) @@ -101,6 +102,7 @@ const context = createContext<{ showGenericToolOutput: () => boolean diffWrapMode: () => "word" | "none" sync: ReturnType + tui: ReturnType }>() function use() { @@ -113,6 +115,7 @@ export function Session() { const route = useRouteData("session") const { navigate } = useRoute() const sync = useSync() + const tuiConfig = useTuiConfig() const kv = useKV() const { theme } = useTheme() const promptRef = usePromptRef() @@ -166,7 +169,7 @@ export function Session() { const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4) const scrollAcceleration = createMemo(() => { - const tui = sync.data.config.tui + const tui = tuiConfig if (tui?.scroll_acceleration?.enabled) { return new MacOSScrollAccel() } @@ -988,6 +991,7 @@ export function Session() { showGenericToolOutput, diffWrapMode, sync, + tui: tuiConfig, }} > @@ -1949,7 +1953,7 @@ function Edit(props: ToolProps) { const { theme, syntax } = useTheme() const view = createMemo(() => { - const diffStyle = ctx.sync.data.config.tui?.diff_style + const diffStyle = ctx.tui.diff_style if (diffStyle === "stacked") return "unified" // Default to "auto" behavior return ctx.width > 120 ? "split" : "unified" @@ -2003,7 +2007,7 @@ function ApplyPatch(props: ToolProps) { const files = createMemo(() => props.metadata.files ?? []) const view = createMemo(() => { - const diffStyle = ctx.sync.data.config.tui?.diff_style + const diffStyle = ctx.tui.diff_style if (diffStyle === "stacked") return "unified" return ctx.width > 120 ? "split" : "unified" }) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx index 389fc2418cc..a50cd96fc84 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx @@ -15,6 +15,7 @@ import { Keybind } from "@/util/keybind" import { Locale } from "@/util/locale" import { Global } from "@/global" import { useDialog } from "../../ui/dialog" +import { useTuiConfig } from "../../context/tui-config" type PermissionStage = "permission" | "always" | "reject" @@ -48,14 +49,14 @@ function EditBody(props: { request: PermissionRequest }) { const themeState = useTheme() const theme = themeState.theme const syntax = themeState.syntax - const sync = useSync() + const config = useTuiConfig() const dimensions = useTerminalDimensions() const filepath = createMemo(() => (props.request.metadata?.filepath as string) ?? "") const diff = createMemo(() => (props.request.metadata?.diff as string) ?? "") const view = createMemo(() => { - const diffStyle = sync.data.config.tui?.diff_style + const diffStyle = config.diff_style if (diffStyle === "stacked") return "unified" return dimensions().width > 120 ? "split" : "unified" }) diff --git a/packages/opencode/src/cli/cmd/tui/thread.ts b/packages/opencode/src/cli/cmd/tui/thread.ts index 50f63c3dfbd..750347d9d63 100644 --- a/packages/opencode/src/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/cli/cmd/tui/thread.ts @@ -12,6 +12,8 @@ import { Filesystem } from "@/util/filesystem" import type { Event } from "@opencode-ai/sdk/v2" import type { EventSource } from "./context/sdk" import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32" +import { TuiConfig } from "@/config/tui" +import { Instance } from "@/project/instance" declare global { const OPENCODE_WORKER_PATH: string @@ -135,6 +137,10 @@ export const TuiThreadCommand = cmd({ if (!args.prompt) return piped return piped ? piped + "\n" + args.prompt : args.prompt }) + const config = await Instance.provide({ + directory: cwd, + fn: () => TuiConfig.get(), + }) // Check if server should be started (port or hostname explicitly set in CLI or config) const networkOpts = await resolveNetworkOptions(args) @@ -163,6 +169,8 @@ export const TuiThreadCommand = cmd({ const tuiPromise = tui({ url, + config, + directory: cwd, fetch: customFetch, events, args: { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 761ce23f3d6..28aea4d6777 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -4,7 +4,6 @@ import { pathToFileURL, fileURLToPath } from "url" import { createRequire } from "module" import os from "os" import z from "zod" -import { Filesystem } from "../util/filesystem" import { ModelsDev } from "../provider/models" import { mergeDeep, pipe, unique } from "remeda" import { Global } from "../global" @@ -34,6 +33,8 @@ import { PackageRegistry } from "@/bun/registry" import { proxied } from "@/util/proxied" import { iife } from "@/util/iife" import { Control } from "@/control" +import { ConfigPaths } from "./paths" +import { Filesystem } from "@/util/filesystem" export namespace Config { const ModelId = z.string().meta({ $ref: "https://models.dev/model-schema.json#/$defs/Model" }) @@ -42,7 +43,7 @@ export namespace Config { // Managed settings directory for enterprise deployments (highest priority, admin-controlled) // These settings override all user and project settings - function getManagedConfigDir(): string { + function systemManagedConfigDir(): string { switch (process.platform) { case "darwin": return "/Library/Application Support/opencode" @@ -53,10 +54,14 @@ export namespace Config { } } - const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR || getManagedConfigDir() + export function managedConfigDir() { + return process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR || systemManagedConfigDir() + } + + const managedDir = managedConfigDir() // Custom merge function that concatenates array fields instead of replacing them - function merge(target: Info, source: Info): Info { + function mergeConfigConcatArrays(target: Info, source: Info): Info { const merged = mergeDeep(target, source) if (target.plugin && source.plugin) { merged.plugin = Array.from(new Set([...target.plugin, ...source.plugin])) @@ -91,7 +96,7 @@ export namespace Config { const remoteConfig = wellknown.config ?? {} // Add $schema to prevent load() from trying to write back to a non-existent file if (!remoteConfig.$schema) remoteConfig.$schema = "https://opencode.ai/config.json" - result = merge( + result = mergeConfigConcatArrays( result, await load(JSON.stringify(remoteConfig), { dir: path.dirname(`${key}/.well-known/opencode`), @@ -107,21 +112,18 @@ export namespace Config { } // Global user config overrides remote config. - result = merge(result, await global()) + result = mergeConfigConcatArrays(result, await global()) // Custom config path overrides global config. if (Flag.OPENCODE_CONFIG) { - result = merge(result, await loadFile(Flag.OPENCODE_CONFIG)) + result = mergeConfigConcatArrays(result, await loadFile(Flag.OPENCODE_CONFIG)) log.debug("loaded custom config", { path: Flag.OPENCODE_CONFIG }) } // Project config overrides global and remote config. if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) { - for (const file of ["opencode.jsonc", "opencode.json"]) { - const found = await Filesystem.findUp(file, Instance.directory, Instance.worktree) - for (const resolved of found.toReversed()) { - result = merge(result, await loadFile(resolved)) - } + for (const file of await ConfigPaths.projectFiles("opencode", Instance.directory, Instance.worktree)) { + result = mergeConfigConcatArrays(result, await loadFile(file)) } } @@ -129,31 +131,10 @@ export namespace Config { result.mode = result.mode || {} result.plugin = result.plugin || [] - const directories = [ - Global.Path.config, - // Only scan project .opencode/ directories when project discovery is enabled - ...(!Flag.OPENCODE_DISABLE_PROJECT_CONFIG - ? await Array.fromAsync( - Filesystem.up({ - targets: [".opencode"], - start: Instance.directory, - stop: Instance.worktree, - }), - ) - : []), - // Always scan ~/.opencode/ (user home directory) - ...(await Array.fromAsync( - Filesystem.up({ - targets: [".opencode"], - start: Global.Path.home, - stop: Global.Path.home, - }), - )), - ] + const directories = await ConfigPaths.directories(Instance.directory, Instance.worktree) // .opencode directory config overrides (project and global) config sources. if (Flag.OPENCODE_CONFIG_DIR) { - directories.push(Flag.OPENCODE_CONFIG_DIR) log.debug("loading config from OPENCODE_CONFIG_DIR", { path: Flag.OPENCODE_CONFIG_DIR }) } @@ -163,7 +144,7 @@ export namespace Config { if (dir.endsWith(".opencode") || dir === Flag.OPENCODE_CONFIG_DIR) { for (const file of ["opencode.jsonc", "opencode.json"]) { log.debug(`loading config from ${path.join(dir, file)}`) - result = merge(result, await loadFile(path.join(dir, file))) + result = mergeConfigConcatArrays(result, await loadFile(path.join(dir, file))) // to satisfy the type checker result.agent ??= {} result.mode ??= {} @@ -186,7 +167,7 @@ export namespace Config { // Inline config content overrides all non-managed config sources. if (process.env.OPENCODE_CONFIG_CONTENT) { - result = merge( + result = mergeConfigConcatArrays( result, await load(process.env.OPENCODE_CONFIG_CONTENT, { dir: Instance.directory, @@ -200,9 +181,9 @@ export namespace Config { // Kept separate from directories array to avoid write operations when installing plugins // which would fail on system directories requiring elevated permissions // This way it only loads config file and not skills/plugins/commands - if (existsSync(managedConfigDir)) { + if (existsSync(managedDir)) { for (const file of ["opencode.jsonc", "opencode.json"]) { - result = merge(result, await loadFile(path.join(managedConfigDir, file))) + result = mergeConfigConcatArrays(result, await loadFile(path.join(managedDir, file))) } } @@ -241,8 +222,6 @@ export namespace Config { result.share = "auto" } - if (!result.keybinds) result.keybinds = Info.shape.keybinds.parse({}) - // Apply flag overrides for compaction settings if (Flag.OPENCODE_DISABLE_AUTOCOMPACT) { result.compaction = { ...result.compaction, auto: false } @@ -306,7 +285,7 @@ export namespace Config { } } - async function needsInstall(dir: string) { + export async function needsInstall(dir: string) { // Some config dirs may be read-only. // Installing deps there will fail; skip installation in that case. const writable = await isWritable(dir) @@ -930,20 +909,6 @@ export namespace Config { ref: "KeybindsConfig", }) - export const TUI = z.object({ - scroll_speed: z.number().min(0.001).optional().describe("TUI scroll speed"), - scroll_acceleration: z - .object({ - enabled: z.boolean().describe("Enable scroll acceleration"), - }) - .optional() - .describe("Scroll acceleration settings"), - diff_style: z - .enum(["auto", "stacked"]) - .optional() - .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), - }) - export const Server = z .object({ port: z.number().int().positive().optional().describe("Port to listen on"), @@ -1018,10 +983,7 @@ export namespace Config { export const Info = z .object({ $schema: z.string().optional().describe("JSON schema reference for configuration validation"), - theme: z.string().optional().describe("Theme name to use for the interface"), - keybinds: Keybinds.optional().describe("Custom keybind configurations"), logLevel: Log.Level.optional().describe("Log level"), - tui: TUI.optional().describe("TUI specific settings"), server: Server.optional().describe("Server configuration for opencode serve and web commands"), command: z .record(z.string(), Command) @@ -1241,86 +1203,37 @@ export namespace Config { return result }) + export const { readFile } = ConfigPaths + async function loadFile(filepath: string): Promise { log.info("loading", { path: filepath }) - let text = await Filesystem.readText(filepath).catch((err: any) => { - if (err.code === "ENOENT") return - throw new JsonError({ path: filepath }, { cause: err }) - }) + const text = await readFile(filepath) if (!text) return {} return load(text, { path: filepath }) } async function load(text: string, options: { path: string } | { dir: string; source: string }) { const original = text - const configDir = "path" in options ? path.dirname(options.path) : options.dir const source = "path" in options ? options.path : options.source const isFile = "path" in options + const data = await ConfigPaths.parseText( + text, + "path" in options ? options.path : { source: options.source, dir: options.dir }, + ) - text = text.replace(/\{env:([^}]+)\}/g, (_, varName) => { - return process.env[varName] || "" - }) + const normalized = (() => { + if (!data || typeof data !== "object" || Array.isArray(data)) return data + const copy = { ...(data as Record) } + const hadLegacy = "theme" in copy || "keybinds" in copy || "tui" in copy + if (!hadLegacy) return copy + delete copy.theme + delete copy.keybinds + delete copy.tui + log.warn("tui keys in opencode config are deprecated; move them to tui.json", { path: source }) + return copy + })() - const fileMatches = text.match(/\{file:[^}]+\}/g) - if (fileMatches) { - const lines = text.split("\n") - - for (const match of fileMatches) { - const lineIndex = lines.findIndex((line) => line.includes(match)) - if (lineIndex !== -1 && lines[lineIndex].trim().startsWith("//")) { - continue - } - let filePath = match.replace(/^\{file:/, "").replace(/\}$/, "") - if (filePath.startsWith("~/")) { - filePath = path.join(os.homedir(), filePath.slice(2)) - } - const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(configDir, filePath) - const fileContent = ( - await Bun.file(resolvedPath) - .text() - .catch((error) => { - const errMsg = `bad file reference: "${match}"` - if (error.code === "ENOENT") { - throw new InvalidError( - { - path: source, - message: errMsg + ` ${resolvedPath} does not exist`, - }, - { cause: error }, - ) - } - throw new InvalidError({ path: source, message: errMsg }, { cause: error }) - }) - ).trim() - text = text.replace(match, () => JSON.stringify(fileContent).slice(1, -1)) - } - } - - const errors: JsoncParseError[] = [] - const data = parseJsonc(text, errors, { allowTrailingComma: true }) - if (errors.length) { - const lines = text.split("\n") - const errorDetails = errors - .map((e) => { - const beforeOffset = text.substring(0, e.offset).split("\n") - const line = beforeOffset.length - const column = beforeOffset[beforeOffset.length - 1].length + 1 - const problemLine = lines[line - 1] - - const error = `${printParseErrorCode(e.error)} at line ${line}, column ${column}` - if (!problemLine) return error - - return `${error}\n Line ${line}: ${problemLine}\n${"".padStart(column + 9)}^` - }) - .join("\n") - - throw new JsonError({ - path: source, - message: `\n--- JSONC Input ---\n${text}\n--- Errors ---\n${errorDetails}\n--- End ---`, - }) - } - - const parsed = Info.safeParse(data) + const parsed = Info.safeParse(normalized) if (parsed.success) { if (!parsed.data.$schema && isFile) { parsed.data.$schema = "https://opencode.ai/config.json" @@ -1353,13 +1266,7 @@ export namespace Config { issues: parsed.error.issues, }) } - export const JsonError = NamedError.create( - "ConfigJsonError", - z.object({ - path: z.string(), - message: z.string().optional(), - }), - ) + export const { JsonError, InvalidError } = ConfigPaths export const ConfigDirectoryTypoError = NamedError.create( "ConfigDirectoryTypoError", @@ -1370,15 +1277,6 @@ export namespace Config { }), ) - export const InvalidError = NamedError.create( - "ConfigInvalidError", - z.object({ - path: z.string(), - issues: z.custom().optional(), - message: z.string().optional(), - }), - ) - export async function get() { return state().then((x) => x.config) } diff --git a/packages/opencode/src/config/migrate-tui-config.ts b/packages/opencode/src/config/migrate-tui-config.ts new file mode 100644 index 00000000000..b426e4fbd10 --- /dev/null +++ b/packages/opencode/src/config/migrate-tui-config.ts @@ -0,0 +1,155 @@ +import path from "path" +import { type ParseError as JsoncParseError, applyEdits, modify, parse as parseJsonc } from "jsonc-parser" +import { unique } from "remeda" +import z from "zod" +import { ConfigPaths } from "./paths" +import { TuiInfo, TuiOptions } from "./tui-schema" +import { Instance } from "@/project/instance" +import { Flag } from "@/flag/flag" +import { Log } from "@/util/log" +import { Filesystem } from "@/util/filesystem" +import { Global } from "@/global" + +const log = Log.create({ service: "tui.migrate" }) + +const TUI_SCHEMA_URL = "https://opencode.ai/tui.json" + +const LegacyTheme = TuiInfo.shape.theme.optional() +const LegacyRecord = z.record(z.string(), z.unknown()).optional() + +const TuiLegacy = z + .object({ + scroll_speed: TuiOptions.shape.scroll_speed.catch(undefined), + scroll_acceleration: TuiOptions.shape.scroll_acceleration.catch(undefined), + diff_style: TuiOptions.shape.diff_style.catch(undefined), + }) + .strip() + +interface MigrateInput { + directories: string[] + custom?: string + managed: string +} + +/** + * Migrates tui-specific keys (theme, keybinds, tui) from opencode.json files + * into dedicated tui.json files. Migration is performed per-directory and + * skips only locations where a tui.json already exists. + */ +export async function migrateTuiConfig(input: MigrateInput) { + const opencode = await opencodeFiles(input) + for (const file of opencode) { + const source = await Filesystem.readText(file).catch((error) => { + log.warn("failed to read config for tui migration", { path: file, error }) + return undefined + }) + if (!source) continue + const errors: JsoncParseError[] = [] + const data = parseJsonc(source, errors, { allowTrailingComma: true }) + if (errors.length || !data || typeof data !== "object" || Array.isArray(data)) continue + + const theme = LegacyTheme.safeParse("theme" in data ? data.theme : undefined) + const keybinds = LegacyRecord.safeParse("keybinds" in data ? data.keybinds : undefined) + const legacyTui = LegacyRecord.safeParse("tui" in data ? data.tui : undefined) + const extracted = { + theme: theme.success ? theme.data : undefined, + keybinds: keybinds.success ? keybinds.data : undefined, + tui: legacyTui.success ? legacyTui.data : undefined, + } + const tui = extracted.tui ? normalizeTui(extracted.tui) : undefined + if (extracted.theme === undefined && extracted.keybinds === undefined && !tui) continue + + const target = path.join(path.dirname(file), "tui.json") + const targetExists = await Filesystem.exists(target) + if (targetExists) continue + + const payload: Record = { + $schema: TUI_SCHEMA_URL, + } + if (extracted.theme !== undefined) payload.theme = extracted.theme + if (extracted.keybinds !== undefined) payload.keybinds = extracted.keybinds + if (tui) Object.assign(payload, tui) + + const wrote = await Bun.write(target, JSON.stringify(payload, null, 2)) + .then(() => true) + .catch((error) => { + log.warn("failed to write tui migration target", { from: file, to: target, error }) + return false + }) + if (!wrote) continue + + const stripped = await backupAndStripLegacy(file, source) + if (!stripped) { + log.warn("tui config migrated but source file was not stripped", { from: file, to: target }) + continue + } + log.info("migrated tui config", { from: file, to: target }) + } +} + +function normalizeTui(data: Record) { + const parsed = TuiLegacy.parse(data) + if ( + parsed.scroll_speed === undefined && + parsed.diff_style === undefined && + parsed.scroll_acceleration === undefined + ) { + return + } + return parsed +} + +async function backupAndStripLegacy(file: string, source: string) { + const backup = file + ".tui-migration.bak" + const hasBackup = await Filesystem.exists(backup) + const backed = hasBackup + ? true + : await Bun.write(backup, source) + .then(() => true) + .catch((error) => { + log.warn("failed to backup source config during tui migration", { path: file, backup, error }) + return false + }) + if (!backed) return false + + const text = ["theme", "keybinds", "tui"].reduce((acc, key) => { + const edits = modify(acc, [key], undefined, { + formattingOptions: { + insertSpaces: true, + tabSize: 2, + }, + }) + if (!edits.length) return acc + return applyEdits(acc, edits) + }, source) + + return Bun.write(file, text) + .then(() => { + log.info("stripped tui keys from server config", { path: file, backup }) + return true + }) + .catch((error) => { + log.warn("failed to strip legacy tui keys from server config", { path: file, backup, error }) + return false + }) +} + +async function opencodeFiles(input: { directories: string[]; managed: string }) { + const project = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + ? [] + : await ConfigPaths.projectFiles("opencode", Instance.directory, Instance.worktree) + const files = [...project, ...ConfigPaths.fileInDirectory(Global.Path.config, "opencode")] + for (const dir of unique(input.directories)) { + files.push(...ConfigPaths.fileInDirectory(dir, "opencode")) + } + if (Flag.OPENCODE_CONFIG) files.push(Flag.OPENCODE_CONFIG) + files.push(...ConfigPaths.fileInDirectory(input.managed, "opencode")) + + const existing = await Promise.all( + unique(files).map(async (file) => { + const ok = await Filesystem.exists(file) + return ok ? file : undefined + }), + ) + return existing.filter((file): file is string => !!file) +} diff --git a/packages/opencode/src/config/paths.ts b/packages/opencode/src/config/paths.ts new file mode 100644 index 00000000000..396417e9a5b --- /dev/null +++ b/packages/opencode/src/config/paths.ts @@ -0,0 +1,174 @@ +import path from "path" +import os from "os" +import z from "zod" +import { type ParseError as JsoncParseError, parse as parseJsonc, printParseErrorCode } from "jsonc-parser" +import { NamedError } from "@opencode-ai/util/error" +import { Filesystem } from "@/util/filesystem" +import { Flag } from "@/flag/flag" +import { Global } from "@/global" + +export namespace ConfigPaths { + export async function projectFiles(name: string, directory: string, worktree: string) { + const files: string[] = [] + for (const file of [`${name}.jsonc`, `${name}.json`]) { + const found = await Filesystem.findUp(file, directory, worktree) + for (const resolved of found.toReversed()) { + files.push(resolved) + } + } + return files + } + + export async function directories(directory: string, worktree: string) { + return [ + Global.Path.config, + ...(!Flag.OPENCODE_DISABLE_PROJECT_CONFIG + ? await Array.fromAsync( + Filesystem.up({ + targets: [".opencode"], + start: directory, + stop: worktree, + }), + ) + : []), + ...(await Array.fromAsync( + Filesystem.up({ + targets: [".opencode"], + start: Global.Path.home, + stop: Global.Path.home, + }), + )), + ...(Flag.OPENCODE_CONFIG_DIR ? [Flag.OPENCODE_CONFIG_DIR] : []), + ] + } + + export function fileInDirectory(dir: string, name: string) { + return [path.join(dir, `${name}.jsonc`), path.join(dir, `${name}.json`)] + } + + export const JsonError = NamedError.create( + "ConfigJsonError", + z.object({ + path: z.string(), + message: z.string().optional(), + }), + ) + + export const InvalidError = NamedError.create( + "ConfigInvalidError", + z.object({ + path: z.string(), + issues: z.custom().optional(), + message: z.string().optional(), + }), + ) + + /** Read a config file, returning undefined for missing files and throwing JsonError for other failures. */ + export async function readFile(filepath: string) { + return Filesystem.readText(filepath).catch((err: NodeJS.ErrnoException) => { + if (err.code === "ENOENT") return + throw new JsonError({ path: filepath }, { cause: err }) + }) + } + + type ParseSource = string | { source: string; dir: string } + + function source(input: ParseSource) { + return typeof input === "string" ? input : input.source + } + + function dir(input: ParseSource) { + return typeof input === "string" ? path.dirname(input) : input.dir + } + + /** Apply {env:VAR} and {file:path} substitutions to config text. */ + async function substitute(text: string, input: ParseSource, missing: "error" | "empty" = "error") { + text = text.replace(/\{env:([^}]+)\}/g, (_, varName) => { + return process.env[varName] || "" + }) + + const fileMatches = Array.from(text.matchAll(/\{file:[^}]+\}/g)) + if (!fileMatches.length) return text + + const configDir = dir(input) + const configSource = source(input) + let out = "" + let cursor = 0 + + for (const match of fileMatches) { + const token = match[0] + const index = match.index! + out += text.slice(cursor, index) + + const lineStart = text.lastIndexOf("\n", index - 1) + 1 + const prefix = text.slice(lineStart, index).trimStart() + if (prefix.startsWith("//")) { + out += token + cursor = index + token.length + continue + } + + let filePath = token.replace(/^\{file:/, "").replace(/\}$/, "") + if (filePath.startsWith("~/")) { + filePath = path.join(os.homedir(), filePath.slice(2)) + } + + const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(configDir, filePath) + const fileContent = ( + await Filesystem.readText(resolvedPath).catch((error: NodeJS.ErrnoException) => { + if (missing === "empty") return "" + + const errMsg = `bad file reference: "${token}"` + if (error.code === "ENOENT") { + throw new InvalidError( + { + path: configSource, + message: errMsg + ` ${resolvedPath} does not exist`, + }, + { cause: error }, + ) + } + throw new InvalidError({ path: configSource, message: errMsg }, { cause: error }) + }) + ).trim() + + out += JSON.stringify(fileContent).slice(1, -1) + cursor = index + token.length + } + + out += text.slice(cursor) + return out + } + + /** Substitute and parse JSONC text, throwing JsonError on syntax errors. */ + export async function parseText(text: string, input: ParseSource, missing: "error" | "empty" = "error") { + const configSource = source(input) + text = await substitute(text, input, missing) + + const errors: JsoncParseError[] = [] + const data = parseJsonc(text, errors, { allowTrailingComma: true }) + if (errors.length) { + const lines = text.split("\n") + const errorDetails = errors + .map((e) => { + const beforeOffset = text.substring(0, e.offset).split("\n") + const line = beforeOffset.length + const column = beforeOffset[beforeOffset.length - 1].length + 1 + const problemLine = lines[line - 1] + + const error = `${printParseErrorCode(e.error)} at line ${line}, column ${column}` + if (!problemLine) return error + + return `${error}\n Line ${line}: ${problemLine}\n${"".padStart(column + 9)}^` + }) + .join("\n") + + throw new JsonError({ + path: configSource, + message: `\n--- JSONC Input ---\n${text}\n--- Errors ---\n${errorDetails}\n--- End ---`, + }) + } + + return data + } +} diff --git a/packages/opencode/src/config/tui-schema.ts b/packages/opencode/src/config/tui-schema.ts new file mode 100644 index 00000000000..f9068e3f01d --- /dev/null +++ b/packages/opencode/src/config/tui-schema.ts @@ -0,0 +1,34 @@ +import z from "zod" +import { Config } from "./config" + +const KeybindOverride = z + .object( + Object.fromEntries(Object.keys(Config.Keybinds.shape).map((key) => [key, z.string().optional()])) as Record< + string, + z.ZodOptional + >, + ) + .strict() + +export const TuiOptions = z.object({ + scroll_speed: z.number().min(0.001).optional().describe("TUI scroll speed"), + scroll_acceleration: z + .object({ + enabled: z.boolean().describe("Enable scroll acceleration"), + }) + .optional() + .describe("Scroll acceleration settings"), + diff_style: z + .enum(["auto", "stacked"]) + .optional() + .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), +}) + +export const TuiInfo = z + .object({ + $schema: z.string().optional(), + theme: z.string().optional(), + keybinds: KeybindOverride.optional(), + }) + .extend(TuiOptions.shape) + .strict() diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts new file mode 100644 index 00000000000..f0964f63b35 --- /dev/null +++ b/packages/opencode/src/config/tui.ts @@ -0,0 +1,118 @@ +import { existsSync } from "fs" +import z from "zod" +import { mergeDeep, unique } from "remeda" +import { Config } from "./config" +import { ConfigPaths } from "./paths" +import { migrateTuiConfig } from "./migrate-tui-config" +import { TuiInfo } from "./tui-schema" +import { Instance } from "@/project/instance" +import { Flag } from "@/flag/flag" +import { Log } from "@/util/log" +import { Global } from "@/global" + +export namespace TuiConfig { + const log = Log.create({ service: "tui.config" }) + + export const Info = TuiInfo + + export type Info = z.output + + function mergeInfo(target: Info, source: Info): Info { + return mergeDeep(target, source) + } + + function customPath() { + return Flag.OPENCODE_TUI_CONFIG + } + + const state = Instance.state(async () => { + let projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + ? [] + : await ConfigPaths.projectFiles("tui", Instance.directory, Instance.worktree) + const directories = await ConfigPaths.directories(Instance.directory, Instance.worktree) + const custom = customPath() + const managed = Config.managedConfigDir() + await migrateTuiConfig({ directories, custom, managed }) + // Re-compute after migration since migrateTuiConfig may have created new tui.json files + projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + ? [] + : await ConfigPaths.projectFiles("tui", Instance.directory, Instance.worktree) + + let result: Info = {} + + for (const file of ConfigPaths.fileInDirectory(Global.Path.config, "tui")) { + result = mergeInfo(result, await loadFile(file)) + } + + if (custom) { + result = mergeInfo(result, await loadFile(custom)) + log.debug("loaded custom tui config", { path: custom }) + } + + for (const file of projectFiles) { + result = mergeInfo(result, await loadFile(file)) + } + + for (const dir of unique(directories)) { + if (!dir.endsWith(".opencode") && dir !== Flag.OPENCODE_CONFIG_DIR) continue + for (const file of ConfigPaths.fileInDirectory(dir, "tui")) { + result = mergeInfo(result, await loadFile(file)) + } + } + + if (existsSync(managed)) { + for (const file of ConfigPaths.fileInDirectory(managed, "tui")) { + result = mergeInfo(result, await loadFile(file)) + } + } + + result.keybinds = Config.Keybinds.parse(result.keybinds ?? {}) + + return { + config: result, + } + }) + + export async function get() { + return state().then((x) => x.config) + } + + async function loadFile(filepath: string): Promise { + const text = await ConfigPaths.readFile(filepath) + if (!text) return {} + return load(text, filepath).catch((error) => { + log.warn("failed to load tui config", { path: filepath, error }) + return {} + }) + } + + async function load(text: string, configFilepath: string): Promise { + const data = await ConfigPaths.parseText(text, configFilepath, "empty") + if (!data || typeof data !== "object" || Array.isArray(data)) return {} + + // Flatten a nested "tui" key so users who wrote `{ "tui": { ... } }` inside tui.json + // (mirroring the old opencode.json shape) still get their settings applied. + const normalized = (() => { + const copy = { ...(data as Record) } + if (!("tui" in copy)) return copy + if (!copy.tui || typeof copy.tui !== "object" || Array.isArray(copy.tui)) { + delete copy.tui + return copy + } + const tui = copy.tui as Record + delete copy.tui + return { + ...tui, + ...copy, + } + })() + + const parsed = Info.safeParse(normalized) + if (!parsed.success) { + log.warn("invalid tui config", { path: configFilepath, issues: parsed.error.issues }) + return {} + } + + return parsed.data + } +} diff --git a/packages/opencode/src/flag/flag.ts b/packages/opencode/src/flag/flag.ts index 0049d716d09..e02f191c709 100644 --- a/packages/opencode/src/flag/flag.ts +++ b/packages/opencode/src/flag/flag.ts @@ -7,6 +7,7 @@ export namespace Flag { export const OPENCODE_AUTO_SHARE = truthy("OPENCODE_AUTO_SHARE") export const OPENCODE_GIT_BASH_PATH = process.env["OPENCODE_GIT_BASH_PATH"] export const OPENCODE_CONFIG = process.env["OPENCODE_CONFIG"] + export declare const OPENCODE_TUI_CONFIG: string | undefined export declare const OPENCODE_CONFIG_DIR: string | undefined export const OPENCODE_CONFIG_CONTENT = process.env["OPENCODE_CONFIG_CONTENT"] export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE") @@ -74,6 +75,17 @@ Object.defineProperty(Flag, "OPENCODE_DISABLE_PROJECT_CONFIG", { configurable: false, }) +// Dynamic getter for OPENCODE_TUI_CONFIG +// This must be evaluated at access time, not module load time, +// because tests and external tooling may set this env var at runtime +Object.defineProperty(Flag, "OPENCODE_TUI_CONFIG", { + get() { + return process.env["OPENCODE_TUI_CONFIG"] + }, + enumerable: true, + configurable: false, +}) + // Dynamic getter for OPENCODE_CONFIG_DIR // This must be evaluated at access time, not module load time, // because external tooling may set this env var at runtime diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index 2b1ba816ea3..f245dc3493d 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -56,6 +56,28 @@ test("loads JSON config file", async () => { }) }) +test("ignores legacy tui keys in opencode config", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await writeConfig(dir, { + $schema: "https://opencode.ai/config.json", + model: "test/model", + theme: "legacy", + tui: { scroll_speed: 4 }, + }) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.model).toBe("test/model") + expect((config as Record).theme).toBeUndefined() + expect((config as Record).tui).toBeUndefined() + }, + }) +}) + test("loads JSONC config file", async () => { await using tmp = await tmpdir({ init: async (dir) => { @@ -110,14 +132,14 @@ test("merges multiple config files with correct precedence", async () => { test("handles environment variable substitution", async () => { const originalEnv = process.env["TEST_VAR"] - process.env["TEST_VAR"] = "test_theme" + process.env["TEST_VAR"] = "test-user" try { await using tmp = await tmpdir({ init: async (dir) => { await writeConfig(dir, { $schema: "https://opencode.ai/config.json", - theme: "{env:TEST_VAR}", + username: "{env:TEST_VAR}", }) }, }) @@ -125,7 +147,7 @@ test("handles environment variable substitution", async () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("test_theme") + expect(config.username).toBe("test-user") }, }) } finally { @@ -148,7 +170,7 @@ test("preserves env variables when adding $schema to config", async () => { await Filesystem.write( path.join(dir, "opencode.json"), JSON.stringify({ - theme: "{env:PRESERVE_VAR}", + username: "{env:PRESERVE_VAR}", }), ) }, @@ -157,7 +179,7 @@ test("preserves env variables when adding $schema to config", async () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("secret_value") + expect(config.username).toBe("secret_value") // Read the file to verify the env variable was preserved const content = await Filesystem.readText(path.join(tmp.path, "opencode.json")) @@ -178,10 +200,10 @@ test("preserves env variables when adding $schema to config", async () => { test("handles file inclusion substitution", async () => { await using tmp = await tmpdir({ init: async (dir) => { - await Filesystem.write(path.join(dir, "included.txt"), "test_theme") + await Filesystem.write(path.join(dir, "included.txt"), "test-user") await writeConfig(dir, { $schema: "https://opencode.ai/config.json", - theme: "{file:included.txt}", + username: "{file:included.txt}", }) }, }) @@ -189,7 +211,7 @@ test("handles file inclusion substitution", async () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("test_theme") + expect(config.username).toBe("test-user") }, }) }) @@ -200,7 +222,7 @@ test("handles file inclusion with replacement tokens", async () => { await Filesystem.write(path.join(dir, "included.md"), "const out = await Bun.$`echo hi`") await writeConfig(dir, { $schema: "https://opencode.ai/config.json", - theme: "{file:included.md}", + username: "{file:included.md}", }) }, }) @@ -208,7 +230,7 @@ test("handles file inclusion with replacement tokens", async () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("const out = await Bun.$`echo hi`") + expect(config.username).toBe("const out = await Bun.$`echo hi`") }, }) }) @@ -1043,7 +1065,6 @@ test("managed settings override project settings", async () => { $schema: "https://opencode.ai/config.json", autoupdate: true, disabled_providers: [], - theme: "dark", }) }, }) @@ -1060,7 +1081,6 @@ test("managed settings override project settings", async () => { const config = await Config.get() expect(config.autoupdate).toBe(false) expect(config.disabled_providers).toEqual(["openai"]) - expect(config.theme).toBe("dark") }, }) }) @@ -1809,7 +1829,7 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => { process.env["TEST_CONFIG_VAR"] = "test_api_key_12345" process.env["OPENCODE_CONFIG_CONTENT"] = JSON.stringify({ $schema: "https://opencode.ai/config.json", - theme: "{env:TEST_CONFIG_VAR}", + username: "{env:TEST_CONFIG_VAR}", }) try { @@ -1818,7 +1838,7 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("test_api_key_12345") + expect(config.username).toBe("test_api_key_12345") }, }) } finally { @@ -1841,10 +1861,10 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => { try { await using tmp = await tmpdir({ init: async (dir) => { - await Bun.write(path.join(dir, "api_key.txt"), "secret_key_from_file") + await Filesystem.write(path.join(dir, "api_key.txt"), "secret_key_from_file") process.env["OPENCODE_CONFIG_CONTENT"] = JSON.stringify({ $schema: "https://opencode.ai/config.json", - theme: "{file:./api_key.txt}", + username: "{file:./api_key.txt}", }) }, }) @@ -1852,7 +1872,7 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => { directory: tmp.path, fn: async () => { const config = await Config.get() - expect(config.theme).toBe("secret_key_from_file") + expect(config.username).toBe("secret_key_from_file") }, }) } finally { diff --git a/packages/opencode/test/config/tui.test.ts b/packages/opencode/test/config/tui.test.ts new file mode 100644 index 00000000000..f9de5b041b4 --- /dev/null +++ b/packages/opencode/test/config/tui.test.ts @@ -0,0 +1,510 @@ +import { afterEach, expect, test } from "bun:test" +import path from "path" +import fs from "fs/promises" +import { tmpdir } from "../fixture/fixture" +import { Instance } from "../../src/project/instance" +import { TuiConfig } from "../../src/config/tui" +import { Global } from "../../src/global" +import { Filesystem } from "../../src/util/filesystem" + +const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR! + +afterEach(async () => { + delete process.env.OPENCODE_CONFIG + delete process.env.OPENCODE_TUI_CONFIG + await fs.rm(path.join(Global.Path.config, "tui.json"), { force: true }).catch(() => {}) + await fs.rm(path.join(Global.Path.config, "tui.jsonc"), { force: true }).catch(() => {}) + await fs.rm(managedConfigDir, { force: true, recursive: true }).catch(() => {}) +}) + +test("loads tui config with the same precedence order as server config paths", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(Global.Path.config, "tui.json"), JSON.stringify({ theme: "global" }, null, 2)) + await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ theme: "project" }, null, 2)) + await fs.mkdir(path.join(dir, ".opencode"), { recursive: true }) + await Bun.write( + path.join(dir, ".opencode", "tui.json"), + JSON.stringify({ theme: "local", diff_style: "stacked" }, null, 2), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("local") + expect(config.diff_style).toBe("stacked") + }, + }) +}) + +test("migrates tui-specific keys from opencode.json when tui.json does not exist", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify( + { + theme: "migrated-theme", + tui: { scroll_speed: 5 }, + keybinds: { app_exit: "ctrl+q" }, + }, + null, + 2, + ), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("migrated-theme") + expect(config.scroll_speed).toBe(5) + expect(config.keybinds?.app_exit).toBe("ctrl+q") + const text = await Filesystem.readText(path.join(tmp.path, "tui.json")) + expect(JSON.parse(text)).toMatchObject({ + theme: "migrated-theme", + scroll_speed: 5, + }) + const server = JSON.parse(await Filesystem.readText(path.join(tmp.path, "opencode.json"))) + expect(server.theme).toBeUndefined() + expect(server.keybinds).toBeUndefined() + expect(server.tui).toBeUndefined() + expect(await Filesystem.exists(path.join(tmp.path, "opencode.json.tui-migration.bak"))).toBe(true) + expect(await Filesystem.exists(path.join(tmp.path, "tui.json"))).toBe(true) + }, + }) +}) + +test("migrates project legacy tui keys even when global tui.json already exists", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(Global.Path.config, "tui.json"), JSON.stringify({ theme: "global" }, null, 2)) + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify( + { + theme: "project-migrated", + tui: { scroll_speed: 2 }, + }, + null, + 2, + ), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("project-migrated") + expect(config.scroll_speed).toBe(2) + expect(await Filesystem.exists(path.join(tmp.path, "tui.json"))).toBe(true) + + const server = JSON.parse(await Filesystem.readText(path.join(tmp.path, "opencode.json"))) + expect(server.theme).toBeUndefined() + expect(server.tui).toBeUndefined() + }, + }) +}) + +test("drops unknown legacy tui keys during migration", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify( + { + theme: "migrated-theme", + tui: { scroll_speed: 2, foo: 1 }, + }, + null, + 2, + ), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("migrated-theme") + expect(config.scroll_speed).toBe(2) + + const text = await Filesystem.readText(path.join(tmp.path, "tui.json")) + const migrated = JSON.parse(text) + expect(migrated.scroll_speed).toBe(2) + expect(migrated.foo).toBeUndefined() + }, + }) +}) + +test("skips migration when opencode.jsonc is syntactically invalid", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.jsonc"), + `{ + "theme": "broken-theme", + "tui": { "scroll_speed": 2 } + "username": "still-broken" +}`, + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBeUndefined() + expect(config.scroll_speed).toBeUndefined() + expect(await Filesystem.exists(path.join(tmp.path, "tui.json"))).toBe(false) + expect(await Filesystem.exists(path.join(tmp.path, "opencode.jsonc.tui-migration.bak"))).toBe(false) + const source = await Filesystem.readText(path.join(tmp.path, "opencode.jsonc")) + expect(source).toContain('"theme": "broken-theme"') + expect(source).toContain('"tui": { "scroll_speed": 2 }') + }, + }) +}) + +test("skips migration when tui.json already exists", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ theme: "legacy" }, null, 2)) + await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ diff_style: "stacked" }, null, 2)) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.diff_style).toBe("stacked") + expect(config.theme).toBeUndefined() + + const server = JSON.parse(await Filesystem.readText(path.join(tmp.path, "opencode.json"))) + expect(server.theme).toBe("legacy") + expect(await Filesystem.exists(path.join(tmp.path, "opencode.json.tui-migration.bak"))).toBe(false) + }, + }) +}) + +test("continues loading tui config when legacy source cannot be stripped", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ theme: "readonly-theme" }, null, 2)) + }, + }) + + const source = path.join(tmp.path, "opencode.json") + await fs.chmod(source, 0o444) + + try { + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("readonly-theme") + expect(await Filesystem.exists(path.join(tmp.path, "tui.json"))).toBe(true) + + const server = JSON.parse(await Filesystem.readText(source)) + expect(server.theme).toBe("readonly-theme") + }, + }) + } finally { + await fs.chmod(source, 0o644) + } +}) + +test("migration backup preserves JSONC comments", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.jsonc"), + `{ + // top-level comment + "theme": "jsonc-theme", + "tui": { + // nested comment + "scroll_speed": 1.5 + } +}`, + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + await TuiConfig.get() + const backup = await Filesystem.readText(path.join(tmp.path, "opencode.jsonc.tui-migration.bak")) + expect(backup).toContain("// top-level comment") + expect(backup).toContain("// nested comment") + expect(backup).toContain('"theme": "jsonc-theme"') + expect(backup).toContain('"scroll_speed": 1.5') + }, + }) +}) + +test("migrates legacy tui keys across multiple opencode.json levels", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const nested = path.join(dir, "apps", "client") + await fs.mkdir(nested, { recursive: true }) + await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ theme: "root-theme" }, null, 2)) + await Bun.write(path.join(nested, "opencode.json"), JSON.stringify({ theme: "nested-theme" }, null, 2)) + }, + }) + + await Instance.provide({ + directory: path.join(tmp.path, "apps", "client"), + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("nested-theme") + expect(await Filesystem.exists(path.join(tmp.path, "tui.json"))).toBe(true) + expect(await Filesystem.exists(path.join(tmp.path, "apps", "client", "tui.json"))).toBe(true) + }, + }) +}) + +test("flattens nested tui key inside tui.json", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "tui.json"), + JSON.stringify({ + theme: "outer", + tui: { scroll_speed: 3, diff_style: "stacked" }, + }), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.scroll_speed).toBe(3) + expect(config.diff_style).toBe("stacked") + // top-level keys take precedence over nested tui keys + expect(config.theme).toBe("outer") + }, + }) +}) + +test("top-level keys in tui.json take precedence over nested tui key", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "tui.json"), + JSON.stringify({ + diff_style: "auto", + tui: { diff_style: "stacked", scroll_speed: 2 }, + }), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.diff_style).toBe("auto") + expect(config.scroll_speed).toBe(2) + }, + }) +}) + +test("project config takes precedence over OPENCODE_TUI_CONFIG (matches OPENCODE_CONFIG)", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ theme: "project", diff_style: "auto" })) + const custom = path.join(dir, "custom-tui.json") + await Bun.write(custom, JSON.stringify({ theme: "custom", diff_style: "stacked" })) + process.env.OPENCODE_TUI_CONFIG = custom + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + // project tui.json overrides the custom path, same as server config precedence + expect(config.theme).toBe("project") + // project also set diff_style, so that wins + expect(config.diff_style).toBe("auto") + }, + }) +}) + +test("merges keybind overrides across precedence layers", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(Global.Path.config, "tui.json"), JSON.stringify({ keybinds: { app_exit: "ctrl+q" } })) + await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ keybinds: { theme_list: "ctrl+k" } })) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.keybinds?.app_exit).toBe("ctrl+q") + expect(config.keybinds?.theme_list).toBe("ctrl+k") + }, + }) +}) + +test("OPENCODE_TUI_CONFIG provides settings when no project config exists", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const custom = path.join(dir, "custom-tui.json") + await Bun.write(custom, JSON.stringify({ theme: "from-env", diff_style: "stacked" })) + process.env.OPENCODE_TUI_CONFIG = custom + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("from-env") + expect(config.diff_style).toBe("stacked") + }, + }) +}) + +test("does not derive tui path from OPENCODE_CONFIG", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const customDir = path.join(dir, "custom") + await fs.mkdir(customDir, { recursive: true }) + await Bun.write(path.join(customDir, "opencode.json"), JSON.stringify({ model: "test/model" })) + await Bun.write(path.join(customDir, "tui.json"), JSON.stringify({ theme: "should-not-load" })) + process.env.OPENCODE_CONFIG = path.join(customDir, "opencode.json") + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBeUndefined() + }, + }) +}) + +test("applies env and file substitutions in tui.json", async () => { + const original = process.env.TUI_THEME_TEST + process.env.TUI_THEME_TEST = "env-theme" + try { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "keybind.txt"), "ctrl+q") + await Bun.write( + path.join(dir, "tui.json"), + JSON.stringify({ + theme: "{env:TUI_THEME_TEST}", + keybinds: { app_exit: "{file:keybind.txt}" }, + }), + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("env-theme") + expect(config.keybinds?.app_exit).toBe("ctrl+q") + }, + }) + } finally { + if (original === undefined) delete process.env.TUI_THEME_TEST + else process.env.TUI_THEME_TEST = original + } +}) + +test("applies file substitutions when first identical token is in a commented line", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "theme.txt"), "resolved-theme") + await Bun.write( + path.join(dir, "tui.jsonc"), + `{ + // "theme": "{file:theme.txt}", + "theme": "{file:theme.txt}" +}`, + ) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("resolved-theme") + }, + }) +}) + +test("loads managed tui config and gives it highest precedence", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ theme: "project-theme" }, null, 2)) + await fs.mkdir(managedConfigDir, { recursive: true }) + await Bun.write(path.join(managedConfigDir, "tui.json"), JSON.stringify({ theme: "managed-theme" }, null, 2)) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("managed-theme") + }, + }) +}) + +test("loads .opencode/tui.json", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await fs.mkdir(path.join(dir, ".opencode"), { recursive: true }) + await Bun.write(path.join(dir, ".opencode", "tui.json"), JSON.stringify({ diff_style: "stacked" }, null, 2)) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.diff_style).toBe("stacked") + }, + }) +}) + +test("gracefully falls back when tui.json has invalid JSON", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "tui.json"), "{ invalid json }") + await fs.mkdir(managedConfigDir, { recursive: true }) + await Bun.write(path.join(managedConfigDir, "tui.json"), JSON.stringify({ theme: "managed-fallback" }, null, 2)) + }, + }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await TuiConfig.get() + expect(config.theme).toBe("managed-fallback") + expect(config.keybinds).toBeDefined() + }, + }) +}) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 28d5caa02bb..be6c00cf445 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -991,388 +991,6 @@ export type GlobalEvent = { payload: Event } -/** - * Custom keybind configurations - */ -export type KeybindsConfig = { - /** - * Leader key for keybind combinations - */ - leader?: string - /** - * Exit the application - */ - app_exit?: string - /** - * Open external editor - */ - editor_open?: string - /** - * List available themes - */ - theme_list?: string - /** - * Toggle sidebar - */ - sidebar_toggle?: string - /** - * Toggle session scrollbar - */ - scrollbar_toggle?: string - /** - * Toggle username visibility - */ - username_toggle?: string - /** - * View status - */ - status_view?: string - /** - * Export session to editor - */ - session_export?: string - /** - * Create a new session - */ - session_new?: string - /** - * List all sessions - */ - session_list?: string - /** - * Show session timeline - */ - session_timeline?: string - /** - * Fork session from message - */ - session_fork?: string - /** - * Rename session - */ - session_rename?: string - /** - * Delete session - */ - session_delete?: string - /** - * Delete stash entry - */ - stash_delete?: string - /** - * Open provider list from model dialog - */ - model_provider_list?: string - /** - * Toggle model favorite status - */ - model_favorite_toggle?: string - /** - * Share current session - */ - session_share?: string - /** - * Unshare current session - */ - session_unshare?: string - /** - * Interrupt current session - */ - session_interrupt?: string - /** - * Compact the session - */ - session_compact?: string - /** - * Scroll messages up by one page - */ - messages_page_up?: string - /** - * Scroll messages down by one page - */ - messages_page_down?: string - /** - * Scroll messages up by one line - */ - messages_line_up?: string - /** - * Scroll messages down by one line - */ - messages_line_down?: string - /** - * Scroll messages up by half page - */ - messages_half_page_up?: string - /** - * Scroll messages down by half page - */ - messages_half_page_down?: string - /** - * Navigate to first message - */ - messages_first?: string - /** - * Navigate to last message - */ - messages_last?: string - /** - * Navigate to next message - */ - messages_next?: string - /** - * Navigate to previous message - */ - messages_previous?: string - /** - * Navigate to last user message - */ - messages_last_user?: string - /** - * Copy message - */ - messages_copy?: string - /** - * Undo message - */ - messages_undo?: string - /** - * Redo message - */ - messages_redo?: string - /** - * Toggle code block concealment in messages - */ - messages_toggle_conceal?: string - /** - * Toggle tool details visibility - */ - tool_details?: string - /** - * List available models - */ - model_list?: string - /** - * Next recently used model - */ - model_cycle_recent?: string - /** - * Previous recently used model - */ - model_cycle_recent_reverse?: string - /** - * Next favorite model - */ - model_cycle_favorite?: string - /** - * Previous favorite model - */ - model_cycle_favorite_reverse?: string - /** - * List available commands - */ - command_list?: string - /** - * List agents - */ - agent_list?: string - /** - * Next agent - */ - agent_cycle?: string - /** - * Previous agent - */ - agent_cycle_reverse?: string - /** - * Cycle model variants - */ - variant_cycle?: string - /** - * Clear input field - */ - input_clear?: string - /** - * Paste from clipboard - */ - input_paste?: string - /** - * Submit input - */ - input_submit?: string - /** - * Insert newline in input - */ - input_newline?: string - /** - * Move cursor left in input - */ - input_move_left?: string - /** - * Move cursor right in input - */ - input_move_right?: string - /** - * Move cursor up in input - */ - input_move_up?: string - /** - * Move cursor down in input - */ - input_move_down?: string - /** - * Select left in input - */ - input_select_left?: string - /** - * Select right in input - */ - input_select_right?: string - /** - * Select up in input - */ - input_select_up?: string - /** - * Select down in input - */ - input_select_down?: string - /** - * Move to start of line in input - */ - input_line_home?: string - /** - * Move to end of line in input - */ - input_line_end?: string - /** - * Select to start of line in input - */ - input_select_line_home?: string - /** - * Select to end of line in input - */ - input_select_line_end?: string - /** - * Move to start of visual line in input - */ - input_visual_line_home?: string - /** - * Move to end of visual line in input - */ - input_visual_line_end?: string - /** - * Select to start of visual line in input - */ - input_select_visual_line_home?: string - /** - * Select to end of visual line in input - */ - input_select_visual_line_end?: string - /** - * Move to start of buffer in input - */ - input_buffer_home?: string - /** - * Move to end of buffer in input - */ - input_buffer_end?: string - /** - * Select to start of buffer in input - */ - input_select_buffer_home?: string - /** - * Select to end of buffer in input - */ - input_select_buffer_end?: string - /** - * Delete line in input - */ - input_delete_line?: string - /** - * Delete to end of line in input - */ - input_delete_to_line_end?: string - /** - * Delete to start of line in input - */ - input_delete_to_line_start?: string - /** - * Backspace in input - */ - input_backspace?: string - /** - * Delete character in input - */ - input_delete?: string - /** - * Undo in input - */ - input_undo?: string - /** - * Redo in input - */ - input_redo?: string - /** - * Move word forward in input - */ - input_word_forward?: string - /** - * Move word backward in input - */ - input_word_backward?: string - /** - * Select word forward in input - */ - input_select_word_forward?: string - /** - * Select word backward in input - */ - input_select_word_backward?: string - /** - * Delete word forward in input - */ - input_delete_word_forward?: string - /** - * Delete word backward in input - */ - input_delete_word_backward?: string - /** - * Previous history item - */ - history_previous?: string - /** - * Next history item - */ - history_next?: string - /** - * Next child session - */ - session_child_cycle?: string - /** - * Previous child session - */ - session_child_cycle_reverse?: string - /** - * Go to parent session - */ - session_parent?: string - /** - * Suspend terminal - */ - terminal_suspend?: string - /** - * Toggle terminal title - */ - terminal_title_toggle?: string - /** - * Toggle tips on home screen - */ - tips_toggle?: string - /** - * Toggle thinking blocks visibility - */ - display_thinking?: string -} - /** * Log level */ @@ -1672,34 +1290,7 @@ export type Config = { * JSON schema reference for configuration validation */ $schema?: string - /** - * Theme name to use for the interface - */ - theme?: string - keybinds?: KeybindsConfig logLevel?: LogLevel - /** - * TUI specific settings - */ - tui?: { - /** - * TUI scroll speed - */ - scroll_speed?: number - /** - * Scroll acceleration settings - */ - scroll_acceleration?: { - /** - * Enable scroll acceleration - */ - enabled: boolean - } - /** - * Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column - */ - diff_style?: "auto" | "stacked" - } server?: ServerConfig /** * Command configuration, see https://opencode.ai/docs/commands diff --git a/packages/web/astro.config.mjs b/packages/web/astro.config.mjs index b14a7ccb8f8..612d4fb8cdd 100644 --- a/packages/web/astro.config.mjs +++ b/packages/web/astro.config.mjs @@ -314,7 +314,7 @@ function configSchema() { hooks: { "astro:build:done": async () => { console.log("generating config schema") - spawnSync("../opencode/script/schema.ts", ["./dist/config.json"]) + spawnSync("../opencode/script/schema.ts", ["./dist/config.json", "./dist/tui.json"]) }, }, } diff --git a/packages/web/src/content/docs/cli.mdx b/packages/web/src/content/docs/cli.mdx index c504f734fa5..6b1c3dee57e 100644 --- a/packages/web/src/content/docs/cli.mdx +++ b/packages/web/src/content/docs/cli.mdx @@ -558,6 +558,7 @@ OpenCode can be configured using environment variables. | `OPENCODE_AUTO_SHARE` | boolean | Automatically share sessions | | `OPENCODE_GIT_BASH_PATH` | string | Path to Git Bash executable on Windows | | `OPENCODE_CONFIG` | string | Path to config file | +| `OPENCODE_TUI_CONFIG` | string | Path to TUI config file | | `OPENCODE_CONFIG_DIR` | string | Path to config directory | | `OPENCODE_CONFIG_CONTENT` | string | Inline json config content | | `OPENCODE_DISABLE_AUTOUPDATE` | boolean | Disable automatic update checks | diff --git a/packages/web/src/content/docs/config.mdx b/packages/web/src/content/docs/config.mdx index eeccde2f791..038f253274e 100644 --- a/packages/web/src/content/docs/config.mdx +++ b/packages/web/src/content/docs/config.mdx @@ -14,10 +14,11 @@ OpenCode supports both **JSON** and **JSONC** (JSON with Comments) formats. ```jsonc title="opencode.jsonc" { "$schema": "https://opencode.ai/config.json", - // Theme configuration - "theme": "opencode", "model": "anthropic/claude-sonnet-4-5", "autoupdate": true, + "server": { + "port": 4096, + }, } ``` @@ -34,7 +35,7 @@ Configuration files are **merged together**, not replaced. Configuration files are merged together, not replaced. Settings from the following config locations are combined. Later configs override earlier ones only for conflicting keys. Non-conflicting settings from all configs are preserved. -For example, if your global config sets `theme: "opencode"` and `autoupdate: true`, and your project config sets `model: "anthropic/claude-sonnet-4-5"`, the final configuration will include all three settings. +For example, if your global config sets `autoupdate: true` and your project config sets `model: "anthropic/claude-sonnet-4-5"`, the final configuration will include both settings. --- @@ -95,7 +96,9 @@ You can enable specific servers in your local config: ### Global -Place your global OpenCode config in `~/.config/opencode/opencode.json`. Use global config for user-wide preferences like themes, providers, or keybinds. +Place your global OpenCode config in `~/.config/opencode/opencode.json`. Use global config for user-wide server/runtime preferences like providers, models, and permissions. + +For TUI-specific settings, use `~/.config/opencode/tui.json`. Global config overrides remote organizational defaults. @@ -105,6 +108,8 @@ Global config overrides remote organizational defaults. Add `opencode.json` in your project root. Project config has the highest precedence among standard config files - it overrides both global and remote configs. +For project-specific TUI settings, add `tui.json` alongside it. + :::tip Place project specific config in the root of your project. ::: @@ -146,7 +151,9 @@ The custom directory is loaded after the global config and `.opencode` directori ## Schema -The config file has a schema that's defined in [**`opencode.ai/config.json`**](https://opencode.ai/config.json). +The server/runtime config schema is defined in [**`opencode.ai/config.json`**](https://opencode.ai/config.json). + +TUI config uses [**`opencode.ai/tui.json`**](https://opencode.ai/tui.json). Your editor should be able to validate and autocomplete based on the schema. @@ -154,28 +161,24 @@ Your editor should be able to validate and autocomplete based on the schema. ### TUI -You can configure TUI-specific settings through the `tui` option. +Use a dedicated `tui.json` (or `tui.jsonc`) file for TUI-specific settings. -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", - "tui": { - "scroll_speed": 3, - "scroll_acceleration": { - "enabled": true - }, - "diff_style": "auto" - } + "$schema": "https://opencode.ai/tui.json", + "scroll_speed": 3, + "scroll_acceleration": { + "enabled": true + }, + "diff_style": "auto" } ``` -Available options: +Use `OPENCODE_TUI_CONFIG` to point to a custom TUI config file. -- `scroll_acceleration.enabled` - Enable macOS-style scroll acceleration. **Takes precedence over `scroll_speed`.** -- `scroll_speed` - Custom scroll speed multiplier (default: `3`, minimum: `1`). Ignored if `scroll_acceleration.enabled` is `true`. -- `diff_style` - Control diff rendering. `"auto"` adapts to terminal width, `"stacked"` always shows single column. +Legacy `theme`, `keybinds`, and `tui` keys in `opencode.json` are deprecated and automatically migrated when possible. -[Learn more about using the TUI here](/docs/tui). +[Learn more about TUI configuration here](/docs/tui#configure). --- @@ -301,12 +304,12 @@ Bearer tokens (`AWS_BEARER_TOKEN_BEDROCK` or `/connect`) take precedence over pr ### Themes -You can configure the theme you want to use in your OpenCode config through the `theme` option. +Set your UI theme in `tui.json`. -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", - "theme": "" + "$schema": "https://opencode.ai/tui.json", + "theme": "tokyonight" } ``` @@ -406,11 +409,11 @@ You can also define commands using markdown files in `~/.config/opencode/command ### Keybinds -You can customize your keybinds through the `keybinds` option. +Customize keybinds in `tui.json`. -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", + "$schema": "https://opencode.ai/tui.json", "keybinds": {} } ``` diff --git a/packages/web/src/content/docs/keybinds.mdx b/packages/web/src/content/docs/keybinds.mdx index 25fe2a1d910..95b3d496391 100644 --- a/packages/web/src/content/docs/keybinds.mdx +++ b/packages/web/src/content/docs/keybinds.mdx @@ -3,11 +3,11 @@ title: Keybinds description: Customize your keybinds. --- -OpenCode has a list of keybinds that you can customize through the OpenCode config. +OpenCode has a list of keybinds that you can customize through `tui.json`. -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", + "$schema": "https://opencode.ai/tui.json", "keybinds": { "leader": "ctrl+x", "app_exit": "ctrl+c,ctrl+d,q", @@ -117,11 +117,11 @@ You don't need to use a leader key for your keybinds but we recommend doing so. ## Disable keybind -You can disable a keybind by adding the key to your config with a value of "none". +You can disable a keybind by adding the key to `tui.json` with a value of "none". -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", + "$schema": "https://opencode.ai/tui.json", "keybinds": { "session_compact": "none" } diff --git a/packages/web/src/content/docs/themes.mdx b/packages/web/src/content/docs/themes.mdx index d37ce313556..8a7c6a46ac8 100644 --- a/packages/web/src/content/docs/themes.mdx +++ b/packages/web/src/content/docs/themes.mdx @@ -61,11 +61,11 @@ The system theme is for users who: ## Using a theme -You can select a theme by bringing up the theme select with the `/theme` command. Or you can specify it in your [config](/docs/config). +You can select a theme by bringing up the theme select with the `/theme` command. Or you can specify it in `tui.json`. -```json title="opencode.json" {3} +```json title="tui.json" {3} { - "$schema": "https://opencode.ai/config.json", + "$schema": "https://opencode.ai/tui.json", "theme": "tokyonight" } ``` diff --git a/packages/web/src/content/docs/tui.mdx b/packages/web/src/content/docs/tui.mdx index 1e48d42ccb1..010e8328f41 100644 --- a/packages/web/src/content/docs/tui.mdx +++ b/packages/web/src/content/docs/tui.mdx @@ -355,24 +355,34 @@ Some editors need command-line arguments to run in blocking mode. The `--wait` f ## Configure -You can customize TUI behavior through your OpenCode config file. +You can customize TUI behavior through `tui.json` (or `tui.jsonc`). -```json title="opencode.json" +```json title="tui.json" { - "$schema": "https://opencode.ai/config.json", - "tui": { - "scroll_speed": 3, - "scroll_acceleration": { - "enabled": true - } - } + "$schema": "https://opencode.ai/tui.json", + "theme": "opencode", + "keybinds": { + "leader": "ctrl+x" + }, + "scroll_speed": 3, + "scroll_acceleration": { + "enabled": true + }, + "diff_style": "auto" } ``` +This is separate from `opencode.json`, which configures server/runtime behavior. + ### Options -- `scroll_acceleration` - Enable macOS-style scroll acceleration for smooth, natural scrolling. When enabled, scroll speed increases with rapid scrolling gestures and stays precise for slower movements. **This setting takes precedence over `scroll_speed` and overrides it when enabled.** -- `scroll_speed` - Controls how fast the TUI scrolls when using scroll commands (minimum: `1`). Defaults to `3`. **Note: This is ignored if `scroll_acceleration.enabled` is set to `true`.** +- `theme` - Sets your UI theme. [Learn more](/docs/themes). +- `keybinds` - Customizes keyboard shortcuts. [Learn more](/docs/keybinds). +- `scroll_acceleration.enabled` - Enable macOS-style scroll acceleration for smooth, natural scrolling. When enabled, scroll speed increases with rapid scrolling gestures and stays precise for slower movements. **This setting takes precedence over `scroll_speed` and overrides it when enabled.** +- `scroll_speed` - Controls how fast the TUI scrolls when using scroll commands (minimum: `0.001`, supports decimal values). Defaults to `3`. **Note: This is ignored if `scroll_acceleration.enabled` is set to `true`.** +- `diff_style` - Controls diff rendering. `"auto"` adapts to terminal width, `"stacked"` always shows a single-column layout. + +Use `OPENCODE_TUI_CONFIG` to load a custom TUI config path. --- From 4551282a4b95cd3f7e6ea4b6ba6a83dd747bb3a0 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Wed, 25 Feb 2026 22:55:09 +0000 Subject: [PATCH 09/23] chore: generate --- packages/sdk/openapi.json | 511 -------------------------------------- 1 file changed, 511 deletions(-) diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 80a4a8d72ae..0f9c6f0203c 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -8721,483 +8721,6 @@ }, "required": ["directory", "payload"] }, - "KeybindsConfig": { - "description": "Custom keybind configurations", - "type": "object", - "properties": { - "leader": { - "description": "Leader key for keybind combinations", - "default": "ctrl+x", - "type": "string" - }, - "app_exit": { - "description": "Exit the application", - "default": "ctrl+c,ctrl+d,q", - "type": "string" - }, - "editor_open": { - "description": "Open external editor", - "default": "e", - "type": "string" - }, - "theme_list": { - "description": "List available themes", - "default": "t", - "type": "string" - }, - "sidebar_toggle": { - "description": "Toggle sidebar", - "default": "b", - "type": "string" - }, - "scrollbar_toggle": { - "description": "Toggle session scrollbar", - "default": "none", - "type": "string" - }, - "username_toggle": { - "description": "Toggle username visibility", - "default": "none", - "type": "string" - }, - "status_view": { - "description": "View status", - "default": "s", - "type": "string" - }, - "session_export": { - "description": "Export session to editor", - "default": "x", - "type": "string" - }, - "session_new": { - "description": "Create a new session", - "default": "n", - "type": "string" - }, - "session_list": { - "description": "List all sessions", - "default": "l", - "type": "string" - }, - "session_timeline": { - "description": "Show session timeline", - "default": "g", - "type": "string" - }, - "session_fork": { - "description": "Fork session from message", - "default": "none", - "type": "string" - }, - "session_rename": { - "description": "Rename session", - "default": "ctrl+r", - "type": "string" - }, - "session_delete": { - "description": "Delete session", - "default": "ctrl+d", - "type": "string" - }, - "stash_delete": { - "description": "Delete stash entry", - "default": "ctrl+d", - "type": "string" - }, - "model_provider_list": { - "description": "Open provider list from model dialog", - "default": "ctrl+a", - "type": "string" - }, - "model_favorite_toggle": { - "description": "Toggle model favorite status", - "default": "ctrl+f", - "type": "string" - }, - "session_share": { - "description": "Share current session", - "default": "none", - "type": "string" - }, - "session_unshare": { - "description": "Unshare current session", - "default": "none", - "type": "string" - }, - "session_interrupt": { - "description": "Interrupt current session", - "default": "escape", - "type": "string" - }, - "session_compact": { - "description": "Compact the session", - "default": "c", - "type": "string" - }, - "messages_page_up": { - "description": "Scroll messages up by one page", - "default": "pageup,ctrl+alt+b", - "type": "string" - }, - "messages_page_down": { - "description": "Scroll messages down by one page", - "default": "pagedown,ctrl+alt+f", - "type": "string" - }, - "messages_line_up": { - "description": "Scroll messages up by one line", - "default": "ctrl+alt+y", - "type": "string" - }, - "messages_line_down": { - "description": "Scroll messages down by one line", - "default": "ctrl+alt+e", - "type": "string" - }, - "messages_half_page_up": { - "description": "Scroll messages up by half page", - "default": "ctrl+alt+u", - "type": "string" - }, - "messages_half_page_down": { - "description": "Scroll messages down by half page", - "default": "ctrl+alt+d", - "type": "string" - }, - "messages_first": { - "description": "Navigate to first message", - "default": "ctrl+g,home", - "type": "string" - }, - "messages_last": { - "description": "Navigate to last message", - "default": "ctrl+alt+g,end", - "type": "string" - }, - "messages_next": { - "description": "Navigate to next message", - "default": "none", - "type": "string" - }, - "messages_previous": { - "description": "Navigate to previous message", - "default": "none", - "type": "string" - }, - "messages_last_user": { - "description": "Navigate to last user message", - "default": "none", - "type": "string" - }, - "messages_copy": { - "description": "Copy message", - "default": "y", - "type": "string" - }, - "messages_undo": { - "description": "Undo message", - "default": "u", - "type": "string" - }, - "messages_redo": { - "description": "Redo message", - "default": "r", - "type": "string" - }, - "messages_toggle_conceal": { - "description": "Toggle code block concealment in messages", - "default": "h", - "type": "string" - }, - "tool_details": { - "description": "Toggle tool details visibility", - "default": "none", - "type": "string" - }, - "model_list": { - "description": "List available models", - "default": "m", - "type": "string" - }, - "model_cycle_recent": { - "description": "Next recently used model", - "default": "f2", - "type": "string" - }, - "model_cycle_recent_reverse": { - "description": "Previous recently used model", - "default": "shift+f2", - "type": "string" - }, - "model_cycle_favorite": { - "description": "Next favorite model", - "default": "none", - "type": "string" - }, - "model_cycle_favorite_reverse": { - "description": "Previous favorite model", - "default": "none", - "type": "string" - }, - "command_list": { - "description": "List available commands", - "default": "ctrl+p", - "type": "string" - }, - "agent_list": { - "description": "List agents", - "default": "a", - "type": "string" - }, - "agent_cycle": { - "description": "Next agent", - "default": "tab", - "type": "string" - }, - "agent_cycle_reverse": { - "description": "Previous agent", - "default": "shift+tab", - "type": "string" - }, - "variant_cycle": { - "description": "Cycle model variants", - "default": "ctrl+t", - "type": "string" - }, - "input_clear": { - "description": "Clear input field", - "default": "ctrl+c", - "type": "string" - }, - "input_paste": { - "description": "Paste from clipboard", - "default": "ctrl+v", - "type": "string" - }, - "input_submit": { - "description": "Submit input", - "default": "return", - "type": "string" - }, - "input_newline": { - "description": "Insert newline in input", - "default": "shift+return,ctrl+return,alt+return,ctrl+j", - "type": "string" - }, - "input_move_left": { - "description": "Move cursor left in input", - "default": "left,ctrl+b", - "type": "string" - }, - "input_move_right": { - "description": "Move cursor right in input", - "default": "right,ctrl+f", - "type": "string" - }, - "input_move_up": { - "description": "Move cursor up in input", - "default": "up", - "type": "string" - }, - "input_move_down": { - "description": "Move cursor down in input", - "default": "down", - "type": "string" - }, - "input_select_left": { - "description": "Select left in input", - "default": "shift+left", - "type": "string" - }, - "input_select_right": { - "description": "Select right in input", - "default": "shift+right", - "type": "string" - }, - "input_select_up": { - "description": "Select up in input", - "default": "shift+up", - "type": "string" - }, - "input_select_down": { - "description": "Select down in input", - "default": "shift+down", - "type": "string" - }, - "input_line_home": { - "description": "Move to start of line in input", - "default": "ctrl+a", - "type": "string" - }, - "input_line_end": { - "description": "Move to end of line in input", - "default": "ctrl+e", - "type": "string" - }, - "input_select_line_home": { - "description": "Select to start of line in input", - "default": "ctrl+shift+a", - "type": "string" - }, - "input_select_line_end": { - "description": "Select to end of line in input", - "default": "ctrl+shift+e", - "type": "string" - }, - "input_visual_line_home": { - "description": "Move to start of visual line in input", - "default": "alt+a", - "type": "string" - }, - "input_visual_line_end": { - "description": "Move to end of visual line in input", - "default": "alt+e", - "type": "string" - }, - "input_select_visual_line_home": { - "description": "Select to start of visual line in input", - "default": "alt+shift+a", - "type": "string" - }, - "input_select_visual_line_end": { - "description": "Select to end of visual line in input", - "default": "alt+shift+e", - "type": "string" - }, - "input_buffer_home": { - "description": "Move to start of buffer in input", - "default": "home", - "type": "string" - }, - "input_buffer_end": { - "description": "Move to end of buffer in input", - "default": "end", - "type": "string" - }, - "input_select_buffer_home": { - "description": "Select to start of buffer in input", - "default": "shift+home", - "type": "string" - }, - "input_select_buffer_end": { - "description": "Select to end of buffer in input", - "default": "shift+end", - "type": "string" - }, - "input_delete_line": { - "description": "Delete line in input", - "default": "ctrl+shift+d", - "type": "string" - }, - "input_delete_to_line_end": { - "description": "Delete to end of line in input", - "default": "ctrl+k", - "type": "string" - }, - "input_delete_to_line_start": { - "description": "Delete to start of line in input", - "default": "ctrl+u", - "type": "string" - }, - "input_backspace": { - "description": "Backspace in input", - "default": "backspace,shift+backspace", - "type": "string" - }, - "input_delete": { - "description": "Delete character in input", - "default": "ctrl+d,delete,shift+delete", - "type": "string" - }, - "input_undo": { - "description": "Undo in input", - "default": "ctrl+-,super+z", - "type": "string" - }, - "input_redo": { - "description": "Redo in input", - "default": "ctrl+.,super+shift+z", - "type": "string" - }, - "input_word_forward": { - "description": "Move word forward in input", - "default": "alt+f,alt+right,ctrl+right", - "type": "string" - }, - "input_word_backward": { - "description": "Move word backward in input", - "default": "alt+b,alt+left,ctrl+left", - "type": "string" - }, - "input_select_word_forward": { - "description": "Select word forward in input", - "default": "alt+shift+f,alt+shift+right", - "type": "string" - }, - "input_select_word_backward": { - "description": "Select word backward in input", - "default": "alt+shift+b,alt+shift+left", - "type": "string" - }, - "input_delete_word_forward": { - "description": "Delete word forward in input", - "default": "alt+d,alt+delete,ctrl+delete", - "type": "string" - }, - "input_delete_word_backward": { - "description": "Delete word backward in input", - "default": "ctrl+w,ctrl+backspace,alt+backspace", - "type": "string" - }, - "history_previous": { - "description": "Previous history item", - "default": "up", - "type": "string" - }, - "history_next": { - "description": "Next history item", - "default": "down", - "type": "string" - }, - "session_child_cycle": { - "description": "Next child session", - "default": "right", - "type": "string" - }, - "session_child_cycle_reverse": { - "description": "Previous child session", - "default": "left", - "type": "string" - }, - "session_parent": { - "description": "Go to parent session", - "default": "up", - "type": "string" - }, - "terminal_suspend": { - "description": "Suspend terminal", - "default": "ctrl+z", - "type": "string" - }, - "terminal_title_toggle": { - "description": "Toggle terminal title", - "default": "none", - "type": "string" - }, - "tips_toggle": { - "description": "Toggle tips on home screen", - "default": "h", - "type": "string" - }, - "display_thinking": { - "description": "Toggle thinking blocks visibility", - "default": "none", - "type": "string" - } - }, - "additionalProperties": false - }, "LogLevel": { "description": "Log level", "type": "string", @@ -9777,43 +9300,9 @@ "description": "JSON schema reference for configuration validation", "type": "string" }, - "theme": { - "description": "Theme name to use for the interface", - "type": "string" - }, - "keybinds": { - "$ref": "#/components/schemas/KeybindsConfig" - }, "logLevel": { "$ref": "#/components/schemas/LogLevel" }, - "tui": { - "description": "TUI specific settings", - "type": "object", - "properties": { - "scroll_speed": { - "description": "TUI scroll speed", - "type": "number", - "minimum": 0.001 - }, - "scroll_acceleration": { - "description": "Scroll acceleration settings", - "type": "object", - "properties": { - "enabled": { - "description": "Enable scroll acceleration", - "type": "boolean" - } - }, - "required": ["enabled"] - }, - "diff_style": { - "description": "Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column", - "type": "string", - "enum": ["auto", "stacked"] - } - } - }, "server": { "$ref": "#/components/schemas/ServerConfig" }, From 444178e079fb41ba2149a1cdfdd3040593715d70 Mon Sep 17 00:00:00 2001 From: OpeOginni <107570612+OpeOginni@users.noreply.github.com> Date: Thu, 26 Feb 2026 00:16:39 +0100 Subject: [PATCH 10/23] fix(docs): update schema URL in share configuration examples across multiple languages (#15114) --- packages/web/src/content/docs/ar/share.mdx | 6 +++--- packages/web/src/content/docs/bs/share.mdx | 6 +++--- packages/web/src/content/docs/da/share.mdx | 6 +++--- packages/web/src/content/docs/de/share.mdx | 6 +++--- packages/web/src/content/docs/es/share.mdx | 6 +++--- packages/web/src/content/docs/fr/share.mdx | 6 +++--- packages/web/src/content/docs/it/share.mdx | 6 +++--- packages/web/src/content/docs/ja/share.mdx | 6 +++--- packages/web/src/content/docs/ko/share.mdx | 6 +++--- packages/web/src/content/docs/nb/share.mdx | 6 +++--- packages/web/src/content/docs/pl/share.mdx | 6 +++--- packages/web/src/content/docs/pt-br/share.mdx | 6 +++--- packages/web/src/content/docs/ru/share.mdx | 6 +++--- packages/web/src/content/docs/share.mdx | 6 +++--- packages/web/src/content/docs/th/share.mdx | 6 +++--- packages/web/src/content/docs/tr/share.mdx | 6 +++--- packages/web/src/content/docs/zh-cn/share.mdx | 6 +++--- packages/web/src/content/docs/zh-tw/share.mdx | 6 +++--- 18 files changed, 54 insertions(+), 54 deletions(-) diff --git a/packages/web/src/content/docs/ar/share.mdx b/packages/web/src/content/docs/ar/share.mdx index 535d44dadf8..6d13410458c 100644 --- a/packages/web/src/content/docs/ar/share.mdx +++ b/packages/web/src/content/docs/ar/share.mdx @@ -41,7 +41,7 @@ description: شارك محادثات OpenCode الخاصة بك. ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ description: شارك محادثات OpenCode الخاصة بك. ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ description: شارك محادثات OpenCode الخاصة بك. ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/bs/share.mdx b/packages/web/src/content/docs/bs/share.mdx index a15e1507434..b0760ee0c13 100644 --- a/packages/web/src/content/docs/bs/share.mdx +++ b/packages/web/src/content/docs/bs/share.mdx @@ -41,7 +41,7 @@ Da eksplicitno postavite rucni nacin u [config datoteci](/docs/config): ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Mozete ukljuciti automatsko dijeljenje za sve nove razgovore tako sto `share` po ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Dijeljenje mozete potpuno iskljuciti tako sto `share` postavite na `"disabled"` ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/da/share.mdx b/packages/web/src/content/docs/da/share.mdx index 1ac2094ca70..80b9f0959e2 100644 --- a/packages/web/src/content/docs/da/share.mdx +++ b/packages/web/src/content/docs/da/share.mdx @@ -41,7 +41,7 @@ For at eksplisitt angi manuell modus i [konfigurasjonsfilen](/docs/config): ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Du kan aktivere automatisk deling for alle nye samtaler ved at sette alternative ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Du kan deaktivere deling helt ved at sette alternativet `share` til `"disabled"` ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/de/share.mdx b/packages/web/src/content/docs/de/share.mdx index 99fad21099b..9b7e9284c7a 100644 --- a/packages/web/src/content/docs/de/share.mdx +++ b/packages/web/src/content/docs/de/share.mdx @@ -43,7 +43,7 @@ Um den manuellen Modus explizit in der [Konfiguration](/docs/config) zu setzen: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -56,7 +56,7 @@ Du kannst automatisches Teilen fuer neue Unterhaltungen aktivieren, indem du in ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -71,7 +71,7 @@ Du kannst Teilen komplett deaktivieren, indem du in der [Konfiguration](/docs/co ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/es/share.mdx b/packages/web/src/content/docs/es/share.mdx index e1c62a031c0..3bb376f3862 100644 --- a/packages/web/src/content/docs/es/share.mdx +++ b/packages/web/src/content/docs/es/share.mdx @@ -41,7 +41,7 @@ Para configurar explícitamente el modo manual en su [archivo de configuración] ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Puede habilitar el uso compartido automático para todas las conversaciones nuev ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Puede desactivar el uso compartido por completo configurando la opción `share` ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/fr/share.mdx b/packages/web/src/content/docs/fr/share.mdx index acc7c03f83e..e6b067a8c82 100644 --- a/packages/web/src/content/docs/fr/share.mdx +++ b/packages/web/src/content/docs/fr/share.mdx @@ -41,7 +41,7 @@ Pour définir explicitement le mode manuel dans votre [fichier de configuration] ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Vous pouvez activer le partage automatique pour toutes les nouvelles conversatio ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Vous pouvez désactiver entièrement le partage en définissant l'option `share` ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/it/share.mdx b/packages/web/src/content/docs/it/share.mdx index f9eff6ca9bd..9b410a6b865 100644 --- a/packages/web/src/content/docs/it/share.mdx +++ b/packages/web/src/content/docs/it/share.mdx @@ -41,7 +41,7 @@ Per impostare esplicitamente la modalita manuale nel tuo [file di config](/docs/ ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Puoi abilitare la condivisione automatica per tutte le nuove conversazioni impos ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Puoi disabilitare completamente la condivisione impostando l'opzione `share` su ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/ja/share.mdx b/packages/web/src/content/docs/ja/share.mdx index 7995ba9a075..606e807dc8a 100644 --- a/packages/web/src/content/docs/ja/share.mdx +++ b/packages/web/src/content/docs/ja/share.mdx @@ -41,7 +41,7 @@ OpenCode は、会話の共有方法を制御する 3 つの共有モードを ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ OpenCode は、会話の共有方法を制御する 3 つの共有モードを ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ OpenCode は、会話の共有方法を制御する 3 つの共有モードを ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/ko/share.mdx b/packages/web/src/content/docs/ko/share.mdx index 55cf6a2c3e3..9e5c6388243 100644 --- a/packages/web/src/content/docs/ko/share.mdx +++ b/packages/web/src/content/docs/ko/share.mdx @@ -41,7 +41,7 @@ opencode는 대화가 공유되는 방법을 제어하는 세 가지 공유 모 ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ opencode는 대화가 공유되는 방법을 제어하는 세 가지 공유 모 ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ opencode는 대화가 공유되는 방법을 제어하는 세 가지 공유 모 ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/nb/share.mdx b/packages/web/src/content/docs/nb/share.mdx index 370477d1cfc..ca0cb4829ac 100644 --- a/packages/web/src/content/docs/nb/share.mdx +++ b/packages/web/src/content/docs/nb/share.mdx @@ -41,7 +41,7 @@ For å eksplisitt angi manuell modus i [konfigurasjonsfilen](/docs/config): ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Du kan aktivere automatisk deling for alle nye samtaler ved å sette alternative ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Du kan deaktivere deling helt ved å sette alternativet `share` til `"disabled"` ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/pl/share.mdx b/packages/web/src/content/docs/pl/share.mdx index 463019295a3..0389267b59a 100644 --- a/packages/web/src/content/docs/pl/share.mdx +++ b/packages/web/src/content/docs/pl/share.mdx @@ -41,7 +41,7 @@ Aby jawnie ustawić tryb ręczny w [pliku konfiguracyjnym] (./config): ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Możesz włączyć automatyczne udostępnianie dla wszystkich nowych rozmów, us ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Możesz całkowicie wyłączyć udostępnianie, ustawiając opcję `share` na `" ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/pt-br/share.mdx b/packages/web/src/content/docs/pt-br/share.mdx index 5aa0439d068..166226d6dc2 100644 --- a/packages/web/src/content/docs/pt-br/share.mdx +++ b/packages/web/src/content/docs/pt-br/share.mdx @@ -41,7 +41,7 @@ Para definir explicitamente o modo manual em seu [arquivo de configuração](/do ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Você pode habilitar o compartilhamento automático para todas as novas conversa ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Você pode desativar o compartilhamento completamente definindo a opção `share ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/ru/share.mdx b/packages/web/src/content/docs/ru/share.mdx index c4df3b6a703..8982afb08df 100644 --- a/packages/web/src/content/docs/ru/share.mdx +++ b/packages/web/src/content/docs/ru/share.mdx @@ -41,7 +41,7 @@ opencode поддерживает три режима общего доступ ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ opencode поддерживает три режима общего доступ ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ opencode поддерживает три режима общего доступ ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/share.mdx b/packages/web/src/content/docs/share.mdx index 475ee08d041..b2c79334097 100644 --- a/packages/web/src/content/docs/share.mdx +++ b/packages/web/src/content/docs/share.mdx @@ -41,7 +41,7 @@ To explicitly set manual mode in your [config file](/docs/config): ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ You can enable automatic sharing for all new conversations by setting the `share ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ You can disable sharing entirely by setting the `share` option to `"disabled"` i ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/th/share.mdx b/packages/web/src/content/docs/th/share.mdx index 195d7696f9b..91bfce44172 100644 --- a/packages/web/src/content/docs/th/share.mdx +++ b/packages/web/src/content/docs/th/share.mdx @@ -41,7 +41,7 @@ OpenCode รองรับโหมดการแชร์สามโหม ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ OpenCode รองรับโหมดการแชร์สามโหม ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ OpenCode รองรับโหมดการแชร์สามโหม ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/tr/share.mdx b/packages/web/src/content/docs/tr/share.mdx index 1b7abfdb7ea..a0544eb02aa 100644 --- a/packages/web/src/content/docs/tr/share.mdx +++ b/packages/web/src/content/docs/tr/share.mdx @@ -41,7 +41,7 @@ Manuel modu acikca ayarlamak icin [config dosyaniza](/docs/config) sunu ekleyin: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ Tum yeni konusmalar icin otomatik paylasimi acmak isterseniz, [config dosyanizda ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ Paylasimi tamamen kapatmak icin [config dosyanizda](/docs/config) `share` degeri ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/zh-cn/share.mdx b/packages/web/src/content/docs/zh-cn/share.mdx index 8a7be16dc91..a2b34688e4d 100644 --- a/packages/web/src/content/docs/zh-cn/share.mdx +++ b/packages/web/src/content/docs/zh-cn/share.mdx @@ -41,7 +41,7 @@ OpenCode 支持三种分享模式,用于控制对话的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ OpenCode 支持三种分享模式,用于控制对话的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ OpenCode 支持三种分享模式,用于控制对话的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` diff --git a/packages/web/src/content/docs/zh-tw/share.mdx b/packages/web/src/content/docs/zh-tw/share.mdx index 1512007bc35..58365035b64 100644 --- a/packages/web/src/content/docs/zh-tw/share.mdx +++ b/packages/web/src/content/docs/zh-tw/share.mdx @@ -41,7 +41,7 @@ OpenCode 支援三種分享模式,用於控制對話的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "manual" } ``` @@ -54,7 +54,7 @@ OpenCode 支援三種分享模式,用於控制對話的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "auto" } ``` @@ -69,7 +69,7 @@ OpenCode 支援三種分享模式,用於控制對話的共享方式: ```json title="opencode.json" { - "$schema": "https://opncd.ai/config.json", + "$schema": "https://opencode.ai/config.json", "share": "disabled" } ``` From b8337cddc4269ba6e72f74c1e1f39aae41f56af3 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:05:08 -0600 Subject: [PATCH 11/23] fix(app): permissions and questions from child sessions (#15105) Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com> --- .../e2e/session/session-composer-dock.spec.ts | 292 +++++++++++++--- packages/app/src/pages/directory-layout.tsx | 11 +- .../composer/session-composer-state.test.ts | 83 +++++ .../composer/session-composer-state.ts | 22 +- .../session/composer/session-request-tree.ts | 45 +++ packages/ui/src/components/message-part.css | 101 +----- packages/ui/src/components/message-part.tsx | 325 +----------------- packages/ui/src/context/data.tsx | 34 +- 8 files changed, 390 insertions(+), 523 deletions(-) create mode 100644 packages/app/src/pages/session/composer/session-composer-state.test.ts create mode 100644 packages/app/src/pages/session/composer/session-request-tree.ts diff --git a/packages/app/e2e/session/session-composer-dock.spec.ts b/packages/app/e2e/session/session-composer-dock.spec.ts index 6bf7714a66d..e9cfc03e485 100644 --- a/packages/app/e2e/session/session-composer-dock.spec.ts +++ b/packages/app/e2e/session/session-composer-dock.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { clearSessionDockSeed, seedSessionPermission, seedSessionQuestion, seedSessionTodos } from "../actions" +import { clearSessionDockSeed, seedSessionQuestion, seedSessionTodos } from "../actions" import { permissionDockSelector, promptSelector, @@ -11,11 +11,23 @@ import { } from "../selectors" type Sdk = Parameters[0] +type PermissionRule = { permission: string; pattern: string; action: "allow" | "deny" | "ask" } -async function withDockSession(sdk: Sdk, title: string, fn: (session: { id: string; title: string }) => Promise) { - const session = await sdk.session.create({ title }).then((r) => r.data) +async function withDockSession( + sdk: Sdk, + title: string, + fn: (session: { id: string; title: string }) => Promise, + opts?: { permission?: PermissionRule[] }, +) { + const session = await sdk.session + .create(opts?.permission ? { title, permission: opts.permission } : { title }) + .then((r) => r.data) if (!session?.id) throw new Error("Session create did not return an id") - return fn(session) + try { + return await fn(session) + } finally { + await sdk.session.delete({ sessionID: session.id }).catch(() => undefined) + } } test.setTimeout(120_000) @@ -28,6 +40,85 @@ async function withDockSeed(sdk: Sdk, sessionID: string, fn: () => Promise } } +async function clearPermissionDock(page: any, label: RegExp) { + const dock = page.locator(permissionDockSelector) + for (let i = 0; i < 3; i++) { + const count = await dock.count() + if (count === 0) return + await dock.getByRole("button", { name: label }).click() + await page.waitForTimeout(150) + } +} + +async function withMockPermission( + page: any, + request: { + id: string + sessionID: string + permission: string + patterns: string[] + metadata?: Record + always?: string[] + }, + opts: { child?: any } | undefined, + fn: () => Promise, +) { + let pending = [ + { + ...request, + always: request.always ?? ["*"], + metadata: request.metadata ?? {}, + }, + ] + + const list = async (route: any) => { + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(pending), + }) + } + + const reply = async (route: any) => { + const url = new URL(route.request().url()) + const id = url.pathname.split("/").pop() + pending = pending.filter((item) => item.id !== id) + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(true), + }) + } + + await page.route("**/permission", list) + await page.route("**/session/*/permissions/*", reply) + + const sessionList = opts?.child + ? async (route: any) => { + const res = await route.fetch() + const json = await res.json() + const list = Array.isArray(json) ? json : Array.isArray(json?.data) ? json.data : undefined + if (Array.isArray(list) && !list.some((item) => item?.id === opts.child?.id)) list.push(opts.child) + await route.fulfill({ + status: res.status(), + headers: res.headers(), + contentType: "application/json", + body: JSON.stringify(json), + }) + } + : undefined + + if (sessionList) await page.route("**/session?*", sessionList) + + try { + return await fn() + } finally { + await page.unroute("**/permission", list) + await page.unroute("**/session/*/permissions/*", reply) + if (sessionList) await page.unroute("**/session?*", sessionList) + } +} + test("default dock shows prompt input", async ({ page, sdk, gotoSession }) => { await withDockSession(sdk, "e2e composer dock default", async (session) => { await gotoSession(session.id) @@ -76,72 +167,175 @@ test("blocked question flow unblocks after submit", async ({ page, sdk, gotoSess test("blocked permission flow supports allow once", async ({ page, sdk, gotoSession }) => { await withDockSession(sdk, "e2e composer dock permission once", async (session) => { - await withDockSeed(sdk, session.id, async () => { - await gotoSession(session.id) - - await seedSessionPermission(sdk, { + await gotoSession(session.id) + await withMockPermission( + page, + { + id: "per_e2e_once", sessionID: session.id, permission: "bash", - patterns: ["README.md"], - description: "Need permission for command", - }) + patterns: ["/tmp/opencode-e2e-perm-once"], + metadata: { description: "Need permission for command" }, + }, + undefined, + async () => { + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) + await expect(page.locator(promptSelector)).toHaveCount(0) - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) - await expect(page.locator(promptSelector)).toHaveCount(0) - - await page - .locator(permissionDockSelector) - .getByRole("button", { name: /allow once/i }) - .click() - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) - await expect(page.locator(promptSelector)).toBeVisible() - }) + await clearPermissionDock(page, /allow once/i) + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) + await expect(page.locator(promptSelector)).toBeVisible() + }, + ) }) }) test("blocked permission flow supports reject", async ({ page, sdk, gotoSession }) => { await withDockSession(sdk, "e2e composer dock permission reject", async (session) => { - await withDockSeed(sdk, session.id, async () => { - await gotoSession(session.id) - - await seedSessionPermission(sdk, { + await gotoSession(session.id) + await withMockPermission( + page, + { + id: "per_e2e_reject", sessionID: session.id, permission: "bash", - patterns: ["REJECT.md"], - }) + patterns: ["/tmp/opencode-e2e-perm-reject"], + }, + undefined, + async () => { + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) + await expect(page.locator(promptSelector)).toHaveCount(0) - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) - await expect(page.locator(promptSelector)).toHaveCount(0) - - await page.locator(permissionDockSelector).getByRole("button", { name: /deny/i }).click() - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) - await expect(page.locator(promptSelector)).toBeVisible() - }) + await clearPermissionDock(page, /deny/i) + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) + await expect(page.locator(promptSelector)).toBeVisible() + }, + ) }) }) test("blocked permission flow supports allow always", async ({ page, sdk, gotoSession }) => { await withDockSession(sdk, "e2e composer dock permission always", async (session) => { - await withDockSeed(sdk, session.id, async () => { - await gotoSession(session.id) - - await seedSessionPermission(sdk, { + await gotoSession(session.id) + await withMockPermission( + page, + { + id: "per_e2e_always", sessionID: session.id, permission: "bash", - patterns: ["README.md"], - description: "Need permission for command", + patterns: ["/tmp/opencode-e2e-perm-always"], + metadata: { description: "Need permission for command" }, + }, + undefined, + async () => { + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) + await expect(page.locator(promptSelector)).toHaveCount(0) + + await clearPermissionDock(page, /allow always/i) + await page.goto(page.url()) + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) + await expect(page.locator(promptSelector)).toBeVisible() + }, + ) + }) +}) + +test("child session question request blocks parent dock and unblocks after submit", async ({ + page, + sdk, + gotoSession, +}) => { + await withDockSession(sdk, "e2e composer dock child question parent", async (session) => { + await gotoSession(session.id) + + const child = await sdk.session + .create({ + title: "e2e composer dock child question", + parentID: session.id, }) + .then((r) => r.data) + if (!child?.id) throw new Error("Child session create did not return an id") - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(1) - await expect(page.locator(promptSelector)).toHaveCount(0) + try { + await withDockSeed(sdk, child.id, async () => { + await seedSessionQuestion(sdk, { + sessionID: child.id, + questions: [ + { + header: "Child input", + question: "Pick one child option", + options: [ + { label: "Continue", description: "Continue child" }, + { label: "Stop", description: "Stop child" }, + ], + }, + ], + }) - await page - .locator(permissionDockSelector) - .getByRole("button", { name: /allow always/i }) - .click() - await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) - await expect(page.locator(promptSelector)).toBeVisible() - }) + const dock = page.locator(questionDockSelector) + await expect.poll(() => dock.count(), { timeout: 10_000 }).toBe(1) + await expect(page.locator(promptSelector)).toHaveCount(0) + + await dock.locator('[data-slot="question-option"]').first().click() + await dock.getByRole("button", { name: /submit/i }).click() + + await expect.poll(() => page.locator(questionDockSelector).count(), { timeout: 10_000 }).toBe(0) + await expect(page.locator(promptSelector)).toBeVisible() + }) + } finally { + await sdk.session.delete({ sessionID: child.id }).catch(() => undefined) + } + }) +}) + +test("child session permission request blocks parent dock and supports allow once", async ({ + page, + sdk, + gotoSession, +}) => { + await withDockSession(sdk, "e2e composer dock child permission parent", async (session) => { + await gotoSession(session.id) + + const child = await sdk.session + .create({ + title: "e2e composer dock child permission", + parentID: session.id, + }) + .then((r) => r.data) + if (!child?.id) throw new Error("Child session create did not return an id") + + try { + await withMockPermission( + page, + { + id: "per_e2e_child", + sessionID: child.id, + permission: "bash", + patterns: ["/tmp/opencode-e2e-perm-child"], + metadata: { description: "Need child permission" }, + }, + { child }, + async () => { + await page.goto(page.url()) + const dock = page.locator(permissionDockSelector) + await expect.poll(() => dock.count(), { timeout: 10_000 }).toBe(1) + await expect(page.locator(promptSelector)).toHaveCount(0) + + await clearPermissionDock(page, /allow once/i) + await page.goto(page.url()) + + await expect.poll(() => page.locator(permissionDockSelector).count(), { timeout: 10_000 }).toBe(0) + await expect(page.locator(promptSelector)).toBeVisible() + }, + ) + } finally { + await sdk.session.delete({ sessionID: child.id }).catch(() => undefined) + } }) }) diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx index 4f1d93ab282..71b52180f2e 100644 --- a/packages/app/src/pages/directory-layout.tsx +++ b/packages/app/src/pages/directory-layout.tsx @@ -1,12 +1,11 @@ import { createEffect, createMemo, Show, type ParentProps } from "solid-js" import { createStore } from "solid-js/store" import { useNavigate, useParams } from "@solidjs/router" -import { SDKProvider, useSDK } from "@/context/sdk" +import { SDKProvider } from "@/context/sdk" import { SyncProvider, useSync } from "@/context/sync" import { LocalProvider } from "@/context/local" import { DataProvider } from "@opencode-ai/ui/context" -import type { QuestionAnswer } from "@opencode-ai/sdk/v2" import { decode64 } from "@/utils/base64" import { showToast } from "@opencode-ai/ui/toast" import { useLanguage } from "@/context/language" @@ -15,19 +14,11 @@ function DirectoryDataProvider(props: ParentProps<{ directory: string }>) { const params = useParams() const navigate = useNavigate() const sync = useSync() - const sdk = useSDK() return ( sdk.client.permission.respond(input)} - onQuestionReply={(input: { requestID: string; answers: QuestionAnswer[] }) => sdk.client.question.reply(input)} - onQuestionReject={(input: { requestID: string }) => sdk.client.question.reject(input)} onNavigateToSession={(sessionID: string) => navigate(`/${params.dir}/session/${sessionID}`)} onSessionHref={(sessionID: string) => `/${params.dir}/session/${sessionID}`} > diff --git a/packages/app/src/pages/session/composer/session-composer-state.test.ts b/packages/app/src/pages/session/composer/session-composer-state.test.ts new file mode 100644 index 00000000000..7b6029eb31b --- /dev/null +++ b/packages/app/src/pages/session/composer/session-composer-state.test.ts @@ -0,0 +1,83 @@ +import { describe, expect, test } from "bun:test" +import type { PermissionRequest, QuestionRequest, Session } from "@opencode-ai/sdk/v2/client" +import { sessionPermissionRequest, sessionQuestionRequest } from "./session-request-tree" + +const session = (input: { id: string; parentID?: string }) => + ({ + id: input.id, + parentID: input.parentID, + }) as Session + +const permission = (id: string, sessionID: string) => + ({ + id, + sessionID, + }) as PermissionRequest + +const question = (id: string, sessionID: string) => + ({ + id, + sessionID, + questions: [], + }) as QuestionRequest + +describe("sessionPermissionRequest", () => { + test("prefers the current session permission", () => { + const sessions = [session({ id: "root" }), session({ id: "child", parentID: "root" })] + const permissions = { + root: [permission("perm-root", "root")], + child: [permission("perm-child", "child")], + } + + expect(sessionPermissionRequest(sessions, permissions, "root")?.id).toBe("perm-root") + }) + + test("returns a nested child permission", () => { + const sessions = [ + session({ id: "root" }), + session({ id: "child", parentID: "root" }), + session({ id: "grand", parentID: "child" }), + session({ id: "other" }), + ] + const permissions = { + grand: [permission("perm-grand", "grand")], + other: [permission("perm-other", "other")], + } + + expect(sessionPermissionRequest(sessions, permissions, "root")?.id).toBe("perm-grand") + }) + + test("returns undefined without a matching tree permission", () => { + const sessions = [session({ id: "root" }), session({ id: "child", parentID: "root" })] + const permissions = { + other: [permission("perm-other", "other")], + } + + expect(sessionPermissionRequest(sessions, permissions, "root")).toBeUndefined() + }) +}) + +describe("sessionQuestionRequest", () => { + test("prefers the current session question", () => { + const sessions = [session({ id: "root" }), session({ id: "child", parentID: "root" })] + const questions = { + root: [question("q-root", "root")], + child: [question("q-child", "child")], + } + + expect(sessionQuestionRequest(sessions, questions, "root")?.id).toBe("q-root") + }) + + test("returns a nested child question", () => { + const sessions = [ + session({ id: "root" }), + session({ id: "child", parentID: "root" }), + session({ id: "grand", parentID: "child" }), + ] + const questions = { + grand: [question("q-grand", "grand")], + } + + expect(sessionQuestionRequest(sessions, questions, "root")?.id).toBe("q-grand") + }) +}) diff --git a/packages/app/src/pages/session/composer/session-composer-state.ts b/packages/app/src/pages/session/composer/session-composer-state.ts index 04c6f7e692a..ed65867ef00 100644 --- a/packages/app/src/pages/session/composer/session-composer-state.ts +++ b/packages/app/src/pages/session/composer/session-composer-state.ts @@ -7,14 +7,20 @@ import { useGlobalSync } from "@/context/global-sync" import { useLanguage } from "@/context/language" import { useSDK } from "@/context/sdk" import { useSync } from "@/context/sync" +import { sessionPermissionRequest, sessionQuestionRequest } from "./session-request-tree" export function createSessionComposerBlocked() { const params = useParams() const sync = useSync() + const permissionRequest = createMemo(() => + sessionPermissionRequest(sync.data.session, sync.data.permission, params.id), + ) + const questionRequest = createMemo(() => sessionQuestionRequest(sync.data.session, sync.data.question, params.id)) + return createMemo(() => { const id = params.id if (!id) return false - return !!sync.data.permission[id]?.[0] || !!sync.data.question[id]?.[0] + return !!permissionRequest() || !!questionRequest() }) } @@ -26,18 +32,18 @@ export function createSessionComposerState() { const language = useLanguage() const questionRequest = createMemo((): QuestionRequest | undefined => { - const id = params.id - if (!id) return - return sync.data.question[id]?.[0] + return sessionQuestionRequest(sync.data.session, sync.data.question, params.id) }) const permissionRequest = createMemo((): PermissionRequest | undefined => { - const id = params.id - if (!id) return - return sync.data.permission[id]?.[0] + return sessionPermissionRequest(sync.data.session, sync.data.permission, params.id) }) - const blocked = createSessionComposerBlocked() + const blocked = createMemo(() => { + const id = params.id + if (!id) return false + return !!permissionRequest() || !!questionRequest() + }) const todos = createMemo((): Todo[] => { const id = params.id diff --git a/packages/app/src/pages/session/composer/session-request-tree.ts b/packages/app/src/pages/session/composer/session-request-tree.ts new file mode 100644 index 00000000000..f9673e25494 --- /dev/null +++ b/packages/app/src/pages/session/composer/session-request-tree.ts @@ -0,0 +1,45 @@ +import type { PermissionRequest, QuestionRequest, Session } from "@opencode-ai/sdk/v2/client" + +function sessionTreeRequest(session: Session[], request: Record, sessionID?: string) { + if (!sessionID) return + + const map = session.reduce((acc, item) => { + if (!item.parentID) return acc + const list = acc.get(item.parentID) + if (list) list.push(item.id) + if (!list) acc.set(item.parentID, [item.id]) + return acc + }, new Map()) + + const seen = new Set([sessionID]) + const ids = [sessionID] + for (const id of ids) { + const list = map.get(id) + if (!list) continue + for (const child of list) { + if (seen.has(child)) continue + seen.add(child) + ids.push(child) + } + } + + const id = ids.find((id) => !!request[id]?.[0]) + if (!id) return + return request[id]?.[0] +} + +export function sessionPermissionRequest( + session: Session[], + request: Record, + sessionID?: string, +) { + return sessionTreeRequest(session, request, sessionID) +} + +export function sessionQuestionRequest( + session: Session[], + request: Record, + sessionID?: string, +) { + return sessionTreeRequest(session, request, sessionID) +} diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index f063076e079..bea33ff54cf 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -660,105 +660,6 @@ [data-component="tool-part-wrapper"] { width: 100%; - - &[data-permission="true"], - &[data-question="true"] { - position: sticky; - top: calc(2px + var(--sticky-header-height, 40px)); - bottom: 0px; - z-index: 20; - border-radius: 6px; - border: none; - box-shadow: var(--shadow-xs-border-base); - background-color: var(--surface-raised-base); - overflow: visible; - overflow-anchor: none; - - & > *:first-child { - border-top-left-radius: 6px; - border-top-right-radius: 6px; - overflow: hidden; - } - - & > *:last-child { - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; - overflow: hidden; - } - - [data-component="collapsible"] { - border: none; - } - - [data-component="card"] { - border: none; - } - } - - &[data-permission="true"] { - &::before { - content: ""; - position: absolute; - inset: -1.5px; - top: -5px; - border-radius: 7.5px; - border: 1.5px solid transparent; - background: - linear-gradient(var(--background-base) 0 0) padding-box, - conic-gradient( - from var(--border-angle), - transparent 0deg, - transparent 0deg, - var(--border-warning-strong, var(--border-warning-selected)) 300deg, - var(--border-warning-base) 360deg - ) - border-box; - animation: chase-border 2.5s linear infinite; - pointer-events: none; - z-index: -1; - } - } - - &[data-question="true"] { - background: var(--background-base); - border: 1px solid var(--border-weak-base); - } -} - -@property --border-angle { - syntax: ""; - initial-value: 0deg; - inherits: false; -} - -@keyframes chase-border { - from { - --border-angle: 0deg; - } - - to { - --border-angle: 360deg; - } -} - -[data-component="permission-prompt"] { - display: flex; - flex-direction: column; - padding: 8px 12px; - background-color: var(--surface-raised-strong); - border-radius: 0 0 6px 6px; - - [data-slot="permission-actions"] { - display: flex; - align-items: center; - gap: 8px; - justify-content: flex-end; - - [data-component="button"] { - padding-left: 12px; - padding-right: 12px; - } - } } [data-component="dock-prompt"][data-kind="permission"] { @@ -873,7 +774,7 @@ } } -:is([data-component="question-prompt"], [data-component="dock-prompt"][data-kind="question"]) { +[data-component="dock-prompt"][data-kind="question"] { position: relative; display: flex; flex-direction: column; diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index adba42ce930..8fbad45bd8a 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -23,11 +23,9 @@ import { ToolPart, UserMessage, Todo, - QuestionRequest, QuestionAnswer, QuestionInfo, } from "@opencode-ai/sdk/v2" -import { createStore } from "solid-js/store" import { useData } from "../context" import { useDiffComponent } from "../context/diff" import { useCodeComponent } from "../context/code" @@ -37,7 +35,6 @@ import { BasicTool } from "./basic-tool" import { GenericTool } from "./basic-tool" import { Accordion } from "./accordion" import { StickyAccordionHeader } from "./sticky-accordion-header" -import { Button } from "./button" import { Card } from "./card" import { Collapsible } from "./collapsible" import { FileIcon } from "./file-icon" @@ -950,7 +947,6 @@ function ToolFileAccordion(props: { path: string; actions?: JSX.Element; childre } PART_MAPPING["tool"] = function ToolPartDisplay(props) { - const data = useData() const i18n = useI18n() const part = props.part as ToolPart if (part.tool === "todowrite" || part.tool === "todoread") return null @@ -959,75 +955,18 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) { () => part.tool === "question" && (part.state.status === "pending" || part.state.status === "running"), ) - const permission = createMemo(() => { - const next = data.store.permission?.[props.message.sessionID]?.[0] - if (!next || !next.tool) return undefined - if (next.tool!.callID !== part.callID) return undefined - return next - }) - - const questionRequest = createMemo(() => { - const next = data.store.question?.[props.message.sessionID]?.[0] - if (!next || !next.tool) return undefined - if (next.tool!.callID !== part.callID) return undefined - return next - }) - - const [showPermission, setShowPermission] = createSignal(false) - const [showQuestion, setShowQuestion] = createSignal(false) - - createEffect(() => { - const perm = permission() - if (perm) { - const timeout = setTimeout(() => setShowPermission(true), 50) - onCleanup(() => clearTimeout(timeout)) - } else { - setShowPermission(false) - } - }) - - createEffect(() => { - const question = questionRequest() - if (question) { - const timeout = setTimeout(() => setShowQuestion(true), 50) - onCleanup(() => clearTimeout(timeout)) - } else { - setShowQuestion(false) - } - }) - - const [forceOpen, setForceOpen] = createSignal(false) - createEffect(() => { - if (permission() || questionRequest()) setForceOpen(true) - }) - - const respond = (response: "once" | "always" | "reject") => { - const perm = permission() - if (!perm || !data.respondToPermission) return - data.respondToPermission({ - sessionID: perm.sessionID, - permissionID: perm.id, - response, - }) - } - const emptyInput: Record = {} const emptyMetadata: Record = {} const input = () => part.state?.input ?? emptyInput // @ts-expect-error const partMetadata = () => part.state?.metadata ?? emptyMetadata - const metadata = () => { - const perm = permission() - if (perm?.metadata) return { ...perm.metadata, ...partMetadata() } - return partMetadata() - } const render = ToolRegistry.render(part.tool) ?? GenericTool return ( -
+
{(error) => { @@ -1067,33 +1006,15 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) { component={render} input={input()} tool={part.tool} - metadata={metadata()} + metadata={partMetadata()} // @ts-expect-error output={part.state.output} status={part.state.status} hideDetails={props.hideDetails} - forceOpen={forceOpen()} - locked={showPermission() || showQuestion()} defaultOpen={props.defaultOpen} /> - -
-
- - - -
-
-
- {(request) => }
) @@ -1963,245 +1884,3 @@ ToolRegistry.register({ ) }, }) - -function QuestionPrompt(props: { request: QuestionRequest }) { - const data = useData() - const i18n = useI18n() - const questions = createMemo(() => props.request.questions) - const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true) - - const [store, setStore] = createStore({ - tab: 0, - answers: [] as QuestionAnswer[], - custom: [] as string[], - editing: false, - }) - - const question = createMemo(() => questions()[store.tab]) - const confirm = createMemo(() => !single() && store.tab === questions().length) - const options = createMemo(() => question()?.options ?? []) - const input = createMemo(() => store.custom[store.tab] ?? "") - const multi = createMemo(() => question()?.multiple === true) - const customPicked = createMemo(() => { - const value = input() - if (!value) return false - return store.answers[store.tab]?.includes(value) ?? false - }) - - function submit() { - const answers = questions().map((_, i) => store.answers[i] ?? []) - data.replyToQuestion?.({ - requestID: props.request.id, - answers, - }) - } - - function reject() { - data.rejectQuestion?.({ - requestID: props.request.id, - }) - } - - function pick(answer: string, custom: boolean = false) { - const answers = [...store.answers] - answers[store.tab] = [answer] - setStore("answers", answers) - if (custom) { - const inputs = [...store.custom] - inputs[store.tab] = answer - setStore("custom", inputs) - } - if (single()) { - data.replyToQuestion?.({ - requestID: props.request.id, - answers: [[answer]], - }) - return - } - setStore("tab", store.tab + 1) - } - - function toggle(answer: string) { - const existing = store.answers[store.tab] ?? [] - const next = [...existing] - const index = next.indexOf(answer) - if (index === -1) next.push(answer) - if (index !== -1) next.splice(index, 1) - const answers = [...store.answers] - answers[store.tab] = next - setStore("answers", answers) - } - - function selectTab(index: number) { - setStore("tab", index) - setStore("editing", false) - } - - function selectOption(optIndex: number) { - if (optIndex === options().length) { - setStore("editing", true) - return - } - const opt = options()[optIndex] - if (!opt) return - if (multi()) { - toggle(opt.label) - return - } - pick(opt.label) - } - - function handleCustomSubmit(e: Event) { - e.preventDefault() - const value = input().trim() - if (!value) { - setStore("editing", false) - return - } - if (multi()) { - const existing = store.answers[store.tab] ?? [] - const next = [...existing] - if (!next.includes(value)) next.push(value) - const answers = [...store.answers] - answers[store.tab] = next - setStore("answers", answers) - setStore("editing", false) - return - } - pick(value, true) - setStore("editing", false) - } - - return ( -
- -
- - {(q, index) => { - const active = () => index() === store.tab - const answered = () => (store.answers[index()]?.length ?? 0) > 0 - return ( - - ) - }} - - -
-
- - -
-
- {question()?.question} - {multi() ? " " + i18n.t("ui.question.multiHint") : ""} -
-
- - {(opt, i) => { - const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false - return ( - - ) - }} - - - -
- setTimeout(() => el.focus(), 0)} - type="text" - data-slot="custom-input" - placeholder={i18n.t("ui.question.custom.placeholder")} - value={input()} - onInput={(e) => { - const inputs = [...store.custom] - inputs[store.tab] = e.currentTarget.value - setStore("custom", inputs) - }} - /> - - -
-
-
-
-
- - -
-
{i18n.t("ui.messagePart.review.title")}
- - {(q, index) => { - const value = () => store.answers[index()]?.join(", ") ?? "" - const answered = () => Boolean(value()) - return ( -
- {q.question} - - {answered() ? value() : i18n.t("ui.question.review.notAnswered")} - -
- ) - }} -
-
-
- -
- - - - - - - - - -
-
- ) -} diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx index 2c44763f536..e116199eb23 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/ui/src/context/data.tsx @@ -1,14 +1,4 @@ -import type { - Message, - Session, - Part, - FileDiff, - SessionStatus, - PermissionRequest, - QuestionRequest, - QuestionAnswer, - ProviderListResponse, -} from "@opencode-ai/sdk/v2" +import type { Message, Session, Part, FileDiff, SessionStatus, ProviderListResponse } from "@opencode-ai/sdk/v2" import { createSimpleContext } from "./helper" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" @@ -24,12 +14,6 @@ type Data = { session_diff_preload?: { [sessionID: string]: PreloadMultiFileDiffResult[] } - permission?: { - [sessionID: string]: PermissionRequest[] - } - question?: { - [sessionID: string]: QuestionRequest[] - } message: { [sessionID: string]: Message[] } @@ -38,16 +22,6 @@ type Data = { } } -export type PermissionRespondFn = (input: { - sessionID: string - permissionID: string - response: "once" | "always" | "reject" -}) => void - -export type QuestionReplyFn = (input: { requestID: string; answers: QuestionAnswer[] }) => void - -export type QuestionRejectFn = (input: { requestID: string }) => void - export type NavigateToSessionFn = (sessionID: string) => void export type SessionHrefFn = (sessionID: string) => string @@ -57,9 +31,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ init: (props: { data: Data directory: string - onPermissionRespond?: PermissionRespondFn - onQuestionReply?: QuestionReplyFn - onQuestionReject?: QuestionRejectFn onNavigateToSession?: NavigateToSessionFn onSessionHref?: SessionHrefFn }) => { @@ -70,9 +41,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ get directory() { return props.directory }, - respondToPermission: props.onPermissionRespond, - replyToQuestion: props.onQuestionReply, - rejectQuestion: props.onQuestionReject, navigateToSession: props.onNavigateToSession, sessionHref: props.onSessionHref, } From c4ea11fef3dc3ac6bd2e3c55d1c8179457eace5d Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 25 Feb 2026 23:06:16 -0500 Subject: [PATCH 12/23] wip: zen --- packages/console/app/src/routes/black/index.tsx | 13 +++++++++---- .../black/{_subscribe => subscribe}/[plan].tsx | 11 +++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) rename packages/console/app/src/routes/black/{_subscribe => subscribe}/[plan].tsx (98%) diff --git a/packages/console/app/src/routes/black/index.tsx b/packages/console/app/src/routes/black/index.tsx index 382832e8faf..8bce3cd464f 100644 --- a/packages/console/app/src/routes/black/index.tsx +++ b/packages/console/app/src/routes/black/index.tsx @@ -1,16 +1,21 @@ -import { A, useSearchParams } from "@solidjs/router" +import { A, createAsync, query, useSearchParams } from "@solidjs/router" import { Title } from "@solidjs/meta" import { createMemo, createSignal, For, Match, onMount, Show, Switch } from "solid-js" import { PlanIcon, plans } from "./common" import { useI18n } from "~/context/i18n" import { useLanguage } from "~/context/language" +import { Resource } from "@opencode-ai/console-resource" -const paused = true +const getPaused = query(async () => { + "use server" + return Resource.App.stage === "production" +}, "black.paused") export default function Black() { const [params] = useSearchParams() const i18n = useI18n() const language = useLanguage() + const paused = createAsync(() => getPaused()) const [selected, setSelected] = createSignal((params.plan as string) || null) const [mounted, setMounted] = createSignal(false) const selectedPlan = createMemo(() => plans.find((p) => p.id === selected())) @@ -44,7 +49,7 @@ export default function Black() { <> {i18n.t("black.title")}
- {i18n.t("black.paused")}

}> + {i18n.t("black.paused")}

}>
@@ -108,7 +113,7 @@ export default function Black() { - +

{i18n.t("black.finePrint.beforeTerms")} ·{" "} {i18n.t("black.finePrint.terms")} diff --git a/packages/console/app/src/routes/black/_subscribe/[plan].tsx b/packages/console/app/src/routes/black/subscribe/[plan].tsx similarity index 98% rename from packages/console/app/src/routes/black/_subscribe/[plan].tsx rename to packages/console/app/src/routes/black/subscribe/[plan].tsx index 644d87d9b32..19b56eabe67 100644 --- a/packages/console/app/src/routes/black/_subscribe/[plan].tsx +++ b/packages/console/app/src/routes/black/subscribe/[plan].tsx @@ -17,6 +17,12 @@ import { Billing } from "@opencode-ai/console-core/billing.js" import { useI18n } from "~/context/i18n" import { useLanguage } from "~/context/language" import { formError } from "~/lib/form-error" +import { Resource } from "@opencode-ai/console-resource" + +const getEnabled = query(async () => { + "use server" + return Resource.App.stage !== "production" +}, "black.subscribe.enabled") const plansMap = Object.fromEntries(plans.map((p) => [p.id, p])) as Record const stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY!) @@ -269,6 +275,7 @@ export default function BlackSubscribe() { const params = useParams() const i18n = useI18n() const language = useLanguage() + const enabled = createAsync(() => getEnabled()) const planData = plansMap[(params.plan as PlanID) ?? "20"] ?? plansMap["20"] const plan = planData.id @@ -359,7 +366,7 @@ export default function BlackSubscribe() { } return ( - <> + {i18n.t("black.subscribe.title")}

@@ -472,6 +479,6 @@ export default function BlackSubscribe() { {i18n.t("black.finePrint.terms")}

- +
) } From 392a6d993f5cbb233bc0eeab297919cb21099f2c Mon Sep 17 00:00:00 2001 From: kil-penguin Date: Thu, 26 Feb 2026 15:02:40 +0900 Subject: [PATCH 13/23] fix(desktop): remove interactive shell flag from sidecar spawn to prevent hang on macOS (#15136) Co-authored-by: kil-penguin --- packages/desktop/src-tauri/src/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop/src-tauri/src/cli.rs b/packages/desktop/src-tauri/src/cli.rs index 0c5dfebaf5e..af1a45cf3a3 100644 --- a/packages/desktop/src-tauri/src/cli.rs +++ b/packages/desktop/src-tauri/src/cli.rs @@ -320,7 +320,7 @@ pub fn spawn_command( }; let mut cmd = Command::new(shell); - cmd.args(["-il", "-c", &line]); + cmd.args(["-l", "-c", &line]); for (key, value) in envs { cmd.env(key, value); From aae75b3cfb10cdff965fb434c487980b152efdec Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 26 Feb 2026 08:59:08 +0200 Subject: [PATCH 14/23] fix(app): middle-click tab close in scrollable tab bar (#15081) Co-authored-by: opencode-agent[bot] --- packages/ui/src/components/tabs.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/ui/src/components/tabs.tsx b/packages/ui/src/components/tabs.tsx index 4836a0864c2..a9dbea7bc4d 100644 --- a/packages/ui/src/components/tabs.tsx +++ b/packages/ui/src/components/tabs.tsx @@ -65,6 +65,11 @@ function TabsTrigger(props: ParentProps) { ...(split.classList ?? {}), [split.class ?? ""]: !!split.class, }} + onMouseDown={(e) => { + if (e.button === 1 && split.onMiddleClick) { + e.preventDefault() + } + }} onAuxClick={(e) => { if (e.button === 1 && split.onMiddleClick) { e.preventDefault() From fce811b52f335eb28dc43b49a96f42b2ada751f5 Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:55:01 +1000 Subject: [PATCH 15/23] fix: most segfaults on windows with Bun v1.3.10 stable (#15181) --- .github/actions/setup-bun/action.yml | 56 +--------------------------- .github/workflows/publish.yml | 4 +- .github/workflows/sign-cli.yml | 4 +- package.json | 2 +- packages/desktop/scripts/utils.ts | 2 +- packages/opencode/script/build.ts | 7 +++- 6 files changed, 12 insertions(+), 63 deletions(-) diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index e7966cb48c7..6c632f7e072 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -1,10 +1,5 @@ name: "Setup Bun" description: "Setup Bun with caching and install dependencies" -inputs: - cross-compile: - description: "Pre-cache canary cross-compile binaries for all targets" - required: false - default: "false" runs: using: "composite" steps: @@ -21,12 +16,13 @@ runs: shell: bash run: | if [ "$RUNNER_ARCH" = "X64" ]; then + V=$(node -p "require('./package.json').packageManager.split('@')[1]") case "$RUNNER_OS" in macOS) OS=darwin ;; Linux) OS=linux ;; Windows) OS=windows ;; esac - echo "url=https://github.com/oven-sh/bun/releases/download/canary/bun-${OS}-x64-baseline.zip" >> "$GITHUB_OUTPUT" + echo "url=https://github.com/oven-sh/bun/releases/download/bun-v${V}/bun-${OS}-x64-baseline.zip" >> "$GITHUB_OUTPUT" fi - name: Setup Bun @@ -35,54 +31,6 @@ runs: bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }} bun-download-url: ${{ steps.bun-url.outputs.url }} - - name: Pre-cache canary cross-compile binaries - if: inputs.cross-compile == 'true' - shell: bash - run: | - BUN_VERSION=$(bun --revision) - if echo "$BUN_VERSION" | grep -q "canary"; then - SEMVER=$(echo "$BUN_VERSION" | sed 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/') - echo "Bun version: $BUN_VERSION (semver: $SEMVER)" - CACHE_DIR="$HOME/.bun/install/cache" - mkdir -p "$CACHE_DIR" - TMP_DIR=$(mktemp -d) - for TARGET in linux-aarch64 linux-x64 linux-x64-baseline linux-aarch64-musl linux-x64-musl linux-x64-musl-baseline darwin-aarch64 darwin-x64 windows-x64 windows-x64-baseline; do - DEST="$CACHE_DIR/bun-${TARGET}-v${SEMVER}" - if [ -f "$DEST" ]; then - echo "Already cached: $DEST" - continue - fi - URL="https://github.com/oven-sh/bun/releases/download/canary/bun-${TARGET}.zip" - echo "Downloading $TARGET from $URL" - if curl -sfL -o "$TMP_DIR/bun.zip" "$URL"; then - unzip -qo "$TMP_DIR/bun.zip" -d "$TMP_DIR" - if echo "$TARGET" | grep -q "windows"; then - BIN_NAME="bun.exe" - else - BIN_NAME="bun" - fi - mv "$TMP_DIR/bun-${TARGET}/$BIN_NAME" "$DEST" - chmod +x "$DEST" - rm -rf "$TMP_DIR/bun-${TARGET}" "$TMP_DIR/bun.zip" - echo "Cached: $DEST" - # baseline bun resolves "bun-darwin-x64" to the baseline cache key - # so copy the modern binary there too - if [ "$TARGET" = "darwin-x64" ]; then - BASELINE_DEST="$CACHE_DIR/bun-darwin-x64-baseline-v${SEMVER}" - if [ ! -f "$BASELINE_DEST" ]; then - cp "$DEST" "$BASELINE_DEST" - echo "Cached (baseline alias): $BASELINE_DEST" - fi - fi - else - echo "Skipped: $TARGET (not available)" - fi - done - rm -rf "$TMP_DIR" - else - echo "Not a canary build ($BUN_VERSION), skipping pre-cache" - fi - - name: Install dependencies run: bun install shell: bash diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cca7df5c4ed..8d4c9038a7e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -77,8 +77,6 @@ jobs: fetch-tags: true - uses: ./.github/actions/setup-bun - with: - cross-compile: "true" - name: Setup git committer id: committer @@ -90,7 +88,7 @@ jobs: - name: Build id: build run: | - ./packages/opencode/script/build.ts --all + ./packages/opencode/script/build.ts env: OPENCODE_VERSION: ${{ needs.version.outputs.version }} OPENCODE_RELEASE: ${{ needs.version.outputs.release }} diff --git a/.github/workflows/sign-cli.yml b/.github/workflows/sign-cli.yml index 89176223176..d9d61fd800e 100644 --- a/.github/workflows/sign-cli.yml +++ b/.github/workflows/sign-cli.yml @@ -20,12 +20,10 @@ jobs: fetch-tags: true - uses: ./.github/actions/setup-bun - with: - cross-compile: "true" - name: Build run: | - ./packages/opencode/script/build.ts --all + ./packages/opencode/script/build.ts - name: Upload unsigned Windows CLI id: upload_unsigned_windows_cli diff --git a/package.json b/package.json index 2e7c1172aa6..3fd9f306676 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "AI-powered development tool", "private": true, "type": "module", - "packageManager": "bun@1.3.9", + "packageManager": "bun@1.3.10", "scripts": { "dev": "bun run --cwd packages/opencode --conditions=browser src/index.ts", "dev:desktop": "bun --cwd packages/desktop tauri dev", diff --git a/packages/desktop/scripts/utils.ts b/packages/desktop/scripts/utils.ts index f6ea7009c86..2629eb466c0 100644 --- a/packages/desktop/scripts/utils.ts +++ b/packages/desktop/scripts/utils.ts @@ -8,7 +8,7 @@ export const SIDECAR_BINARIES: Array<{ rustTarget: string; ocBinary: string; ass }, { rustTarget: "x86_64-apple-darwin", - ocBinary: "opencode-darwin-x64", + ocBinary: "opencode-darwin-x64-baseline", assetExt: "zip", }, { diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 19353b67fe4..34e80d71a08 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -56,7 +56,7 @@ const migrations = await Promise.all( ) console.log(`Loaded ${migrations.length} migrations`) -const singleFlag = process.argv.includes("--single") || (!!process.env.CI && !process.argv.includes("--all")) +const singleFlag = process.argv.includes("--single") const baselineFlag = process.argv.includes("--baseline") const skipInstall = process.argv.includes("--skip-install") @@ -103,6 +103,11 @@ const allTargets: { os: "darwin", arch: "x64", }, + { + os: "darwin", + arch: "x64", + avx2: false, + }, { os: "win32", arch: "x64", From 799b2623cbb1c0f19e045d87c2c8593e83678bc0 Mon Sep 17 00:00:00 2001 From: opencode Date: Thu, 26 Feb 2026 08:22:25 +0000 Subject: [PATCH 16/23] release: v1.2.15 --- bun.lock | 30 +++++++++++++------------- packages/app/package.json | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/slack/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 18 files changed, 37 insertions(+), 37 deletions(-) diff --git a/bun.lock b/bun.lock index 2bdab5cb6af..27a2a9a2b63 100644 --- a/bun.lock +++ b/bun.lock @@ -25,7 +25,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -75,7 +75,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -109,7 +109,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -136,7 +136,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -160,7 +160,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -184,7 +184,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -217,7 +217,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -246,7 +246,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -262,7 +262,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.2.14", + "version": "1.2.15", "bin": { "opencode": "./bin/opencode", }, @@ -376,7 +376,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -396,7 +396,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.2.14", + "version": "1.2.15", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -407,7 +407,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -420,7 +420,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -462,7 +462,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "zod": "catalog:", }, @@ -473,7 +473,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/app/package.json b/packages/app/package.json index 37d2801baf7..446c14e9671 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.2.14", + "version": "1.2.15", "description": "", "type": "module", "exports": { diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 05d2309a423..ad5813ced67 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 078d662072d..8f65e0c4578 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.2.14", + "version": "1.2.15", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index ac1c6bfd89a..6cdf752432c 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.2.14", + "version": "1.2.15", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 1b91c7cbe01..09344f7fa23 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.2.14", + "version": "1.2.15", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 2bd9cce9a35..4fe999e700a 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 0cd3ec69083..cc46f7530fb 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.2.14", + "version": "1.2.15", "private": true, "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 436b2e9e191..e9f246af890 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.2.14" +version = "1.2.15" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/anomalyco/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.14/opencode-darwin-arm64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.14/opencode-darwin-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.14/opencode-linux-arm64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.14/opencode-linux-x64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.14/opencode-windows-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 7a68ef5b9d2..63e50b99211 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.2.14", + "version": "1.2.15", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index e23d2e41ad3..9252468153b 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.2.14", + "version": "1.2.15", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index c4ed60455ab..e476c41e2fb 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 3faee471736..ffbdf219824 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/slack/package.json b/packages/slack/package.json index c61ff7521b3..72ffe20d5e3 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 08f46d633bc..0cdccdc54cc 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.2.14", + "version": "1.2.15", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index d389d3ade1b..36a235639ee 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.2.14", + "version": "1.2.15", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index 12bffe86d6b..daf2ad3480f 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.2.14", + "version": "1.2.15", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index a661b25d80f..a041b65223d 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.2.14", + "version": "1.2.15", "publisher": "sst-dev", "repository": { "type": "git", From 2c10cfbb52736e38650711aefd88d26a86cdc7e0 Mon Sep 17 00:00:00 2001 From: Kevin van Dijk Date: Thu, 26 Feb 2026 14:35:48 +0100 Subject: [PATCH 17/23] refactor: kilo compat for v1.2.15 --- github/index.ts | 2 +- github/package.json | 5 +-- package.json | 17 +++++----- packages/app/e2e/session/session.spec.ts | 4 +-- packages/app/e2e/utils.ts | 2 +- packages/app/package.json | 11 ++++--- packages/app/script/e2e-local.ts | 16 +++++----- .../components/dialog-connect-provider.tsx | 2 +- .../src/components/dialog-custom-provider.tsx | 2 +- packages/app/src/components/dialog-fork.tsx | 2 +- packages/app/src/components/file-tree.tsx | 2 +- .../prompt-input/build-request-parts.ts | 2 +- .../app/src/components/prompt-input/submit.ts | 2 +- .../session/session-context-breakdown.test.ts | 2 +- .../session/session-context-breakdown.ts | 2 +- .../session/session-context-metrics.test.ts | 2 +- .../session/session-context-metrics.ts | 2 +- .../session/session-context-tab.tsx | 2 +- .../app/src/components/settings-general.tsx | 2 +- .../app/src/context/file/content-cache.ts | 2 +- packages/app/src/context/file/tree-store.ts | 2 +- packages/app/src/context/file/types.ts | 2 +- packages/app/src/context/file/watcher.ts | 2 +- packages/app/src/context/global-sdk.tsx | 2 +- packages/app/src/context/global-sync.tsx | 2 +- .../app/src/context/global-sync/bootstrap.ts | 2 +- .../src/context/global-sync/child-store.ts | 2 +- .../context/global-sync/event-reducer.test.ts | 2 +- .../src/context/global-sync/event-reducer.ts | 2 +- .../context/global-sync/session-trim.test.ts | 2 +- .../src/context/global-sync/session-trim.ts | 2 +- packages/app/src/context/global-sync/types.ts | 2 +- packages/app/src/context/global-sync/utils.ts | 2 +- packages/app/src/context/highlights.tsx | 2 +- packages/app/src/context/layout.tsx | 2 +- packages/app/src/context/notification.tsx | 2 +- packages/app/src/context/permission.tsx | 2 +- packages/app/src/context/sdk.tsx | 2 +- .../app/src/context/sync-optimistic.test.ts | 2 +- packages/app/src/context/sync.tsx | 2 +- packages/app/src/i18n/ar.ts | 32 +++++++++---------- packages/app/src/i18n/br.ts | 32 +++++++++---------- packages/app/src/i18n/bs.ts | 32 +++++++++---------- packages/app/src/i18n/da.ts | 32 +++++++++---------- packages/app/src/i18n/de.ts | 32 +++++++++---------- packages/app/src/i18n/en.ts | 32 +++++++++---------- packages/app/src/i18n/es.ts | 32 +++++++++---------- packages/app/src/i18n/fr.ts | 32 +++++++++---------- packages/app/src/i18n/ja.ts | 32 +++++++++---------- packages/app/src/i18n/ko.ts | 32 +++++++++---------- packages/app/src/i18n/no.ts | 32 +++++++++---------- packages/app/src/i18n/pl.ts | 32 +++++++++---------- packages/app/src/i18n/ru.ts | 32 +++++++++---------- packages/app/src/i18n/th.ts | 32 +++++++++---------- packages/app/src/i18n/zh.ts | 32 +++++++++---------- packages/app/src/i18n/zht.ts | 32 +++++++++---------- packages/app/src/pages/error.tsx | 2 +- packages/app/src/pages/layout.tsx | 6 ++-- packages/app/src/pages/layout/helpers.ts | 2 +- .../app/src/pages/layout/sidebar-items.tsx | 6 ++-- .../src/pages/layout/sidebar-workspace.tsx | 2 +- packages/app/src/pages/session.tsx | 2 +- .../composer/session-composer-state.test.ts | 2 +- .../composer/session-composer-state.ts | 2 +- .../composer/session-permission-dock.tsx | 2 +- .../composer/session-question-dock.tsx | 2 +- .../session/composer/session-request-tree.ts | 2 +- .../session/composer/session-todo-dock.tsx | 2 +- .../src/pages/session/message-timeline.tsx | 2 +- packages/app/src/pages/session/review-tab.tsx | 2 +- .../pages/session/use-session-commands.tsx | 2 +- .../pages/session/use-session-hash-scroll.ts | 2 +- packages/app/src/utils/prompt.ts | 2 +- packages/app/src/utils/server.ts | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/console/resource/package.json | 3 +- packages/desktop/package.json | 2 +- packages/desktop/src-tauri/Cargo.toml | 4 +-- packages/desktop/src-tauri/src/cli.rs | 28 ++++++++-------- packages/desktop/src-tauri/src/constants.rs | 2 +- packages/desktop/src-tauri/src/lib.rs | 8 ++--- .../desktop/src-tauri/src/linux_display.rs | 4 +-- packages/desktop/src-tauri/src/main.rs | 2 +- packages/desktop/src-tauri/src/windows.rs | 6 ++-- packages/desktop/src-tauri/tauri.conf.json | 8 ++--- .../desktop/src-tauri/tauri.prod.conf.json | 6 ++-- packages/desktop/src/i18n/ar.ts | 4 +-- packages/desktop/src/i18n/br.ts | 4 +-- packages/desktop/src/i18n/bs.ts | 4 +-- packages/desktop/src/i18n/da.ts | 4 +-- packages/desktop/src/i18n/de.ts | 4 +-- packages/desktop/src/i18n/en.ts | 4 +-- packages/desktop/src/i18n/es.ts | 4 +-- packages/desktop/src/i18n/fr.ts | 4 +-- packages/desktop/src/i18n/ja.ts | 4 +-- packages/desktop/src/i18n/ko.ts | 4 +-- packages/desktop/src/i18n/no.ts | 4 +-- packages/desktop/src/i18n/pl.ts | 4 +-- packages/desktop/src/i18n/ru.ts | 4 +-- packages/desktop/src/i18n/zh.ts | 4 +-- packages/desktop/src/i18n/zht.ts | 4 +-- packages/desktop/src/menu.ts | 10 +++--- packages/desktop/src/updater.ts | 2 +- packages/enterprise/package.json | 2 +- packages/enterprise/src/core/share.ts | 2 +- .../enterprise/src/routes/share/[shareID].tsx | 2 +- packages/extensions/zed/extension.toml | 18 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 18 +++++++---- packages/opencode/script/build.ts | 12 +++---- packages/opencode/script/publish.ts | 18 +++++------ packages/opencode/src/acp/agent.ts | 2 +- packages/opencode/src/acp/session.ts | 2 +- packages/opencode/src/acp/types.ts | 2 +- packages/opencode/src/cli/cmd/acp.ts | 2 +- packages/opencode/src/cli/cmd/auth.ts | 2 +- packages/opencode/src/cli/cmd/import.ts | 2 +- packages/opencode/src/cli/cmd/run.ts | 2 +- .../cli/cmd/tui/component/dialog-provider.tsx | 2 +- .../cli/cmd/tui/component/prompt/history.tsx | 2 +- .../cli/cmd/tui/component/prompt/index.tsx | 2 +- .../opencode/src/cli/cmd/tui/context/sdk.tsx | 2 +- .../opencode/src/cli/cmd/tui/context/sync.tsx | 4 +-- .../session/dialog-fork-from-timeline.tsx | 2 +- .../tui/routes/session/dialog-timeline.tsx | 2 +- .../src/cli/cmd/tui/routes/session/header.tsx | 2 +- .../src/cli/cmd/tui/routes/session/index.tsx | 2 +- .../cli/cmd/tui/routes/session/permission.tsx | 2 +- .../cli/cmd/tui/routes/session/question.tsx | 2 +- .../cli/cmd/tui/routes/session/sidebar.tsx | 2 +- packages/opencode/src/cli/cmd/tui/thread.ts | 2 +- .../src/cli/cmd/tui/util/transcript.ts | 2 +- packages/opencode/src/cli/cmd/tui/worker.ts | 2 +- packages/opencode/src/plugin/codex.ts | 2 +- packages/opencode/src/plugin/copilot.ts | 2 +- packages/opencode/src/plugin/index.ts | 4 +-- packages/opencode/src/provider/auth.ts | 2 +- packages/opencode/src/share/share-next.ts | 2 +- packages/opencode/src/tool/registry.ts | 2 +- .../test/acp/event-subscription.test.ts | 2 +- .../test/cli/plugin-auth-picker.test.ts | 2 +- .../opencode/test/cli/tui/transcript.test.ts | 2 +- packages/opencode/test/tool/registry.test.ts | 2 +- packages/plugin/package.json | 9 +++--- packages/plugin/src/index.ts | 2 +- packages/script/package.json | 5 ++- packages/sdk/js/example/example.ts | 2 +- packages/sdk/js/package.json | 7 ++-- packages/slack/package.json | 4 +-- packages/slack/src/index.ts | 2 +- packages/ui/package.json | 4 +-- packages/ui/src/components/favicon.tsx | 2 +- packages/ui/src/components/message-nav.tsx | 2 +- packages/ui/src/components/message-part.tsx | 2 +- packages/ui/src/components/session-review.tsx | 2 +- packages/ui/src/components/session-turn.tsx | 2 +- packages/ui/src/context/data.tsx | 2 +- packages/ui/src/context/marked.tsx | 12 +++---- packages/util/package.json | 2 +- packages/web/package.json | 2 +- script/changelog.ts | 8 ++--- script/duplicate-pr.ts | 2 +- script/stats.ts | 4 +-- sdks/vscode/package.json | 2 +- 167 files changed, 534 insertions(+), 519 deletions(-) diff --git a/github/index.ts b/github/index.ts index da310178a7d..88809f8f441 100644 --- a/github/index.ts +++ b/github/index.ts @@ -6,7 +6,7 @@ import * as core from "@actions/core" import * as github from "@actions/github" import type { Context as GitHubContext } from "@actions/github/lib/context" import type { IssueCommentEvent, PullRequestReviewCommentEvent } from "@octokit/webhooks-types" -import { createOpencodeClient } from "@opencode-ai/sdk" +import { createOpencodeClient } from "@kilocode/sdk" import { spawn } from "node:child_process" type GitHubAuthor = { diff --git a/github/package.json b/github/package.json index e1b913abedc..28b6f353681 100644 --- a/github/package.json +++ b/github/package.json @@ -15,6 +15,7 @@ "@actions/github": "6.0.1", "@octokit/graphql": "9.0.1", "@octokit/rest": "catalog:", - "@opencode-ai/sdk": "workspace:*" - } + "@kilocode/sdk": "workspace:*" + }, + "version": "7.0.30" } diff --git a/package.json b/package.json index 3fd9f306676..f5cc4e614a3 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,7 @@ "workspaces": { "packages": [ "packages/*", - "packages/console/*", - "packages/sdk/js", - "packages/slack" + "packages/sdk/js" ], "catalog": { "@types/bun": "1.3.9", @@ -35,7 +33,7 @@ "@tsconfig/bun": "1.0.9", "@cloudflare/workers-types": "4.20251008.0", "@openauthjs/openauth": "0.0.0-20250322224806", - "@pierre/diffs": "1.1.0-beta.13", + "@pierre/diffs": "1.1.0-beta.17", "@solid-primitives/storage": "4.3.3", "@tailwindcss/vite": "4.1.11", "diff": "8.0.2", @@ -79,9 +77,9 @@ }, "dependencies": { "@aws-sdk/client-s3": "3.933.0", - "@opencode-ai/plugin": "workspace:*", + "@kilocode/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "typescript": "catalog:" }, "repository": { @@ -106,6 +104,9 @@ }, "patchedDependencies": { "@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch", - "@openrouter/ai-sdk-provider@1.5.4": "patches/@openrouter%2Fai-sdk-provider@1.5.4.patch" - } + "@openrouter/ai-sdk-provider@1.5.4": "patches/@openrouter%2Fai-sdk-provider@1.5.4.patch", + "ghostty-web@0.3.0": "patches/ghostty-web@0.3.0.patch" + }, + "version": "7.0.30", + "peerDependencies": {} } diff --git a/packages/app/e2e/session/session.spec.ts b/packages/app/e2e/session/session.spec.ts index 68d99294996..4e99843ca6c 100644 --- a/packages/app/e2e/session/session.spec.ts +++ b/packages/app/e2e/session/session.spec.ts @@ -9,7 +9,7 @@ import { } from "../actions" import { sessionItemSelector, inlineInputSelector } from "../selectors" -const shareDisabled = process.env.OPENCODE_DISABLE_SHARE === "true" || process.env.OPENCODE_DISABLE_SHARE === "1" +const shareDisabled = process.env.KILO_DISABLE_SHARE === "true" || process.env.KILO_DISABLE_SHARE === "1" type Sdk = Parameters[0] @@ -120,7 +120,7 @@ test("session can be deleted via header menu", async ({ page, sdk, gotoSession } }) test("session can be shared and unshared via header button", async ({ page, sdk, gotoSession }) => { - test.skip(shareDisabled, "Share is disabled in this environment (OPENCODE_DISABLE_SHARE).") + test.skip(shareDisabled, "Share is disabled in this environment (KILO_DISABLE_SHARE).") const stamp = Date.now() const title = `e2e share test ${stamp}` diff --git a/packages/app/e2e/utils.ts b/packages/app/e2e/utils.ts index e015a1e9b96..6e763fb7e04 100644 --- a/packages/app/e2e/utils.ts +++ b/packages/app/e2e/utils.ts @@ -1,4 +1,4 @@ -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import { base64Encode } from "@opencode-ai/util/encode" export const serverHost = process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1" diff --git a/packages/app/package.json b/packages/app/package.json index 446c14e9671..98807f6fb0a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.2.15", + "version": "7.0.30", "description": "", "type": "module", "exports": { @@ -39,7 +39,7 @@ }, "dependencies": { "@kobalte/core": "catalog:", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", "@shikijs/transformers": "3.9.2", @@ -67,6 +67,9 @@ "solid-list": "catalog:", "tailwindcss": "catalog:", "virtua": "catalog:", - "zod": "catalog:" - } + "zod": "catalog:", + "@kilocode/kilo-ui": "workspace:*", + "@kilocode/kilo-i18n": "workspace:*" + }, + "peerDependencies": {} } diff --git a/packages/app/script/e2e-local.ts b/packages/app/script/e2e-local.ts index 112e2bc60a1..3921c77fa2f 100644 --- a/packages/app/script/e2e-local.ts +++ b/packages/app/script/e2e-local.ts @@ -59,11 +59,11 @@ const keepSandbox = process.env.OPENCODE_E2E_KEEP_SANDBOX === "1" const serverEnv = { ...process.env, - OPENCODE_DISABLE_SHARE: process.env.OPENCODE_DISABLE_SHARE ?? "true", - OPENCODE_DISABLE_LSP_DOWNLOAD: "true", - OPENCODE_DISABLE_DEFAULT_PLUGINS: "true", - OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "true", - OPENCODE_TEST_HOME: path.join(sandbox, "home"), + KILO_DISABLE_SHARE: process.env.KILO_DISABLE_SHARE ?? "true", + KILO_DISABLE_LSP_DOWNLOAD: "true", + KILO_DISABLE_DEFAULT_PLUGINS: "true", + KILO_EXPERIMENTAL_DISABLE_FILEWATCHER: "true", + KILO_TEST_HOME: path.join(sandbox, "home"), XDG_DATA_HOME: path.join(sandbox, "share"), XDG_CACHE_HOME: path.join(sandbox, "cache"), XDG_CONFIG_HOME: path.join(sandbox, "config"), @@ -72,15 +72,15 @@ const serverEnv = { OPENCODE_E2E_SESSION_TITLE: "E2E Session", OPENCODE_E2E_MESSAGE: "Seeded for UI e2e", OPENCODE_E2E_MODEL: "opencode/gpt-5-nano", - OPENCODE_CLIENT: "app", + KILO_CLIENT: "app", } satisfies Record const runnerEnv = { ...serverEnv, PLAYWRIGHT_SERVER_HOST: "127.0.0.1", PLAYWRIGHT_SERVER_PORT: String(serverPort), - VITE_OPENCODE_SERVER_HOST: "127.0.0.1", - VITE_OPENCODE_SERVER_PORT: String(serverPort), + VITE_KILO_SERVER_HOST: "127.0.0.1", + VITE_KILO_SERVER_PORT: String(serverPort), PLAYWRIGHT_PORT: String(webPort), } satisfies Record diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index 90f4f41f7c6..feac1334d8a 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -1,4 +1,4 @@ -import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2/client" +import type { ProviderAuthAuthorization } from "@kilocode/sdk/v2/client" import { Button } from "@opencode-ai/ui/button" import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx index 017b85a2c99..11f10cf7855 100644 --- a/packages/app/src/components/dialog-custom-provider.tsx +++ b/packages/app/src/components/dialog-custom-provider.tsx @@ -292,7 +292,7 @@ export function DialogCustomProvider(props: Props) {

{language.t("provider.custom.description.prefix")} - + {language.t("provider.custom.description.link")} {language.t("provider.custom.description.suffix")} diff --git a/packages/app/src/components/dialog-fork.tsx b/packages/app/src/components/dialog-fork.tsx index 8810955cc65..595da6f1fd7 100644 --- a/packages/app/src/components/dialog-fork.tsx +++ b/packages/app/src/components/dialog-fork.tsx @@ -8,7 +8,7 @@ import { Dialog } from "@opencode-ai/ui/dialog" import { List } from "@opencode-ai/ui/list" import { showToast } from "@opencode-ai/ui/toast" import { extractPromptFromParts } from "@/utils/prompt" -import type { TextPart as SDKTextPart } from "@opencode-ai/sdk/v2/client" +import type { TextPart as SDKTextPart } from "@kilocode/sdk/v2/client" import { base64Encode } from "@opencode-ai/util/encode" import { useLanguage } from "@/context/language" diff --git a/packages/app/src/components/file-tree.tsx b/packages/app/src/components/file-tree.tsx index 3840f18ed87..e449586ba1a 100644 --- a/packages/app/src/components/file-tree.tsx +++ b/packages/app/src/components/file-tree.tsx @@ -18,7 +18,7 @@ import { type ParentProps, } from "solid-js" import { Dynamic } from "solid-js/web" -import type { FileNode } from "@opencode-ai/sdk/v2" +import type { FileNode } from "@kilocode/sdk/v2" const MAX_DEPTH = 128 diff --git a/packages/app/src/components/prompt-input/build-request-parts.ts b/packages/app/src/components/prompt-input/build-request-parts.ts index 0cc54dc2b78..95c369f391a 100644 --- a/packages/app/src/components/prompt-input/build-request-parts.ts +++ b/packages/app/src/components/prompt-input/build-request-parts.ts @@ -1,5 +1,5 @@ import { getFilename } from "@opencode-ai/util/path" -import { type AgentPartInput, type FilePartInput, type Part, type TextPartInput } from "@opencode-ai/sdk/v2/client" +import { type AgentPartInput, type FilePartInput, type Part, type TextPartInput } from "@kilocode/sdk/v2/client" import type { FileSelection } from "@/context/file" import { encodeFilePath } from "@/context/file/path" import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt" diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index a7ff39e091f..77f605ebed7 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -1,4 +1,4 @@ -import type { Message } from "@opencode-ai/sdk/v2/client" +import type { Message } from "@kilocode/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" import { base64Encode } from "@opencode-ai/util/encode" import { useNavigate, useParams } from "@solidjs/router" diff --git a/packages/app/src/components/session/session-context-breakdown.test.ts b/packages/app/src/components/session/session-context-breakdown.test.ts index f38aecb55da..36c43843453 100644 --- a/packages/app/src/components/session/session-context-breakdown.test.ts +++ b/packages/app/src/components/session/session-context-breakdown.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import type { Message, Part } from "@opencode-ai/sdk/v2/client" +import type { Message, Part } from "@kilocode/sdk/v2/client" import { estimateSessionContextBreakdown } from "./session-context-breakdown" const user = (id: string) => { diff --git a/packages/app/src/components/session/session-context-breakdown.ts b/packages/app/src/components/session/session-context-breakdown.ts index e263b2957b3..1b11fadcceb 100644 --- a/packages/app/src/components/session/session-context-breakdown.ts +++ b/packages/app/src/components/session/session-context-breakdown.ts @@ -1,4 +1,4 @@ -import type { Message, Part } from "@opencode-ai/sdk/v2/client" +import type { Message, Part } from "@kilocode/sdk/v2/client" export type SessionContextBreakdownKey = "system" | "user" | "assistant" | "tool" | "other" diff --git a/packages/app/src/components/session/session-context-metrics.test.ts b/packages/app/src/components/session/session-context-metrics.test.ts index 0e109a71bda..be1bbca2585 100644 --- a/packages/app/src/components/session/session-context-metrics.test.ts +++ b/packages/app/src/components/session/session-context-metrics.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import type { Message } from "@opencode-ai/sdk/v2/client" +import type { Message } from "@kilocode/sdk/v2/client" import { getSessionContextMetrics } from "./session-context-metrics" const assistant = ( diff --git a/packages/app/src/components/session/session-context-metrics.ts b/packages/app/src/components/session/session-context-metrics.ts index 0789b05f173..4bdcff52ebb 100644 --- a/packages/app/src/components/session/session-context-metrics.ts +++ b/packages/app/src/components/session/session-context-metrics.ts @@ -1,4 +1,4 @@ -import type { AssistantMessage, Message } from "@opencode-ai/sdk/v2/client" +import type { AssistantMessage, Message } from "@kilocode/sdk/v2/client" type Provider = { id: string diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx index 1ea97c395c4..17a8de1dc3c 100644 --- a/packages/app/src/components/session/session-context-tab.tsx +++ b/packages/app/src/components/session/session-context-tab.tsx @@ -12,7 +12,7 @@ import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" import { Code } from "@opencode-ai/ui/code" import { Markdown } from "@opencode-ai/ui/markdown" import { ScrollView } from "@opencode-ai/ui/scroll-view" -import type { Message, Part, UserMessage } from "@opencode-ai/sdk/v2/client" +import type { Message, Part, UserMessage } from "@kilocode/sdk/v2/client" import { useLanguage } from "@/context/language" import { getSessionContextMetrics } from "./session-context-metrics" import { estimateSessionContextBreakdown, type SessionContextBreakdownKey } from "./session-context-breakdown" diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index 42ee4092f68..7235c94cf05 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -219,7 +219,7 @@ export const SettingsGeneral: Component = () => { description={ <> {language.t("settings.general.row.theme.description")}{" "} - {language.t("common.learnMore")} + {language.t("common.learnMore")} } > diff --git a/packages/app/src/context/file/content-cache.ts b/packages/app/src/context/file/content-cache.ts index 4b724068834..98de196ab6f 100644 --- a/packages/app/src/context/file/content-cache.ts +++ b/packages/app/src/context/file/content-cache.ts @@ -1,4 +1,4 @@ -import type { FileContent } from "@opencode-ai/sdk/v2" +import type { FileContent } from "@kilocode/sdk/v2" const MAX_FILE_CONTENT_ENTRIES = 40 const MAX_FILE_CONTENT_BYTES = 20 * 1024 * 1024 diff --git a/packages/app/src/context/file/tree-store.ts b/packages/app/src/context/file/tree-store.ts index a86051d286e..dc4e58f7a25 100644 --- a/packages/app/src/context/file/tree-store.ts +++ b/packages/app/src/context/file/tree-store.ts @@ -1,5 +1,5 @@ import { createStore, produce, reconcile } from "solid-js/store" -import type { FileNode } from "@opencode-ai/sdk/v2" +import type { FileNode } from "@kilocode/sdk/v2" type DirectoryState = { expanded: boolean diff --git a/packages/app/src/context/file/types.ts b/packages/app/src/context/file/types.ts index 7ce8a37c25e..ee1cc49f311 100644 --- a/packages/app/src/context/file/types.ts +++ b/packages/app/src/context/file/types.ts @@ -1,4 +1,4 @@ -import type { FileContent } from "@opencode-ai/sdk/v2" +import type { FileContent } from "@kilocode/sdk/v2" export type FileSelection = { startLine: number diff --git a/packages/app/src/context/file/watcher.ts b/packages/app/src/context/file/watcher.ts index fbf71992791..57bc68edc9b 100644 --- a/packages/app/src/context/file/watcher.ts +++ b/packages/app/src/context/file/watcher.ts @@ -1,4 +1,4 @@ -import type { FileNode } from "@opencode-ai/sdk/v2" +import type { FileNode } from "@kilocode/sdk/v2" type WatcherEvent = { type: string diff --git a/packages/app/src/context/global-sdk.tsx b/packages/app/src/context/global-sdk.tsx index c1a87b95b89..8ff9e6bb291 100644 --- a/packages/app/src/context/global-sdk.tsx +++ b/packages/app/src/context/global-sdk.tsx @@ -1,4 +1,4 @@ -import type { Event } from "@opencode-ai/sdk/v2/client" +import type { Event } from "@kilocode/sdk/v2/client" import { createSimpleContext } from "@opencode-ai/ui/context" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { batch, onCleanup } from "solid-js" diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index f87c3fb394e..e5e83fee207 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -6,7 +6,7 @@ import type { ProviderAuthResponse, ProviderListResponse, Todo, -} from "@opencode-ai/sdk/v2/client" +} from "@kilocode/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" import { getFilename } from "@opencode-ai/util/path" import { diff --git a/packages/app/src/context/global-sync/bootstrap.ts b/packages/app/src/context/global-sync/bootstrap.ts index b2610656103..3a8f04861d5 100644 --- a/packages/app/src/context/global-sync/bootstrap.ts +++ b/packages/app/src/context/global-sync/bootstrap.ts @@ -8,7 +8,7 @@ import type { ProviderListResponse, QuestionRequest, Todo, -} from "@opencode-ai/sdk/v2/client" +} from "@kilocode/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" import { getFilename } from "@opencode-ai/util/path" import { retry } from "@opencode-ai/util/retry" diff --git a/packages/app/src/context/global-sync/child-store.ts b/packages/app/src/context/global-sync/child-store.ts index 2fe5b783039..10714174860 100644 --- a/packages/app/src/context/global-sync/child-store.ts +++ b/packages/app/src/context/global-sync/child-store.ts @@ -1,7 +1,7 @@ import { createRoot, createEffect, getOwner, onCleanup, runWithOwner, type Accessor, type Owner } from "solid-js" import { createStore, type SetStoreFunction, type Store } from "solid-js/store" import { Persist, persisted } from "@/utils/persist" -import type { VcsInfo } from "@opencode-ai/sdk/v2/client" +import type { VcsInfo } from "@kilocode/sdk/v2/client" import { DIR_IDLE_TTL_MS, MAX_DIR_STORES, diff --git a/packages/app/src/context/global-sync/event-reducer.test.ts b/packages/app/src/context/global-sync/event-reducer.test.ts index ab7f99cef3f..c75e987ab4c 100644 --- a/packages/app/src/context/global-sync/event-reducer.test.ts +++ b/packages/app/src/context/global-sync/event-reducer.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import type { Message, Part, PermissionRequest, Project, QuestionRequest, Session } from "@opencode-ai/sdk/v2/client" +import type { Message, Part, PermissionRequest, Project, QuestionRequest, Session } from "@kilocode/sdk/v2/client" import { createStore } from "solid-js/store" import type { State } from "./types" import { applyDirectoryEvent, applyGlobalEvent } from "./event-reducer" diff --git a/packages/app/src/context/global-sync/event-reducer.ts b/packages/app/src/context/global-sync/event-reducer.ts index 241dfb14d7d..dcba38eeb97 100644 --- a/packages/app/src/context/global-sync/event-reducer.ts +++ b/packages/app/src/context/global-sync/event-reducer.ts @@ -10,7 +10,7 @@ import type { Session, SessionStatus, Todo, -} from "@opencode-ai/sdk/v2/client" +} from "@kilocode/sdk/v2/client" import type { State, VcsCache } from "./types" import { trimSessions } from "./session-trim" diff --git a/packages/app/src/context/global-sync/session-trim.test.ts b/packages/app/src/context/global-sync/session-trim.test.ts index be12c074b5d..da9ef3498f5 100644 --- a/packages/app/src/context/global-sync/session-trim.test.ts +++ b/packages/app/src/context/global-sync/session-trim.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client" +import type { PermissionRequest, Session } from "@kilocode/sdk/v2/client" import { trimSessions } from "./session-trim" const session = (input: { id: string; parentID?: string; created: number; updated?: number; archived?: number }) => diff --git a/packages/app/src/context/global-sync/session-trim.ts b/packages/app/src/context/global-sync/session-trim.ts index 800ba74a684..8aa31400217 100644 --- a/packages/app/src/context/global-sync/session-trim.ts +++ b/packages/app/src/context/global-sync/session-trim.ts @@ -1,4 +1,4 @@ -import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client" +import type { PermissionRequest, Session } from "@kilocode/sdk/v2/client" import { cmp } from "./utils" import { SESSION_RECENT_LIMIT, SESSION_RECENT_WINDOW } from "./types" diff --git a/packages/app/src/context/global-sync/types.ts b/packages/app/src/context/global-sync/types.ts index c61dc337d8b..168c05489b8 100644 --- a/packages/app/src/context/global-sync/types.ts +++ b/packages/app/src/context/global-sync/types.ts @@ -16,7 +16,7 @@ import type { SessionStatus, Todo, VcsInfo, -} from "@opencode-ai/sdk/v2/client" +} from "@kilocode/sdk/v2/client" import type { Accessor } from "solid-js" import type { SetStoreFunction, Store } from "solid-js/store" diff --git a/packages/app/src/context/global-sync/utils.ts b/packages/app/src/context/global-sync/utils.ts index 6b78134a611..6ba75241642 100644 --- a/packages/app/src/context/global-sync/utils.ts +++ b/packages/app/src/context/global-sync/utils.ts @@ -1,4 +1,4 @@ -import type { Project, ProviderListResponse } from "@opencode-ai/sdk/v2/client" +import type { Project, ProviderListResponse } from "@kilocode/sdk/v2/client" export const cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0) diff --git a/packages/app/src/context/highlights.tsx b/packages/app/src/context/highlights.tsx index 476209e4173..54c609ac426 100644 --- a/packages/app/src/context/highlights.tsx +++ b/packages/app/src/context/highlights.tsx @@ -7,7 +7,7 @@ import { useSettings } from "@/context/settings" import { persisted } from "@/utils/persist" import { DialogReleaseNotes, type Highlight } from "@/components/dialog-release-notes" -const CHANGELOG_URL = "https://opencode.ai/changelog.json" +const CHANGELOG_URL = "https://kilo.ai/changelog.json" type Store = { version?: string diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx index 71f0294e7e6..5d80c2b5e49 100644 --- a/packages/app/src/context/layout.tsx +++ b/packages/app/src/context/layout.tsx @@ -5,7 +5,7 @@ import { useGlobalSync } from "./global-sync" import { useGlobalSDK } from "./global-sdk" import { useServer } from "./server" import { usePlatform } from "./platform" -import { Project } from "@opencode-ai/sdk/v2" +import { Project } from "@kilocode/sdk/v2" import { Persist, persisted, removePersisted } from "@/utils/persist" import { same } from "@/utils/same" import { createScrollPersistence, type SessionScroll } from "./layout-scroll" diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 04bc2fdaaaf..5062a3bfa21 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -10,7 +10,7 @@ import { useSettings } from "@/context/settings" import { Binary } from "@opencode-ai/util/binary" import { base64Encode } from "@opencode-ai/util/encode" import { decode64 } from "@/utils/base64" -import { EventSessionError } from "@opencode-ai/sdk/v2" +import { EventSessionError } from "@kilocode/sdk/v2" import { Persist, persisted } from "@/utils/persist" import { playSound, soundSrc } from "@/utils/sound" diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx index 988723834f9..f0b7ccceb1c 100644 --- a/packages/app/src/context/permission.tsx +++ b/packages/app/src/context/permission.tsx @@ -1,7 +1,7 @@ import { createMemo, onCleanup } from "solid-js" import { createStore, produce } from "solid-js/store" import { createSimpleContext } from "@opencode-ai/ui/context" -import type { PermissionRequest } from "@opencode-ai/sdk/v2/client" +import type { PermissionRequest } from "@kilocode/sdk/v2/client" import { Persist, persisted } from "@/utils/persist" import { useGlobalSDK } from "@/context/global-sdk" import { useGlobalSync } from "./global-sync" diff --git a/packages/app/src/context/sdk.tsx b/packages/app/src/context/sdk.tsx index bc97ea13acc..2eaf4627c04 100644 --- a/packages/app/src/context/sdk.tsx +++ b/packages/app/src/context/sdk.tsx @@ -1,4 +1,4 @@ -import type { Event } from "@opencode-ai/sdk/v2/client" +import type { Event } from "@kilocode/sdk/v2/client" import { createSimpleContext } from "@opencode-ai/ui/context" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { type Accessor, createEffect, createMemo, onCleanup } from "solid-js" diff --git a/packages/app/src/context/sync-optimistic.test.ts b/packages/app/src/context/sync-optimistic.test.ts index 7deeddd6ee6..f07242635ef 100644 --- a/packages/app/src/context/sync-optimistic.test.ts +++ b/packages/app/src/context/sync-optimistic.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import type { Message, Part } from "@opencode-ai/sdk/v2/client" +import type { Message, Part } from "@kilocode/sdk/v2/client" import { applyOptimisticAdd, applyOptimisticRemove } from "./sync" const userMessage = (id: string, sessionID: string): Message => ({ diff --git a/packages/app/src/context/sync.tsx b/packages/app/src/context/sync.tsx index 60888b1a6fd..b4ed77182d3 100644 --- a/packages/app/src/context/sync.tsx +++ b/packages/app/src/context/sync.tsx @@ -5,7 +5,7 @@ import { retry } from "@opencode-ai/util/retry" import { createSimpleContext } from "@opencode-ai/ui/context" import { useGlobalSync } from "./global-sync" import { useSDK } from "./sdk" -import type { Message, Part } from "@opencode-ai/sdk/v2/client" +import type { Message, Part } from "@kilocode/sdk/v2/client" function sortParts(parts: Part[]) { return parts.filter((part) => !!part?.id).sort((a, b) => cmp(a.id, b.id)) diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index 91a16b3b853..db735ac3599 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -102,7 +102,7 @@ export const dict = { "dialog.model.empty": "لا توجد نتائج للنماذج", "dialog.model.manage": "إدارة النماذج", "dialog.model.manage.description": "تخصيص النماذج التي تظهر في محدد النماذج.", - "dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من OpenCode", + "dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من Kilo", "dialog.model.unpaid.addMore.title": "إضافة المزيد من النماذج من موفرين مشهورين", "dialog.provider.viewAll": "عرض المزيد من الموفرين", "provider.connect.title": "اتصال {{provider}}", @@ -113,7 +113,7 @@ export const dict = { "provider.connect.status.waiting": "في انتظار التفويض...", "provider.connect.status.failed": "فشل التفويض: {{error}}", "provider.connect.apiKey.description": - "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.apiKey.label": "مفتاح واجهة برمجة تطبيقات {{provider}}", "provider.connect.apiKey.placeholder": "مفتاح API", "provider.connect.apiKey.required": "مفتاح API مطلوب", @@ -127,7 +127,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "قم بزيارة ", "provider.connect.oauth.code.visit.link": "هذا الرابط", "provider.connect.oauth.code.visit.suffix": - " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.oauth.code.label": "رمز تفويض {{method}}", "provider.connect.oauth.code.placeholder": "رمز التفويض", "provider.connect.oauth.code.required": "رمز التفويض مطلوب", @@ -135,7 +135,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "قم بزيارة ", "provider.connect.oauth.auto.visit.link": "هذا الرابط", "provider.connect.oauth.auto.visit.suffix": - " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.oauth.auto.confirmationCode": "رمز التأكيد", "provider.connect.toast.connected.title": "تم توصيل {{provider}}", "provider.connect.toast.connected.description": "نماذج {{provider}} متاحة الآن للاستخدام.", @@ -277,7 +277,7 @@ export const dict = { "dialog.directory.search.placeholder": "البحث في المجلدات", "dialog.directory.empty": "لم يتم العثور على مجلدات", "dialog.server.title": "الخوادم", - "dialog.server.description": "تبديل خادم OpenCode الذي يتصل به هذا التطبيق.", + "dialog.server.description": "تبديل خادم Kilo الذي يتصل به هذا التطبيق.", "dialog.server.search.placeholder": "البحث في الخوادم", "dialog.server.empty": "لا توجد خوادم بعد", "dialog.server.add.title": "إضافة خادم", @@ -385,7 +385,7 @@ export const dict = { "toast.session.unshare.failed.description": "حدث خطأ أثناء إلغاء مشاركة الجلسة", "toast.session.listFailed.title": "فشل تحميل الجلسات لـ {{project}}", "toast.update.title": "تحديث متاح", - "toast.update.description": "نسخة جديدة من OpenCode ({{version}}) متاحة الآن للتثبيت.", + "toast.update.description": "نسخة جديدة من Kilo ({{version}}) متاحة الآن للتثبيت.", "toast.update.action.installRestart": "تثبيت وإعادة تشغيل", "toast.update.action.notYet": "ليس الآن", "error.page.title": "حدث خطأ ما", @@ -395,7 +395,7 @@ export const dict = { "error.page.action.checking": "جارٍ التحقق...", "error.page.action.checkUpdates": "التحقق من وجود تحديثات", "error.page.action.updateTo": "تحديث إلى {{version}}", - "error.page.report.prefix": "يرجى الإبلاغ عن هذا الخطأ لفريق OpenCode", + "error.page.report.prefix": "يرجى الإبلاغ عن هذا الخطأ لفريق Kilo", "error.page.report.discord": "على Discord", "error.page.version": "الإصدار: {{version}}", "error.dev.rootNotFound": @@ -411,7 +411,7 @@ export const dict = { "error.chain.didYouMean": "هل كنت تعني: {{suggestions}}", "error.chain.modelNotFound": "النموذج غير موجود: {{provider}}/{{model}}", "error.chain.checkConfig": "تحقق من أسماء الموفر/النموذج في التكوين (opencode.json)", - "error.chain.mcpFailed": 'فشل خادم MCP "{{name}}". لاحظ أن OpenCode لا يدعم مصادقة MCP بعد.', + "error.chain.mcpFailed": 'فشل خادم MCP "{{name}}". لاحظ أن Kilo لا يدعم مصادقة MCP بعد.', "error.chain.providerAuthFailed": "فشلت مصادقة الموفر ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'فشل تهيئة الموفر "{{provider}}". تحقق من بيانات الاعتماد والتكوين.', "error.chain.configJsonInvalid": "ملف التكوين في {{path}} ليس JSON(C) صالحًا", @@ -512,19 +512,19 @@ export const dict = { "sidebar.workspaces.enable": "تمكين مساحات العمل", "sidebar.workspaces.disable": "تعطيل مساحات العمل", "sidebar.gettingStarted.title": "البدء", - "sidebar.gettingStarted.line1": "يتضمن OpenCode نماذج مجانية حتى تتمكن من البدء فورًا.", + "sidebar.gettingStarted.line1": "يتضمن Kilo نماذج مجانية حتى تتمكن من البدء فورًا.", "sidebar.gettingStarted.line2": "قم بتوصيل أي موفر لاستخدام النماذج، بما في ذلك Claude و GPT و Gemini وما إلى ذلك.", "sidebar.project.recentSessions": "الجلسات الحديثة", "sidebar.project.viewAllSessions": "عرض جميع الجلسات", "sidebar.project.clearNotifications": "مسح الإشعارات", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "سطح المكتب", "settings.section.server": "الخادم", "settings.tab.general": "عام", "settings.tab.shortcuts": "اختصارات", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "تكامل WSL", - "settings.desktop.wsl.description": "تشغيل خادم OpenCode داخل WSL على Windows.", + "settings.desktop.wsl.description": "تشغيل خادم Kilo داخل WSL على Windows.", "settings.general.section.appearance": "المظهر", "settings.general.section.notifications": "إشعارات النظام", "settings.general.section.updates": "التحديثات", @@ -532,11 +532,11 @@ export const dict = { "settings.general.section.feed": "الخلاصة", "settings.general.section.display": "شاشة العرض", "settings.general.row.language.title": "اللغة", - "settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode", + "settings.general.row.language.description": "تغيير لغة العرض لـ Kilo", "settings.general.row.appearance.title": "المظهر", - "settings.general.row.appearance.description": "تخصيص كيفية ظهور OpenCode على جهازك", + "settings.general.row.appearance.description": "تخصيص كيفية ظهور Kilo على جهازك", "settings.general.row.theme.title": "السمة", - "settings.general.row.theme.description": "تخصيص سمة OpenCode.", + "settings.general.row.theme.description": "تخصيص سمة Kilo.", "settings.general.row.font.title": "الخط", "settings.general.row.font.description": "تخصيص الخط الأحادي المستخدم في كتل التعليمات البرمجية", "settings.general.row.shellToolPartsExpanded.title": "توسيع أجزاء أداة shell", @@ -552,13 +552,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "ملاحظات الإصدار", "settings.general.row.releaseNotes.description": 'عرض نوافذ "ما الجديد" المنبثقة بعد التحديثات', "settings.updates.row.startup.title": "التحقق من التحديثات عند بدء التشغيل", - "settings.updates.row.startup.description": "التحقق تلقائيًا من التحديثات عند تشغيل OpenCode", + "settings.updates.row.startup.description": "التحقق تلقائيًا من التحديثات عند تشغيل Kilo", "settings.updates.row.check.title": "التحقق من التحديثات", "settings.updates.row.check.description": "التحقق يدويًا من التحديثات وتثبيتها إذا كانت متاحة", "settings.updates.action.checkNow": "تحقق الآن", "settings.updates.action.checking": "جارٍ التحقق...", "settings.updates.toast.latest.title": "أنت على آخر إصدار", - "settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من OpenCode.", + "settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 7682a12b697..b05c2cd5afc 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -102,7 +102,7 @@ export const dict = { "dialog.model.empty": "Nenhum resultado de modelo", "dialog.model.manage": "Gerenciar modelos", "dialog.model.manage.description": "Personalizar quais modelos aparecem no seletor de modelos.", - "dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo OpenCode", + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo Kilo", "dialog.model.unpaid.addMore.title": "Adicionar mais modelos de provedores populares", "dialog.provider.viewAll": "Ver mais provedores", "provider.connect.title": "Conectar {{provider}}", @@ -113,7 +113,7 @@ export const dict = { "provider.connect.status.waiting": "Aguardando autorização...", "provider.connect.status.failed": "Autorização falhou: {{error}}", "provider.connect.apiKey.description": - "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no OpenCode.", + "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no Kilo.", "provider.connect.apiKey.label": "Chave de API do {{provider}}", "provider.connect.apiKey.placeholder": "Chave de API", "provider.connect.apiKey.required": "A chave de API é obrigatória", @@ -127,7 +127,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visite ", "provider.connect.oauth.code.visit.link": "este link", "provider.connect.oauth.code.visit.suffix": - " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no OpenCode.", + " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no Kilo.", "provider.connect.oauth.code.label": "Código de autorização {{method}}", "provider.connect.oauth.code.placeholder": "Código de autorização", "provider.connect.oauth.code.required": "O código de autorização é obrigatório", @@ -135,7 +135,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visite ", "provider.connect.oauth.auto.visit.link": "este link", "provider.connect.oauth.auto.visit.suffix": - " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no OpenCode.", + " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no Kilo.", "provider.connect.oauth.auto.confirmationCode": "Código de confirmação", "provider.connect.toast.connected.title": "{{provider}} conectado", "provider.connect.toast.connected.description": "Modelos do {{provider}} agora estão disponíveis para uso.", @@ -277,7 +277,7 @@ export const dict = { "dialog.directory.search.placeholder": "Buscar pastas", "dialog.directory.empty": "Nenhuma pasta encontrada", "dialog.server.title": "Servidores", - "dialog.server.description": "Trocar para qual servidor OpenCode este aplicativo se conecta.", + "dialog.server.description": "Trocar para qual servidor Kilo este aplicativo se conecta.", "dialog.server.search.placeholder": "Buscar servidores", "dialog.server.empty": "Nenhum servidor ainda", "dialog.server.add.title": "Adicionar um servidor", @@ -386,7 +386,7 @@ export const dict = { "toast.session.unshare.failed.description": "Ocorreu um erro ao parar de compartilhar a sessão", "toast.session.listFailed.title": "Falha ao carregar sessões para {{project}}", "toast.update.title": "Atualização disponível", - "toast.update.description": "Uma nova versão do OpenCode ({{version}}) está disponível para instalação.", + "toast.update.description": "Uma nova versão do Kilo ({{version}}) está disponível para instalação.", "toast.update.action.installRestart": "Instalar e reiniciar", "toast.update.action.notYet": "Agora não", "error.page.title": "Algo deu errado", @@ -396,7 +396,7 @@ export const dict = { "error.page.action.checking": "Verificando...", "error.page.action.checkUpdates": "Verificar atualizações", "error.page.action.updateTo": "Atualizar para {{version}}", - "error.page.report.prefix": "Por favor, reporte este erro para a equipe do OpenCode", + "error.page.report.prefix": "Por favor, reporte este erro para a equipe do Kilo", "error.page.report.discord": "no Discord", "error.page.version": "Versão: {{version}}", "error.dev.rootNotFound": @@ -412,7 +412,7 @@ export const dict = { "error.chain.didYouMean": "Você quis dizer: {{suggestions}}", "error.chain.modelNotFound": "Modelo não encontrado: {{provider}}/{{model}}", "error.chain.checkConfig": "Verifique os nomes de provedor/modelo na sua configuração (opencode.json)", - "error.chain.mcpFailed": 'Servidor MCP "{{name}}" falhou. Nota: OpenCode ainda não suporta autenticação MCP.', + "error.chain.mcpFailed": 'Servidor MCP "{{name}}" falhou. Nota: Kilo ainda não suporta autenticação MCP.', "error.chain.providerAuthFailed": "Autenticação do provedor falhou ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Falha ao inicializar provedor "{{provider}}". Verifique credenciais e configuração.', @@ -518,19 +518,19 @@ export const dict = { "sidebar.workspaces.enable": "Habilitar espaços de trabalho", "sidebar.workspaces.disable": "Desabilitar espaços de trabalho", "sidebar.gettingStarted.title": "Começando", - "sidebar.gettingStarted.line1": "OpenCode inclui modelos gratuitos para você começar imediatamente.", + "sidebar.gettingStarted.line1": "Kilo inclui modelos gratuitos para você começar imediatamente.", "sidebar.gettingStarted.line2": "Conecte qualquer provedor para usar modelos, incluindo Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sessões recentes", "sidebar.project.viewAllSessions": "Ver todas as sessões", "sidebar.project.clearNotifications": "Limpar notificações", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Servidor", "settings.tab.general": "Geral", "settings.tab.shortcuts": "Atalhos", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Executar o servidor OpenCode dentro do WSL no Windows.", + "settings.desktop.wsl.description": "Executar o servidor Kilo dentro do WSL no Windows.", "settings.general.section.appearance": "Aparência", "settings.general.section.notifications": "Notificações do sistema", "settings.general.section.updates": "Atualizações", @@ -538,11 +538,11 @@ export const dict = { "settings.general.section.feed": "Feed", "settings.general.section.display": "Tela", "settings.general.row.language.title": "Idioma", - "settings.general.row.language.description": "Alterar o idioma de exibição do OpenCode", + "settings.general.row.language.description": "Alterar o idioma de exibição do Kilo", "settings.general.row.appearance.title": "Aparência", - "settings.general.row.appearance.description": "Personalize como o OpenCode aparece no seu dispositivo", + "settings.general.row.appearance.description": "Personalize como o Kilo aparece no seu dispositivo", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Personalize como o OpenCode é tematizado.", + "settings.general.row.theme.description": "Personalize como o Kilo é tematizado.", "settings.general.row.font.title": "Fonte", "settings.general.row.font.description": "Personalize a fonte monoespaçada usada em blocos de código", "settings.general.row.shellToolPartsExpanded.title": "Expandir partes da ferramenta shell", @@ -558,13 +558,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "Notas da versão", "settings.general.row.releaseNotes.description": 'Mostrar pop-ups de "Novidades" após atualizações', "settings.updates.row.startup.title": "Verificar atualizações ao iniciar", - "settings.updates.row.startup.description": "Verificar atualizações automaticamente quando o OpenCode iniciar", + "settings.updates.row.startup.description": "Verificar atualizações automaticamente quando o Kilo iniciar", "settings.updates.row.check.title": "Verificar atualizações", "settings.updates.row.check.description": "Verificar atualizações manualmente e instalar se houver", "settings.updates.action.checkNow": "Verificar agora", "settings.updates.action.checking": "Verificando...", "settings.updates.toast.latest.title": "Você está atualizado", - "settings.updates.toast.latest.description": "Você está usando a versão mais recente do OpenCode.", + "settings.updates.toast.latest.description": "Você está usando a versão mais recente do Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index cb0274042ed..010bd703e7a 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -112,7 +112,7 @@ export const dict = { "dialog.model.manage": "Upravljaj modelima", "dialog.model.manage.description": "Prilagodi koji se modeli prikazuju u izborniku modela.", - "dialog.model.unpaid.freeModels.title": "Besplatni modeli koje obezbjeđuje OpenCode", + "dialog.model.unpaid.freeModels.title": "Besplatni modeli koje obezbjeđuje Kilo", "dialog.model.unpaid.addMore.title": "Dodaj još modela od popularnih provajdera", "dialog.provider.viewAll": "Prikaži više provajdera", @@ -125,7 +125,7 @@ export const dict = { "provider.connect.status.waiting": "Čekanje na autorizaciju...", "provider.connect.status.failed": "Autorizacija nije uspjela: {{error}}", "provider.connect.apiKey.description": - "Unesi svoj {{provider}} API ključ da povežeš račun i koristiš {{provider}} modele u OpenCode-u.", + "Unesi svoj {{provider}} API ključ da povežeš račun i koristiš {{provider}} modele u Kilo-u.", "provider.connect.apiKey.label": "{{provider}} API ključ", "provider.connect.apiKey.placeholder": "API ključ", "provider.connect.apiKey.required": "API ključ je obavezan", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Posjeti ", "provider.connect.oauth.code.visit.link": "ovaj link", "provider.connect.oauth.code.visit.suffix": - " da preuzmeš autorizacijski kod i povežeš račun te koristiš {{provider}} modele u OpenCode-u.", + " da preuzmeš autorizacijski kod i povežeš račun te koristiš {{provider}} modele u Kilo-u.", "provider.connect.oauth.code.label": "{{method}} autorizacijski kod", "provider.connect.oauth.code.placeholder": "Autorizacijski kod", "provider.connect.oauth.code.required": "Autorizacijski kod je obavezan", @@ -147,7 +147,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Posjeti ", "provider.connect.oauth.auto.visit.link": "ovaj link", "provider.connect.oauth.auto.visit.suffix": - " i unesi kod ispod da povežeš račun i koristiš {{provider}} modele u OpenCode-u.", + " i unesi kod ispod da povežeš račun i koristiš {{provider}} modele u Kilo-u.", "provider.connect.oauth.auto.confirmationCode": "Kod za potvrdu", "provider.connect.toast.connected.title": "{{provider}} povezan", "provider.connect.toast.connected.description": "{{provider}} modeli su sada dostupni za korištenje.", @@ -304,7 +304,7 @@ export const dict = { "dialog.directory.empty": "Nema pronađenih foldera", "dialog.server.title": "Serveri", - "dialog.server.description": "Promijeni na koji se OpenCode server ova aplikacija povezuje.", + "dialog.server.description": "Promijeni na koji se Kilo server ova aplikacija povezuje.", "dialog.server.search.placeholder": "Pretraži servere", "dialog.server.empty": "Još nema servera", "dialog.server.add.title": "Dodaj server", @@ -431,7 +431,7 @@ export const dict = { "toast.session.listFailed.title": "Neuspjelo učitavanje sesija za {{project}}", "toast.update.title": "Dostupno ažuriranje", - "toast.update.description": "Nova verzija OpenCode-a ({{version}}) je dostupna za instalaciju.", + "toast.update.description": "Nova verzija Kilo-a ({{version}}) je dostupna za instalaciju.", "toast.update.action.installRestart": "Instaliraj i restartuj", "toast.update.action.notYet": "Ne još", @@ -442,7 +442,7 @@ export const dict = { "error.page.action.checking": "Provjera...", "error.page.action.checkUpdates": "Provjeri ažuriranja", "error.page.action.updateTo": "Ažuriraj na {{version}}", - "error.page.report.prefix": "Molimo prijavi ovu grešku OpenCode timu", + "error.page.report.prefix": "Molimo prijavi ovu grešku Kilo timu", "error.page.report.discord": "na Discordu", "error.page.version": "Verzija: {{version}}", @@ -461,7 +461,7 @@ export const dict = { "error.chain.didYouMean": "Da li si mislio: {{suggestions}}", "error.chain.modelNotFound": "Model nije pronađen: {{provider}}/{{model}}", "error.chain.checkConfig": "Provjeri konfiguraciju (opencode.json) provider/model names", - "error.chain.mcpFailed": 'MCP server "{{name}}" nije uspio. Napomena: OpenCode još ne podržava MCP autentifikaciju.', + "error.chain.mcpFailed": 'MCP server "{{name}}" nije uspio. Napomena: Kilo još ne podržava MCP autentifikaciju.', "error.chain.providerAuthFailed": "Autentifikacija provajdera nije uspjela ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Neuspjelo inicijalizovanje provajdera "{{provider}}". Provjeri kredencijale i konfiguraciju.', @@ -579,13 +579,13 @@ export const dict = { "sidebar.workspaces.enable": "Omogući radne prostore", "sidebar.workspaces.disable": "Onemogući radne prostore", "sidebar.gettingStarted.title": "Početak", - "sidebar.gettingStarted.line1": "OpenCode uključuje besplatne modele, tako da možeš odmah početi.", + "sidebar.gettingStarted.line1": "Kilo uključuje besplatne modele, tako da možeš odmah početi.", "sidebar.gettingStarted.line2": "Poveži bilo kojeg provajdera da koristiš modele, npr. Claude, GPT, Gemini itd.", "sidebar.project.recentSessions": "Nedavne sesije", "sidebar.project.viewAllSessions": "Prikaži sve sesije", "sidebar.project.clearNotifications": "Očisti obavijesti", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", @@ -593,7 +593,7 @@ export const dict = { "settings.tab.shortcuts": "Prečice", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integracija", - "settings.desktop.wsl.description": "Pokreni OpenCode server unutar WSL-a na Windowsu.", + "settings.desktop.wsl.description": "Pokreni Kilo server unutar WSL-a na Windowsu.", "settings.general.section.appearance": "Izgled", "settings.general.section.notifications": "Sistemske obavijesti", @@ -603,11 +603,11 @@ export const dict = { "settings.general.section.display": "Prikaz", "settings.general.row.language.title": "Jezik", - "settings.general.row.language.description": "Promijeni jezik prikaza u OpenCode-u", + "settings.general.row.language.description": "Promijeni jezik prikaza u Kilo-u", "settings.general.row.appearance.title": "Izgled", - "settings.general.row.appearance.description": "Prilagodi kako OpenCode izgleda na tvom uređaju", + "settings.general.row.appearance.description": "Prilagodi kako Kilo izgleda na tvom uređaju", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Prilagodi temu OpenCode-a.", + "settings.general.row.theme.description": "Prilagodi temu Kilo-a.", "settings.general.row.font.title": "Font", "settings.general.row.font.description": "Prilagodi monospace font koji se koristi u blokovima koda", @@ -626,13 +626,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Prikaži iskačuće prozore "Šta je novo" nakon ažuriranja', "settings.updates.row.startup.title": "Provjeri ažuriranja pri pokretanju", - "settings.updates.row.startup.description": "Automatski provjerava ažuriranja kada se OpenCode pokrene", + "settings.updates.row.startup.description": "Automatski provjerava ažuriranja kada se Kilo pokrene", "settings.updates.row.check.title": "Provjeri ažuriranja", "settings.updates.row.check.description": "Ručno provjeri ažuriranja i instaliraj ako su dostupna", "settings.updates.action.checkNow": "Provjeri sada", "settings.updates.action.checking": "Provjera...", "settings.updates.toast.latest.title": "Sve je ažurno", - "settings.updates.toast.latest.description": "Koristiš najnoviju verziju OpenCode-a.", + "settings.updates.toast.latest.description": "Koristiš najnoviju verziju Kilo-a.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index 30cc555eb1a..a4bd68087e2 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -112,7 +112,7 @@ export const dict = { "dialog.model.manage": "Administrer modeller", "dialog.model.manage.description": "Tilpas hvilke modeller der vises i modelvælgeren.", - "dialog.model.unpaid.freeModels.title": "Gratis modeller leveret af OpenCode", + "dialog.model.unpaid.freeModels.title": "Gratis modeller leveret af Kilo", "dialog.model.unpaid.addMore.title": "Tilføj flere modeller fra populære udbydere", "dialog.provider.viewAll": "Vis flere udbydere", @@ -125,7 +125,7 @@ export const dict = { "provider.connect.status.waiting": "Venter på godkendelse...", "provider.connect.status.failed": "Godkendelse mislykkedes: {{error}}", "provider.connect.apiKey.description": - "Indtast din {{provider}} API-nøgle for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + "Indtast din {{provider}} API-nøgle for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.apiKey.label": "{{provider}} API-nøgle", "provider.connect.apiKey.placeholder": "API-nøgle", "provider.connect.apiKey.required": "API-nøgle er påkrævet", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besøg ", "provider.connect.oauth.code.visit.link": "dette link", "provider.connect.oauth.code.visit.suffix": - " for at hente din godkendelseskode for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + " for at hente din godkendelseskode for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.oauth.code.label": "{{method}} godkendelseskode", "provider.connect.oauth.code.placeholder": "Godkendelseskode", "provider.connect.oauth.code.required": "Godkendelseskode er påkrævet", @@ -147,7 +147,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besøg ", "provider.connect.oauth.auto.visit.link": "dette link", "provider.connect.oauth.auto.visit.suffix": - " og indtast koden nedenfor for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + " og indtast koden nedenfor for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.oauth.auto.confirmationCode": "Bekræftelseskode", "provider.connect.toast.connected.title": "{{provider}} forbundet", "provider.connect.toast.connected.description": "{{provider}} modeller er nu tilgængelige.", @@ -302,7 +302,7 @@ export const dict = { "dialog.directory.empty": "Ingen mapper fundet", "dialog.server.title": "Servere", - "dialog.server.description": "Skift hvilken OpenCode-server denne app forbinder til.", + "dialog.server.description": "Skift hvilken Kilo-server denne app forbinder til.", "dialog.server.search.placeholder": "Søg servere", "dialog.server.empty": "Ingen servere endnu", "dialog.server.add.title": "Tilføj en server", @@ -428,7 +428,7 @@ export const dict = { "toast.session.listFailed.title": "Kunne ikke indlæse sessioner for {{project}}", "toast.update.title": "Opdatering tilgængelig", - "toast.update.description": "En ny version af OpenCode ({{version}}) er nu tilgængelig til installation.", + "toast.update.description": "En ny version af Kilo ({{version}}) er nu tilgængelig til installation.", "toast.update.action.installRestart": "Installer og genstart", "toast.update.action.notYet": "Ikke endnu", @@ -439,7 +439,7 @@ export const dict = { "error.page.action.checking": "Tjekker...", "error.page.action.checkUpdates": "Tjek for opdateringer", "error.page.action.updateTo": "Opdater til {{version}}", - "error.page.report.prefix": "Rapporter venligst denne fejl til OpenCode-teamet", + "error.page.report.prefix": "Rapporter venligst denne fejl til Kilo-teamet", "error.page.report.discord": "på Discord", "error.page.version": "Version: {{version}}", @@ -458,7 +458,7 @@ export const dict = { "error.chain.didYouMean": "Mente du: {{suggestions}}", "error.chain.modelNotFound": "Model ikke fundet: {{provider}}/{{model}}", "error.chain.checkConfig": "Tjek dine konfigurations (opencode.json) udbyder/modelnavne", - "error.chain.mcpFailed": 'MCP-server "{{name}}" fejlede. Bemærk, OpenCode understøtter ikke MCP-godkendelse endnu.', + "error.chain.mcpFailed": 'MCP-server "{{name}}" fejlede. Bemærk, Kilo understøtter ikke MCP-godkendelse endnu.', "error.chain.providerAuthFailed": "Udbydergodkendelse mislykkedes ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Kunne ikke initialisere udbyder "{{provider}}". Tjek legitimationsoplysninger og konfiguration.', @@ -575,20 +575,20 @@ export const dict = { "sidebar.workspaces.enable": "Aktiver arbejdsområder", "sidebar.workspaces.disable": "Deaktiver arbejdsområder", "sidebar.gettingStarted.title": "Kom i gang", - "sidebar.gettingStarted.line1": "OpenCode inkluderer gratis modeller så du kan starte med det samme.", + "sidebar.gettingStarted.line1": "Kilo inkluderer gratis modeller så du kan starte med det samme.", "sidebar.gettingStarted.line2": "Forbind enhver udbyder for at bruge modeller, inkl. Claude, GPT, Gemini osv.", "sidebar.project.recentSessions": "Seneste sessioner", "sidebar.project.viewAllSessions": "Vis alle sessioner", "sidebar.project.clearNotifications": "Ryd notifikationer", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", "settings.tab.general": "Generelt", "settings.tab.shortcuts": "Genveje", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Kør OpenCode-serveren inde i WSL på Windows.", + "settings.desktop.wsl.description": "Kør Kilo-serveren inde i WSL på Windows.", "settings.general.section.appearance": "Udseende", "settings.general.section.notifications": "Systemmeddelelser", @@ -598,11 +598,11 @@ export const dict = { "settings.general.section.display": "Skærm", "settings.general.row.language.title": "Sprog", - "settings.general.row.language.description": "Ændr visningssproget for OpenCode", + "settings.general.row.language.description": "Ændr visningssproget for Kilo", "settings.general.row.appearance.title": "Udseende", - "settings.general.row.appearance.description": "Tilpas hvordan OpenCode ser ud på din enhed", + "settings.general.row.appearance.description": "Tilpas hvordan Kilo ser ud på din enhed", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Tilpas hvordan OpenCode er temabestemt.", + "settings.general.row.theme.description": "Tilpas hvordan Kilo er temabestemt.", "settings.general.row.font.title": "Skrifttype", "settings.general.row.font.description": "Tilpas mono-skrifttypen brugt i kodeblokke", @@ -620,13 +620,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Vis "Hvad er nyt"-popups efter opdateringer', "settings.updates.row.startup.title": "Tjek for opdateringer ved opstart", - "settings.updates.row.startup.description": "Tjek automatisk for opdateringer, når OpenCode starter", + "settings.updates.row.startup.description": "Tjek automatisk for opdateringer, når Kilo starter", "settings.updates.row.check.title": "Tjek for opdateringer", "settings.updates.row.check.description": "Tjek manuelt for opdateringer og installer, hvis tilgængelig", "settings.updates.action.checkNow": "Tjek nu", "settings.updates.action.checking": "Tjekker...", "settings.updates.toast.latest.title": "Du er opdateret", - "settings.updates.toast.latest.description": "Du kører den nyeste version af OpenCode.", + "settings.updates.toast.latest.description": "Du kører den nyeste version af Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index 3a7bbe92772..8bfe2bf980f 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -106,7 +106,7 @@ export const dict = { "dialog.model.empty": "Keine Modellergebnisse", "dialog.model.manage": "Modelle verwalten", "dialog.model.manage.description": "Anpassen, welche Modelle in der Modellauswahl erscheinen.", - "dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von OpenCode", + "dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von Kilo", "dialog.model.unpaid.addMore.title": "Weitere Modelle von beliebten Anbietern hinzufügen", "dialog.provider.viewAll": "Mehr Anbieter anzeigen", "provider.connect.title": "{{provider}} verbinden", @@ -117,7 +117,7 @@ export const dict = { "provider.connect.status.waiting": "Warten auf Autorisierung...", "provider.connect.status.failed": "Autorisierung fehlgeschlagen: {{error}}", "provider.connect.apiKey.description": - "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.apiKey.label": "{{provider}} API-Schlüssel", "provider.connect.apiKey.placeholder": "API-Schlüssel", "provider.connect.apiKey.required": "API-Schlüssel ist erforderlich", @@ -131,7 +131,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besuchen Sie ", "provider.connect.oauth.code.visit.link": "diesen Link", "provider.connect.oauth.code.visit.suffix": - ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.oauth.code.label": "{{method}} Autorisierungscode", "provider.connect.oauth.code.placeholder": "Autorisierungscode", "provider.connect.oauth.code.required": "Autorisierungscode ist erforderlich", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besuchen Sie ", "provider.connect.oauth.auto.visit.link": "diesen Link", "provider.connect.oauth.auto.visit.suffix": - " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.oauth.auto.confirmationCode": "Bestätigungscode", "provider.connect.toast.connected.title": "{{provider}} verbunden", "provider.connect.toast.connected.description": "{{provider}} Modelle sind jetzt verfügbar.", @@ -283,7 +283,7 @@ export const dict = { "dialog.directory.search.placeholder": "Ordner durchsuchen", "dialog.directory.empty": "Keine Ordner gefunden", "dialog.server.title": "Server", - "dialog.server.description": "Wechseln Sie den OpenCode-Server, mit dem sich diese App verbindet.", + "dialog.server.description": "Wechseln Sie den Kilo-Server, mit dem sich diese App verbindet.", "dialog.server.search.placeholder": "Server durchsuchen", "dialog.server.empty": "Noch keine Server", "dialog.server.add.title": "Server hinzufügen", @@ -393,7 +393,7 @@ export const dict = { "toast.session.unshare.failed.description": "Beim Aufheben des Teilens ist ein Fehler aufgetreten", "toast.session.listFailed.title": "Sitzungen für {{project}} konnten nicht geladen werden", "toast.update.title": "Update verfügbar", - "toast.update.description": "Eine neue Version von OpenCode ({{version}}) ist zur Installation verfügbar.", + "toast.update.description": "Eine neue Version von Kilo ({{version}}) ist zur Installation verfügbar.", "toast.update.action.installRestart": "Installieren und neu starten", "toast.update.action.notYet": "Noch nicht", "error.page.title": "Etwas ist schiefgelaufen", @@ -403,7 +403,7 @@ export const dict = { "error.page.action.checking": "Prüfen...", "error.page.action.checkUpdates": "Nach Updates suchen", "error.page.action.updateTo": "Auf {{version}} aktualisieren", - "error.page.report.prefix": "Bitte melden Sie diesen Fehler dem OpenCode-Team", + "error.page.report.prefix": "Bitte melden Sie diesen Fehler dem Kilo-Team", "error.page.report.discord": "auf Discord", "error.page.version": "Version: {{version}}", "error.dev.rootNotFound": @@ -420,7 +420,7 @@ export const dict = { "error.chain.modelNotFound": "Modell nicht gefunden: {{provider}}/{{model}}", "error.chain.checkConfig": "Überprüfen Sie Ihre Konfiguration (opencode.json) auf Anbieter-/Modellnamen", "error.chain.mcpFailed": - 'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: OpenCode unterstützt noch keine MCP-Authentifizierung.', + 'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: Kilo unterstützt noch keine MCP-Authentifizierung.', "error.chain.providerAuthFailed": "Anbieter-Authentifizierung fehlgeschlagen ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Anbieter "{{provider}}" konnte nicht initialisiert werden. Überprüfen Sie Anmeldeinformationen und Konfiguration.', @@ -526,20 +526,20 @@ export const dict = { "sidebar.workspaces.enable": "Arbeitsbereiche aktivieren", "sidebar.workspaces.disable": "Arbeitsbereiche deaktivieren", "sidebar.gettingStarted.title": "Erste Schritte", - "sidebar.gettingStarted.line1": "OpenCode enthält kostenlose Modelle, damit Sie sofort loslegen können.", + "sidebar.gettingStarted.line1": "Kilo enthält kostenlose Modelle, damit Sie sofort loslegen können.", "sidebar.gettingStarted.line2": "Verbinden Sie einen beliebigen Anbieter, um Modelle wie Claude, GPT, Gemini usw. zu nutzen.", "sidebar.project.recentSessions": "Letzte Sitzungen", "sidebar.project.viewAllSessions": "Alle Sitzungen anzeigen", "sidebar.project.clearNotifications": "Benachrichtigungen löschen", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", "settings.tab.general": "Allgemein", "settings.tab.shortcuts": "Tastenkombinationen", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL-Integration", - "settings.desktop.wsl.description": "OpenCode-Server innerhalb von WSL unter Windows ausführen.", + "settings.desktop.wsl.description": "Kilo-Server innerhalb von WSL unter Windows ausführen.", "settings.general.section.appearance": "Erscheinungsbild", "settings.general.section.notifications": "Systembenachrichtigungen", "settings.general.section.updates": "Updates", @@ -547,11 +547,11 @@ export const dict = { "settings.general.section.feed": "Feed", "settings.general.section.display": "Anzeige", "settings.general.row.language.title": "Sprache", - "settings.general.row.language.description": "Die Anzeigesprache für OpenCode ändern", + "settings.general.row.language.description": "Die Anzeigesprache für Kilo ändern", "settings.general.row.appearance.title": "Erscheinungsbild", - "settings.general.row.appearance.description": "Anpassen, wie OpenCode auf Ihrem Gerät aussieht", + "settings.general.row.appearance.description": "Anpassen, wie Kilo auf Ihrem Gerät aussieht", "settings.general.row.theme.title": "Thema", - "settings.general.row.theme.description": "Das Thema von OpenCode anpassen.", + "settings.general.row.theme.description": "Das Thema von Kilo anpassen.", "settings.general.row.font.title": "Schriftart", "settings.general.row.font.description": "Die in Codeblöcken verwendete Monospace-Schriftart anpassen", "settings.general.row.shellToolPartsExpanded.title": "Shell-Tool-Abschnitte ausklappen", @@ -567,13 +567,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "Versionshinweise", "settings.general.row.releaseNotes.description": '"Neuigkeiten"-Pop-ups nach Updates anzeigen', "settings.updates.row.startup.title": "Beim Start nach Updates suchen", - "settings.updates.row.startup.description": "Beim Start von OpenCode automatisch nach Updates suchen", + "settings.updates.row.startup.description": "Beim Start von Kilo automatisch nach Updates suchen", "settings.updates.row.check.title": "Nach Updates suchen", "settings.updates.row.check.description": "Manuell nach Updates suchen und installieren, wenn verfügbar", "settings.updates.action.checkNow": "Jetzt prüfen", "settings.updates.action.checking": "Wird geprüft...", "settings.updates.toast.latest.title": "Du bist auf dem neuesten Stand", - "settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von OpenCode.", + "settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index 0b4388ceb19..22ba166d9ab 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -113,7 +113,7 @@ export const dict = { "dialog.model.manage.description": "Customize which models appear in the model selector.", "dialog.model.manage.provider.toggle": "Toggle all {{provider}} models", - "dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode", + "dialog.model.unpaid.freeModels.title": "Free models provided by Kilo", "dialog.model.unpaid.addMore.title": "Add more models from popular providers", "dialog.provider.viewAll": "Show more providers", @@ -126,7 +126,7 @@ export const dict = { "provider.connect.status.waiting": "Waiting for authorization...", "provider.connect.status.failed": "Authorization failed: {{error}}", "provider.connect.apiKey.description": - "Enter your {{provider}} API key to connect your account and use {{provider}} models in OpenCode.", + "Enter your {{provider}} API key to connect your account and use {{provider}} models in Kilo.", "provider.connect.apiKey.label": "{{provider}} API key", "provider.connect.apiKey.placeholder": "API key", "provider.connect.apiKey.required": "API key is required", @@ -140,7 +140,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visit ", "provider.connect.oauth.code.visit.link": "this link", "provider.connect.oauth.code.visit.suffix": - " to collect your authorization code to connect your account and use {{provider}} models in OpenCode.", + " to collect your authorization code to connect your account and use {{provider}} models in Kilo.", "provider.connect.oauth.code.label": "{{method}} authorization code", "provider.connect.oauth.code.placeholder": "Authorization code", "provider.connect.oauth.code.required": "Authorization code is required", @@ -148,7 +148,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visit ", "provider.connect.oauth.auto.visit.link": "this link", "provider.connect.oauth.auto.visit.suffix": - " and enter the code below to connect your account and use {{provider}} models in OpenCode.", + " and enter the code below to connect your account and use {{provider}} models in Kilo.", "provider.connect.oauth.auto.confirmationCode": "Confirmation code", "provider.connect.toast.connected.title": "{{provider}} connected", "provider.connect.toast.connected.description": "{{provider}} models are now available to use.", @@ -304,7 +304,7 @@ export const dict = { "dialog.directory.empty": "No folders found", "dialog.server.title": "Servers", - "dialog.server.description": "Switch which OpenCode server this app connects to.", + "dialog.server.description": "Switch which Kilo server this app connects to.", "dialog.server.search.placeholder": "Search servers", "dialog.server.empty": "No servers yet", "dialog.server.add.title": "Add a server", @@ -430,7 +430,7 @@ export const dict = { "toast.session.listFailed.title": "Failed to load sessions for {{project}}", "toast.update.title": "Update available", - "toast.update.description": "A new version of OpenCode ({{version}}) is now available to install.", + "toast.update.description": "A new version of Kilo ({{version}}) is now available to install.", "toast.update.action.installRestart": "Install and restart", "toast.update.action.notYet": "Not yet", @@ -441,7 +441,7 @@ export const dict = { "error.page.action.checking": "Checking...", "error.page.action.checkUpdates": "Check for updates", "error.page.action.updateTo": "Update to {{version}}", - "error.page.report.prefix": "Please report this error to the OpenCode team", + "error.page.report.prefix": "Please report this error to the Kilo team", "error.page.report.discord": "on Discord", "error.page.version": "Version: {{version}}", @@ -460,7 +460,7 @@ export const dict = { "error.chain.didYouMean": "Did you mean: {{suggestions}}", "error.chain.modelNotFound": "Model not found: {{provider}}/{{model}}", "error.chain.checkConfig": "Check your config (opencode.json) provider/model names", - "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, OpenCode does not support MCP authentication yet.', + "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, Kilo does not support MCP authentication yet.', "error.chain.providerAuthFailed": "Provider authentication failed ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Failed to initialize provider "{{provider}}". Check credentials and configuration.', @@ -581,13 +581,13 @@ export const dict = { "sidebar.workspaces.enable": "Enable workspaces", "sidebar.workspaces.disable": "Disable workspaces", "sidebar.gettingStarted.title": "Getting started", - "sidebar.gettingStarted.line1": "OpenCode includes free models so you can start immediately.", + "sidebar.gettingStarted.line1": "Kilo includes free models so you can start immediately.", "sidebar.gettingStarted.line2": "Connect any provider to use models, inc. Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Recent sessions", "sidebar.project.viewAllSessions": "View all sessions", "sidebar.project.clearNotifications": "Clear notifications", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", @@ -595,7 +595,7 @@ export const dict = { "settings.tab.shortcuts": "Shortcuts", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.", + "settings.desktop.wsl.description": "Run the Kilo server inside WSL on Windows.", "settings.general.section.appearance": "Appearance", "settings.general.section.notifications": "System notifications", @@ -605,11 +605,11 @@ export const dict = { "settings.general.section.display": "Display", "settings.general.row.language.title": "Language", - "settings.general.row.language.description": "Change the display language for OpenCode", + "settings.general.row.language.description": "Change the display language for Kilo", "settings.general.row.appearance.title": "Appearance", - "settings.general.row.appearance.description": "Customise how OpenCode looks on your device", + "settings.general.row.appearance.description": "Customise how Kilo looks on your device", "settings.general.row.theme.title": "Theme", - "settings.general.row.theme.description": "Customise how OpenCode is themed.", + "settings.general.row.theme.description": "Customise how Kilo is themed.", "settings.general.row.font.title": "Font", "settings.general.row.font.description": "Customise the mono font used in code blocks", "settings.general.row.reasoningSummaries.title": "Show reasoning summaries", @@ -630,13 +630,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "Show What's New popups after updates", "settings.updates.row.startup.title": "Check for updates on startup", - "settings.updates.row.startup.description": "Automatically check for updates when OpenCode launches", + "settings.updates.row.startup.description": "Automatically check for updates when Kilo launches", "settings.updates.row.check.title": "Check for updates", "settings.updates.row.check.description": "Manually check for updates and install if available", "settings.updates.action.checkNow": "Check now", "settings.updates.action.checking": "Checking...", "settings.updates.toast.latest.title": "You're up to date", - "settings.updates.toast.latest.description": "You're running the latest version of OpenCode.", + "settings.updates.toast.latest.description": "You're running the latest version of Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 3566226d7bf..2bb3c17ef32 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -112,7 +112,7 @@ export const dict = { "dialog.model.manage": "Gestionar modelos", "dialog.model.manage.description": "Personalizar qué modelos aparecen en el selector de modelos.", - "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por OpenCode", + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por Kilo", "dialog.model.unpaid.addMore.title": "Añadir más modelos de proveedores populares", "dialog.provider.viewAll": "Ver más proveedores", @@ -125,7 +125,7 @@ export const dict = { "provider.connect.status.waiting": "Esperando autorización...", "provider.connect.status.failed": "Autorización fallida: {{error}}", "provider.connect.apiKey.description": - "Introduce tu clave API de {{provider}} para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + "Introduce tu clave API de {{provider}} para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.apiKey.label": "Clave API de {{provider}}", "provider.connect.apiKey.placeholder": "Clave API", "provider.connect.apiKey.required": "La clave API es obligatoria", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visita ", "provider.connect.oauth.code.visit.link": "este enlace", "provider.connect.oauth.code.visit.suffix": - " para obtener tu código de autorización para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + " para obtener tu código de autorización para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.oauth.code.label": "Código de autorización {{method}}", "provider.connect.oauth.code.placeholder": "Código de autorización", "provider.connect.oauth.code.required": "El código de autorización es obligatorio", @@ -147,7 +147,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visita ", "provider.connect.oauth.auto.visit.link": "este enlace", "provider.connect.oauth.auto.visit.suffix": - " e introduce el código a continuación para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + " e introduce el código a continuación para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.oauth.auto.confirmationCode": "Código de confirmación", "provider.connect.toast.connected.title": "{{provider}} conectado", "provider.connect.toast.connected.description": "Los modelos de {{provider}} ahora están disponibles para usar.", @@ -303,7 +303,7 @@ export const dict = { "dialog.directory.empty": "No se encontraron carpetas", "dialog.server.title": "Servidores", - "dialog.server.description": "Cambiar a qué servidor de OpenCode se conecta esta app.", + "dialog.server.description": "Cambiar a qué servidor de Kilo se conecta esta app.", "dialog.server.search.placeholder": "Buscar servidores", "dialog.server.empty": "No hay servidores aún", "dialog.server.add.title": "Añadir un servidor", @@ -431,7 +431,7 @@ export const dict = { "toast.session.listFailed.title": "Fallo al cargar sesiones para {{project}}", "toast.update.title": "Actualización disponible", - "toast.update.description": "Una nueva versión de OpenCode ({{version}}) está disponible para instalar.", + "toast.update.description": "Una nueva versión de Kilo ({{version}}) está disponible para instalar.", "toast.update.action.installRestart": "Instalar y reiniciar", "toast.update.action.notYet": "Todavía no", @@ -442,7 +442,7 @@ export const dict = { "error.page.action.checking": "Comprobando...", "error.page.action.checkUpdates": "Buscar actualizaciones", "error.page.action.updateTo": "Actualizar a {{version}}", - "error.page.report.prefix": "Por favor reporta este error al equipo de OpenCode", + "error.page.report.prefix": "Por favor reporta este error al equipo de Kilo", "error.page.report.discord": "en Discord", "error.page.version": "Versión: {{version}}", @@ -461,7 +461,7 @@ export const dict = { "error.chain.didYouMean": "¿Quisiste decir: {{suggestions}}", "error.chain.modelNotFound": "Modelo no encontrado: {{provider}}/{{model}}", "error.chain.checkConfig": "Comprueba los nombres de proveedor/modelo en tu configuración (opencode.json)", - "error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, OpenCode no soporta autenticación MCP todavía.', + "error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, Kilo no soporta autenticación MCP todavía.', "error.chain.providerAuthFailed": "Autenticación de proveedor fallida ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Fallo al inicializar proveedor "{{provider}}". Comprueba credenciales y configuración.', @@ -582,13 +582,13 @@ export const dict = { "sidebar.workspaces.enable": "Habilitar espacios de trabajo", "sidebar.workspaces.disable": "Deshabilitar espacios de trabajo", "sidebar.gettingStarted.title": "Empezando", - "sidebar.gettingStarted.line1": "OpenCode incluye modelos gratuitos para que puedas empezar inmediatamente.", + "sidebar.gettingStarted.line1": "Kilo incluye modelos gratuitos para que puedas empezar inmediatamente.", "sidebar.gettingStarted.line2": "Conecta cualquier proveedor para usar modelos, inc. Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sesiones recientes", "sidebar.project.viewAllSessions": "Ver todas las sesiones", "sidebar.project.clearNotifications": "Borrar notificaciones", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Escritorio", "settings.section.server": "Servidor", @@ -596,7 +596,7 @@ export const dict = { "settings.tab.shortcuts": "Atajos", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "Integración con WSL", - "settings.desktop.wsl.description": "Ejecutar el servidor OpenCode dentro de WSL en Windows.", + "settings.desktop.wsl.description": "Ejecutar el servidor Kilo dentro de WSL en Windows.", "settings.general.section.appearance": "Apariencia", "settings.general.section.notifications": "Notificaciones del sistema", @@ -606,11 +606,11 @@ export const dict = { "settings.general.section.display": "Pantalla", "settings.general.row.language.title": "Idioma", - "settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode", + "settings.general.row.language.description": "Cambiar el idioma de visualización para Kilo", "settings.general.row.appearance.title": "Apariencia", - "settings.general.row.appearance.description": "Personaliza cómo se ve OpenCode en tu dispositivo", + "settings.general.row.appearance.description": "Personaliza cómo se ve Kilo en tu dispositivo", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Personaliza el tema de OpenCode.", + "settings.general.row.theme.description": "Personaliza el tema de Kilo.", "settings.general.row.font.title": "Fuente", "settings.general.row.font.description": "Personaliza la fuente monoespaciada usada en bloques de código", @@ -630,13 +630,13 @@ export const dict = { 'Mostrar ventanas emergentes de "Novedades" después de las actualizaciones', "settings.updates.row.startup.title": "Buscar actualizaciones al iniciar", - "settings.updates.row.startup.description": "Buscar actualizaciones automáticamente cuando se inicia OpenCode", + "settings.updates.row.startup.description": "Buscar actualizaciones automáticamente cuando se inicia Kilo", "settings.updates.row.check.title": "Buscar actualizaciones", "settings.updates.row.check.description": "Buscar actualizaciones manualmente e instalarlas si hay alguna", "settings.updates.action.checkNow": "Buscar ahora", "settings.updates.action.checking": "Buscando...", "settings.updates.toast.latest.title": "Estás al día", - "settings.updates.toast.latest.description": "Estás usando la última versión de OpenCode.", + "settings.updates.toast.latest.description": "Estás usando la última versión de Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index c961f060e1f..5aac1d03d07 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -102,7 +102,7 @@ export const dict = { "dialog.model.empty": "Aucun résultat de modèle", "dialog.model.manage": "Gérer les modèles", "dialog.model.manage.description": "Personnalisez les modèles qui apparaissent dans le sélecteur.", - "dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par OpenCode", + "dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par Kilo", "dialog.model.unpaid.addMore.title": "Ajouter plus de modèles de fournisseurs populaires", "dialog.provider.viewAll": "Voir plus de fournisseurs", "provider.connect.title": "Connecter {{provider}}", @@ -113,7 +113,7 @@ export const dict = { "provider.connect.status.waiting": "En attente d'autorisation...", "provider.connect.status.failed": "Échec de l'autorisation : {{error}}", "provider.connect.apiKey.description": - "Entrez votre clé API {{provider}} pour connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + "Entrez votre clé API {{provider}} pour connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.apiKey.label": "Clé API {{provider}}", "provider.connect.apiKey.placeholder": "Clé API", "provider.connect.apiKey.required": "La clé API est requise", @@ -127,7 +127,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visitez ", "provider.connect.oauth.code.visit.link": "ce lien", "provider.connect.oauth.code.visit.suffix": - " pour récupérer votre code d'autorisation afin de connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + " pour récupérer votre code d'autorisation afin de connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.oauth.code.label": "Code d'autorisation {{method}}", "provider.connect.oauth.code.placeholder": "Code d'autorisation", "provider.connect.oauth.code.required": "Le code d'autorisation est requis", @@ -135,7 +135,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visitez ", "provider.connect.oauth.auto.visit.link": "ce lien", "provider.connect.oauth.auto.visit.suffix": - " et entrez le code ci-dessous pour connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + " et entrez le code ci-dessous pour connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.oauth.auto.confirmationCode": "Code de confirmation", "provider.connect.toast.connected.title": "{{provider}} connecté", "provider.connect.toast.connected.description": "Les modèles {{provider}} sont maintenant disponibles.", @@ -277,7 +277,7 @@ export const dict = { "dialog.directory.search.placeholder": "Rechercher des dossiers", "dialog.directory.empty": "Aucun dossier trouvé", "dialog.server.title": "Serveurs", - "dialog.server.description": "Changez le serveur OpenCode auquel cette application se connecte.", + "dialog.server.description": "Changez le serveur Kilo auquel cette application se connecte.", "dialog.server.search.placeholder": "Rechercher des serveurs", "dialog.server.empty": "Aucun serveur pour l'instant", "dialog.server.add.title": "Ajouter un serveur", @@ -390,7 +390,7 @@ export const dict = { "toast.session.listFailed.title": "Échec du chargement des sessions pour {{project}}", "toast.update.title": "Mise à jour disponible", "toast.update.description": - "Une nouvelle version d'OpenCode ({{version}}) est maintenant disponible pour installation.", + "Une nouvelle version d'Kilo ({{version}}) est maintenant disponible pour installation.", "toast.update.action.installRestart": "Installer et redémarrer", "toast.update.action.notYet": "Pas encore", "error.page.title": "Quelque chose s'est mal passé", @@ -400,7 +400,7 @@ export const dict = { "error.page.action.checking": "Vérification...", "error.page.action.checkUpdates": "Vérifier les mises à jour", "error.page.action.updateTo": "Mettre à jour vers {{version}}", - "error.page.report.prefix": "Veuillez signaler cette erreur à l'équipe OpenCode", + "error.page.report.prefix": "Veuillez signaler cette erreur à l'équipe Kilo", "error.page.report.discord": "sur Discord", "error.page.version": "Version : {{version}}", "error.dev.rootNotFound": @@ -418,7 +418,7 @@ export const dict = { "error.chain.modelNotFound": "Modèle introuvable : {{provider}}/{{model}}", "error.chain.checkConfig": "Vérifiez votre configuration (opencode.json) pour les noms de fournisseur/modèle", "error.chain.mcpFailed": - "Le serveur MCP \"{{name}}\" a échoué. Notez qu'OpenCode ne supporte pas encore l'authentification MCP.", + "Le serveur MCP \"{{name}}\" a échoué. Notez qu'Kilo ne supporte pas encore l'authentification MCP.", "error.chain.providerAuthFailed": "Échec de l'authentification du fournisseur ({{provider}}) : {{message}}", "error.chain.providerInitFailed": 'Échec de l\'initialisation du fournisseur "{{provider}}". Vérifiez les identifiants et la configuration.', @@ -525,20 +525,20 @@ export const dict = { "sidebar.workspaces.disable": "Désactiver les espaces de travail", "sidebar.gettingStarted.title": "Commencer", "sidebar.gettingStarted.line1": - "OpenCode inclut des modèles gratuits pour que vous puissiez commencer immédiatement.", + "Kilo inclut des modèles gratuits pour que vous puissiez commencer immédiatement.", "sidebar.gettingStarted.line2": "Connectez n'importe quel fournisseur pour utiliser des modèles, y compris Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sessions récentes", "sidebar.project.viewAllSessions": "Voir toutes les sessions", "sidebar.project.clearNotifications": "Effacer les notifications", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Bureau", "settings.section.server": "Serveur", "settings.tab.general": "Général", "settings.tab.shortcuts": "Raccourcis", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "Intégration WSL", - "settings.desktop.wsl.description": "Exécuter le serveur OpenCode dans WSL sur Windows.", + "settings.desktop.wsl.description": "Exécuter le serveur Kilo dans WSL sur Windows.", "settings.general.section.appearance": "Apparence", "settings.general.section.notifications": "Notifications système", "settings.general.section.updates": "Mises à jour", @@ -546,11 +546,11 @@ export const dict = { "settings.general.section.feed": "Flux", "settings.general.section.display": "Affichage", "settings.general.row.language.title": "Langue", - "settings.general.row.language.description": "Changer la langue d'affichage pour OpenCode", + "settings.general.row.language.description": "Changer la langue d'affichage pour Kilo", "settings.general.row.appearance.title": "Apparence", - "settings.general.row.appearance.description": "Personnaliser l'apparence d'OpenCode sur votre appareil", + "settings.general.row.appearance.description": "Personnaliser l'apparence d'Kilo sur votre appareil", "settings.general.row.theme.title": "Thème", - "settings.general.row.theme.description": "Personnaliser le thème d'OpenCode.", + "settings.general.row.theme.description": "Personnaliser le thème d'Kilo.", "settings.general.row.font.title": "Police", "settings.general.row.font.description": "Personnaliser la police mono utilisée dans les blocs de code", "settings.general.row.shellToolPartsExpanded.title": "Développer les parties de l'outil shell", @@ -566,13 +566,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "Notes de version", "settings.general.row.releaseNotes.description": 'Afficher des pop-ups "Quoi de neuf" après les mises à jour', "settings.updates.row.startup.title": "Vérifier les mises à jour au démarrage", - "settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'OpenCode", + "settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'Kilo", "settings.updates.row.check.title": "Vérifier les mises à jour", "settings.updates.row.check.description": "Vérifier manuellement les mises à jour et installer si disponible", "settings.updates.action.checkNow": "Vérifier maintenant", "settings.updates.action.checking": "Vérification...", "settings.updates.toast.latest.title": "Vous êtes à jour", - "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'OpenCode.", + "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index 7a62c9de271..c60fa87d8a2 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -102,7 +102,7 @@ export const dict = { "dialog.model.empty": "モデルが見つかりません", "dialog.model.manage": "モデルを管理", "dialog.model.manage.description": "モデルセレクターに表示するモデルをカスタマイズします。", - "dialog.model.unpaid.freeModels.title": "OpenCodeが提供する無料モデル", + "dialog.model.unpaid.freeModels.title": "Kiloが提供する無料モデル", "dialog.model.unpaid.addMore.title": "人気のプロバイダーからモデルを追加", "dialog.provider.viewAll": "さらにプロバイダーを表示", "provider.connect.title": "{{provider}}を接続", @@ -113,7 +113,7 @@ export const dict = { "provider.connect.status.waiting": "認証を待機中...", "provider.connect.status.failed": "認証に失敗しました: {{error}}", "provider.connect.apiKey.description": - "{{provider}}のAPIキーを入力してアカウントを接続し、OpenCodeで{{provider}}モデルを使用します。", + "{{provider}}のAPIキーを入力してアカウントを接続し、Kiloで{{provider}}モデルを使用します。", "provider.connect.apiKey.label": "{{provider}} APIキー", "provider.connect.apiKey.placeholder": "APIキー", "provider.connect.apiKey.required": "APIキーが必要です", @@ -126,7 +126,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": " ", "provider.connect.oauth.code.visit.link": "このリンク", "provider.connect.oauth.code.visit.suffix": - " にアクセスして認証コードを取得し、アカウントを接続してOpenCodeで{{provider}}モデルを使用してください。", + " にアクセスして認証コードを取得し、アカウントを接続してKiloで{{provider}}モデルを使用してください。", "provider.connect.oauth.code.label": "{{method}} 認証コード", "provider.connect.oauth.code.placeholder": "認証コード", "provider.connect.oauth.code.required": "認証コードが必要です", @@ -134,7 +134,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": " ", "provider.connect.oauth.auto.visit.link": "このリンク", "provider.connect.oauth.auto.visit.suffix": - " にアクセスし、以下のコードを入力してアカウントを接続し、OpenCodeで{{provider}}モデルを使用してください。", + " にアクセスし、以下のコードを入力してアカウントを接続し、Kiloで{{provider}}モデルを使用してください。", "provider.connect.oauth.auto.confirmationCode": "確認コード", "provider.connect.toast.connected.title": "{{provider}}が接続されました", "provider.connect.toast.connected.description": "{{provider}}モデルが使用可能になりました。", @@ -276,7 +276,7 @@ export const dict = { "dialog.directory.search.placeholder": "フォルダを検索", "dialog.directory.empty": "フォルダが見つかりません", "dialog.server.title": "サーバー", - "dialog.server.description": "このアプリが接続するOpenCodeサーバーを切り替えます。", + "dialog.server.description": "このアプリが接続するKiloサーバーを切り替えます。", "dialog.server.search.placeholder": "サーバーを検索", "dialog.server.empty": "サーバーはまだありません", "dialog.server.add.title": "サーバーを追加", @@ -385,7 +385,7 @@ export const dict = { "toast.session.unshare.failed.description": "セッションの共有解除中にエラーが発生しました", "toast.session.listFailed.title": "{{project}}のセッション読み込みに失敗しました", "toast.update.title": "アップデートが利用可能です", - "toast.update.description": "OpenCodeの新しいバージョン ({{version}}) がインストール可能です。", + "toast.update.description": "Kiloの新しいバージョン ({{version}}) がインストール可能です。", "toast.update.action.installRestart": "インストールして再起動", "toast.update.action.notYet": "今はしない", "error.page.title": "問題が発生しました", @@ -395,7 +395,7 @@ export const dict = { "error.page.action.checking": "確認中...", "error.page.action.checkUpdates": "アップデートを確認", "error.page.action.updateTo": "{{version}}にアップデート", - "error.page.report.prefix": "このエラーをOpenCodeチームに報告してください: ", + "error.page.report.prefix": "このエラーをKiloチームに報告してください: ", "error.page.report.discord": "Discord", "error.page.version": "バージョン: {{version}}", "error.dev.rootNotFound": @@ -411,7 +411,7 @@ export const dict = { "error.chain.didYouMean": "もしかして: {{suggestions}}", "error.chain.modelNotFound": "モデルが見つかりません: {{provider}}/{{model}}", "error.chain.checkConfig": "config (opencode.json) のプロバイダー/モデル名を確認してください", - "error.chain.mcpFailed": 'MCPサーバー "{{name}}" が失敗しました。注意: OpenCodeはまだMCP認証をサポートしていません。', + "error.chain.mcpFailed": 'MCPサーバー "{{name}}" が失敗しました。注意: KiloはまだMCP認証をサポートしていません。', "error.chain.providerAuthFailed": "プロバイダー認証に失敗しました ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'プロバイダー "{{provider}}" の初期化に失敗しました。認証情報と設定を確認してください。', @@ -516,19 +516,19 @@ export const dict = { "sidebar.workspaces.enable": "ワークスペースを有効化", "sidebar.workspaces.disable": "ワークスペースを無効化", "sidebar.gettingStarted.title": "はじめに", - "sidebar.gettingStarted.line1": "OpenCodeには無料モデルが含まれているため、すぐに開始できます。", + "sidebar.gettingStarted.line1": "Kiloには無料モデルが含まれているため、すぐに開始できます。", "sidebar.gettingStarted.line2": "プロバイダーを接続して、Claude、GPT、Geminiなどのモデルを使用できます。", "sidebar.project.recentSessions": "最近のセッション", "sidebar.project.viewAllSessions": "すべてのセッションを表示", "sidebar.project.clearNotifications": "通知をクリア", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "デスクトップ", "settings.section.server": "サーバー", "settings.tab.general": "一般", "settings.tab.shortcuts": "ショートカット", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL連携", - "settings.desktop.wsl.description": "WindowsのWSL環境でOpenCodeサーバーを実行します。", + "settings.desktop.wsl.description": "WindowsのWSL環境でKiloサーバーを実行します。", "settings.general.section.appearance": "外観", "settings.general.section.notifications": "システム通知", "settings.general.section.updates": "アップデート", @@ -536,11 +536,11 @@ export const dict = { "settings.general.section.feed": "フィード", "settings.general.section.display": "ディスプレイ", "settings.general.row.language.title": "言語", - "settings.general.row.language.description": "OpenCodeの表示言語を変更します", + "settings.general.row.language.description": "Kiloの表示言語を変更します", "settings.general.row.appearance.title": "外観", - "settings.general.row.appearance.description": "デバイスでのOpenCodeの表示をカスタマイズします", + "settings.general.row.appearance.description": "デバイスでのKiloの表示をカスタマイズします", "settings.general.row.theme.title": "テーマ", - "settings.general.row.theme.description": "OpenCodeのテーマをカスタマイズします。", + "settings.general.row.theme.description": "Kiloのテーマをカスタマイズします。", "settings.general.row.font.title": "フォント", "settings.general.row.font.description": "コードブロックで使用する等幅フォントをカスタマイズします", "settings.general.row.shellToolPartsExpanded.title": "shell ツールパーツを展開", @@ -556,13 +556,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "リリースノート", "settings.general.row.releaseNotes.description": "アップデート後に「新機能」ポップアップを表示", "settings.updates.row.startup.title": "起動時にアップデートを確認", - "settings.updates.row.startup.description": "OpenCode の起動時に自動でアップデートを確認します", + "settings.updates.row.startup.description": "Kilo の起動時に自動でアップデートを確認します", "settings.updates.row.check.title": "アップデートを確認", "settings.updates.row.check.description": "手動でアップデートを確認し、利用可能ならインストールします", "settings.updates.action.checkNow": "今すぐ確認", "settings.updates.action.checking": "確認中...", "settings.updates.toast.latest.title": "最新です", - "settings.updates.toast.latest.description": "OpenCode は最新バージョンです。", + "settings.updates.toast.latest.description": "Kilo は最新バージョンです。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 8967c71cff7..839e627d00f 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -106,7 +106,7 @@ export const dict = { "dialog.model.empty": "모델 결과 없음", "dialog.model.manage": "모델 관리", "dialog.model.manage.description": "모델 선택기에 표시할 모델 사용자 지정", - "dialog.model.unpaid.freeModels.title": "OpenCode에서 제공하는 무료 모델", + "dialog.model.unpaid.freeModels.title": "Kilo에서 제공하는 무료 모델", "dialog.model.unpaid.addMore.title": "인기 공급자의 모델 추가", "dialog.provider.viewAll": "더 많은 공급자 보기", "provider.connect.title": "{{provider}} 연결", @@ -117,7 +117,7 @@ export const dict = { "provider.connect.status.waiting": "인증 대기 중...", "provider.connect.status.failed": "인증 실패: {{error}}", "provider.connect.apiKey.description": - "{{provider}} API 키를 입력하여 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "{{provider}} API 키를 입력하여 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.apiKey.label": "{{provider}} API 키", "provider.connect.apiKey.placeholder": "API 키", "provider.connect.apiKey.required": "API 키가 필요합니다", @@ -130,7 +130,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "다음 ", "provider.connect.oauth.code.visit.link": "이 링크", "provider.connect.oauth.code.visit.suffix": - "를 방문하여 인증 코드를 받아 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "를 방문하여 인증 코드를 받아 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.oauth.code.label": "{{method}} 인증 코드", "provider.connect.oauth.code.placeholder": "인증 코드", "provider.connect.oauth.code.required": "인증 코드가 필요합니다", @@ -138,7 +138,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "다음 ", "provider.connect.oauth.auto.visit.link": "이 링크", "provider.connect.oauth.auto.visit.suffix": - "를 방문하고 아래 코드를 입력하여 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "를 방문하고 아래 코드를 입력하여 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.oauth.auto.confirmationCode": "확인 코드", "provider.connect.toast.connected.title": "{{provider}} 연결됨", "provider.connect.toast.connected.description": "이제 {{provider}} 모델을 사용할 수 있습니다.", @@ -280,7 +280,7 @@ export const dict = { "dialog.directory.search.placeholder": "폴더 검색", "dialog.directory.empty": "폴더 없음", "dialog.server.title": "서버", - "dialog.server.description": "이 앱이 연결할 OpenCode 서버를 전환합니다.", + "dialog.server.description": "이 앱이 연결할 Kilo 서버를 전환합니다.", "dialog.server.search.placeholder": "서버 검색", "dialog.server.empty": "서버 없음", "dialog.server.add.title": "서버 추가", @@ -388,7 +388,7 @@ export const dict = { "toast.session.unshare.failed.description": "세션 공유를 해제하는 동안 오류가 발생했습니다", "toast.session.listFailed.title": "{{project}}에 대한 세션을 로드하지 못했습니다", "toast.update.title": "업데이트 가능", - "toast.update.description": "OpenCode의 새 버전({{version}})을 설치할 수 있습니다.", + "toast.update.description": "Kilo의 새 버전({{version}})을 설치할 수 있습니다.", "toast.update.action.installRestart": "설치 및 다시 시작", "toast.update.action.notYet": "나중에", "error.page.title": "문제가 발생했습니다", @@ -398,7 +398,7 @@ export const dict = { "error.page.action.checking": "확인 중...", "error.page.action.checkUpdates": "업데이트 확인", "error.page.action.updateTo": "{{version}} 버전으로 업데이트", - "error.page.report.prefix": "이 오류를 OpenCode 팀에 제보해 주세요: ", + "error.page.report.prefix": "이 오류를 Kilo 팀에 제보해 주세요: ", "error.page.report.discord": "Discord", "error.page.version": "버전: {{version}}", "error.dev.rootNotFound": @@ -414,7 +414,7 @@ export const dict = { "error.chain.didYouMean": "혹시 {{suggestions}}을(를) 의미하셨나요?", "error.chain.modelNotFound": "모델을 찾을 수 없음: {{provider}}/{{model}}", "error.chain.checkConfig": "구성(opencode.json)의 공급자/모델 이름을 확인하세요", - "error.chain.mcpFailed": 'MCP 서버 "{{name}}" 실패. 참고: OpenCode는 아직 MCP 인증을 지원하지 않습니다.', + "error.chain.mcpFailed": 'MCP 서버 "{{name}}" 실패. 참고: Kilo는 아직 MCP 인증을 지원하지 않습니다.', "error.chain.providerAuthFailed": "공급자 인증 실패 ({{provider}}): {{message}}", "error.chain.providerInitFailed": '공급자 "{{provider}}" 초기화 실패. 자격 증명과 구성을 확인하세요.', "error.chain.configJsonInvalid": "{{path}}의 구성 파일이 유효한 JSON(C)가 아닙니다", @@ -517,19 +517,19 @@ export const dict = { "sidebar.workspaces.enable": "작업 공간 활성화", "sidebar.workspaces.disable": "작업 공간 비활성화", "sidebar.gettingStarted.title": "시작하기", - "sidebar.gettingStarted.line1": "OpenCode에는 무료 모델이 포함되어 있어 즉시 시작할 수 있습니다.", + "sidebar.gettingStarted.line1": "Kilo에는 무료 모델이 포함되어 있어 즉시 시작할 수 있습니다.", "sidebar.gettingStarted.line2": "Claude, GPT, Gemini 등을 포함한 모델을 사용하려면 공급자를 연결하세요.", "sidebar.project.recentSessions": "최근 세션", "sidebar.project.viewAllSessions": "모든 세션 보기", "sidebar.project.clearNotifications": "알림 지우기", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "데스크톱", "settings.section.server": "서버", "settings.tab.general": "일반", "settings.tab.shortcuts": "단축키", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL 통합", - "settings.desktop.wsl.description": "Windows의 WSL 내부에서 OpenCode 서버를 실행합니다.", + "settings.desktop.wsl.description": "Windows의 WSL 내부에서 Kilo 서버를 실행합니다.", "settings.general.section.appearance": "모양", "settings.general.section.notifications": "시스템 알림", "settings.general.section.updates": "업데이트", @@ -537,11 +537,11 @@ export const dict = { "settings.general.section.feed": "피드", "settings.general.section.display": "디스플레이", "settings.general.row.language.title": "언어", - "settings.general.row.language.description": "OpenCode 표시 언어 변경", + "settings.general.row.language.description": "Kilo 표시 언어 변경", "settings.general.row.appearance.title": "모양", - "settings.general.row.appearance.description": "기기에서 OpenCode가 보이는 방식 사용자 지정", + "settings.general.row.appearance.description": "기기에서 Kilo가 보이는 방식 사용자 지정", "settings.general.row.theme.title": "테마", - "settings.general.row.theme.description": "OpenCode 테마 사용자 지정", + "settings.general.row.theme.description": "Kilo 테마 사용자 지정", "settings.general.row.font.title": "글꼴", "settings.general.row.font.description": "코드 블록에 사용되는 고정폭 글꼴 사용자 지정", "settings.general.row.shellToolPartsExpanded.title": "shell 도구 파트 펼치기", @@ -557,13 +557,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "릴리스 노트", "settings.general.row.releaseNotes.description": "업데이트 후 '새 소식' 팝업 표시", "settings.updates.row.startup.title": "시작 시 업데이트 확인", - "settings.updates.row.startup.description": "OpenCode를 실행할 때 업데이트를 자동으로 확인합니다", + "settings.updates.row.startup.description": "Kilo를 실행할 때 업데이트를 자동으로 확인합니다", "settings.updates.row.check.title": "업데이트 확인", "settings.updates.row.check.description": "업데이트를 수동으로 확인하고, 사용 가능하면 설치합니다", "settings.updates.action.checkNow": "지금 확인", "settings.updates.action.checking": "확인 중...", "settings.updates.toast.latest.title": "최신 상태입니다", - "settings.updates.toast.latest.description": "현재 최신 버전의 OpenCode를 사용 중입니다.", + "settings.updates.toast.latest.description": "현재 최신 버전의 Kilo를 사용 중입니다.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 3fbe75716d0..3b65059b352 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -115,7 +115,7 @@ export const dict = { "dialog.model.manage": "Administrer modeller", "dialog.model.manage.description": "Tilpass hvilke modeller som vises i modellvelgeren.", - "dialog.model.unpaid.freeModels.title": "Gratis modeller levert av OpenCode", + "dialog.model.unpaid.freeModels.title": "Gratis modeller levert av Kilo", "dialog.model.unpaid.addMore.title": "Legg til flere modeller fra populære leverandører", "dialog.provider.viewAll": "Vis flere leverandører", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.status.waiting": "Venter på autorisering...", "provider.connect.status.failed": "Autorisering mislyktes: {{error}}", "provider.connect.apiKey.description": - "Skriv inn din {{provider}} API-nøkkel for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + "Skriv inn din {{provider}} API-nøkkel for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.apiKey.label": "{{provider}} API-nøkkel", "provider.connect.apiKey.placeholder": "API-nøkkel", "provider.connect.apiKey.required": "API-nøkkel er påkrevd", @@ -142,7 +142,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besøk ", "provider.connect.oauth.code.visit.link": "denne lenken", "provider.connect.oauth.code.visit.suffix": - " for å hente autorisasjonskoden din for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + " for å hente autorisasjonskoden din for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.oauth.code.label": "{{method}} autorisasjonskode", "provider.connect.oauth.code.placeholder": "Autorisasjonskode", "provider.connect.oauth.code.required": "Autorisasjonskode er påkrevd", @@ -150,7 +150,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besøk ", "provider.connect.oauth.auto.visit.link": "denne lenken", "provider.connect.oauth.auto.visit.suffix": - " og skriv inn koden nedenfor for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + " og skriv inn koden nedenfor for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.oauth.auto.confirmationCode": "Bekreftelseskode", "provider.connect.toast.connected.title": "{{provider}} tilkoblet", "provider.connect.toast.connected.description": "{{provider}}-modeller er nå tilgjengelige.", @@ -306,7 +306,7 @@ export const dict = { "dialog.directory.empty": "Ingen mapper funnet", "dialog.server.title": "Servere", - "dialog.server.description": "Bytt hvilken OpenCode-server denne appen kobler til.", + "dialog.server.description": "Bytt hvilken Kilo-server denne appen kobler til.", "dialog.server.search.placeholder": "Søk etter servere", "dialog.server.empty": "Ingen servere ennå", "dialog.server.add.title": "Legg til en server", @@ -432,7 +432,7 @@ export const dict = { "toast.session.listFailed.title": "Kunne ikke laste sesjoner for {{project}}", "toast.update.title": "Oppdatering tilgjengelig", - "toast.update.description": "En ny versjon av OpenCode ({{version}}) er nå tilgjengelig for installasjon.", + "toast.update.description": "En ny versjon av Kilo ({{version}}) er nå tilgjengelig for installasjon.", "toast.update.action.installRestart": "Installer og start på nytt", "toast.update.action.notYet": "Ikke nå", @@ -443,7 +443,7 @@ export const dict = { "error.page.action.checking": "Sjekker...", "error.page.action.checkUpdates": "Se etter oppdateringer", "error.page.action.updateTo": "Oppdater til {{version}}", - "error.page.report.prefix": "Vennligst rapporter denne feilen til OpenCode-teamet", + "error.page.report.prefix": "Vennligst rapporter denne feilen til Kilo-teamet", "error.page.report.discord": "på Discord", "error.page.version": "Versjon: {{version}}", @@ -462,7 +462,7 @@ export const dict = { "error.chain.didYouMean": "Mente du: {{suggestions}}", "error.chain.modelNotFound": "Modell ikke funnet: {{provider}}/{{model}}", "error.chain.checkConfig": "Sjekk leverandør-/modellnavnene i konfigurasjonen din (opencode.json)", - "error.chain.mcpFailed": 'MCP-server "{{name}}" mislyktes. Merk at OpenCode ikke støtter MCP-autentisering ennå.', + "error.chain.mcpFailed": 'MCP-server "{{name}}" mislyktes. Merk at Kilo ikke støtter MCP-autentisering ennå.', "error.chain.providerAuthFailed": "Leverandørautentisering mislyktes ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Kunne ikke initialisere leverandør "{{provider}}". Sjekk legitimasjon og konfigurasjon.', @@ -582,13 +582,13 @@ export const dict = { "sidebar.workspaces.enable": "Aktiver arbeidsområder", "sidebar.workspaces.disable": "Deaktiver arbeidsområder", "sidebar.gettingStarted.title": "Kom i gang", - "sidebar.gettingStarted.line1": "OpenCode inkluderer gratis modeller så du kan starte umiddelbart.", + "sidebar.gettingStarted.line1": "Kilo inkluderer gratis modeller så du kan starte umiddelbart.", "sidebar.gettingStarted.line2": "Koble til en leverandør for å bruke modeller, inkl. Claude, GPT, Gemini osv.", "sidebar.project.recentSessions": "Nylige sesjoner", "sidebar.project.viewAllSessions": "Vis alle sesjoner", "sidebar.project.clearNotifications": "Fjern varsler", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Skrivebord", "settings.section.server": "Server", @@ -596,7 +596,7 @@ export const dict = { "settings.tab.shortcuts": "Snarveier", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL-integrasjon", - "settings.desktop.wsl.description": "Kjør OpenCode-serveren i WSL på Windows.", + "settings.desktop.wsl.description": "Kjør Kilo-serveren i WSL på Windows.", "settings.general.section.appearance": "Utseende", "settings.general.section.notifications": "Systemvarsler", @@ -606,11 +606,11 @@ export const dict = { "settings.general.section.display": "Skjerm", "settings.general.row.language.title": "Språk", - "settings.general.row.language.description": "Endre visningsspråket for OpenCode", + "settings.general.row.language.description": "Endre visningsspråket for Kilo", "settings.general.row.appearance.title": "Utseende", - "settings.general.row.appearance.description": "Tilpass hvordan OpenCode ser ut på enheten din", + "settings.general.row.appearance.description": "Tilpass hvordan Kilo ser ut på enheten din", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Tilpass hvordan OpenCode er tematisert.", + "settings.general.row.theme.description": "Tilpass hvordan Kilo er tematisert.", "settings.general.row.font.title": "Skrift", "settings.general.row.font.description": "Tilpass mono-skriften som brukes i kodeblokker", @@ -628,13 +628,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Vis "Hva er nytt"-vinduer etter oppdateringer', "settings.updates.row.startup.title": "Se etter oppdateringer ved oppstart", - "settings.updates.row.startup.description": "Se automatisk etter oppdateringer når OpenCode starter", + "settings.updates.row.startup.description": "Se automatisk etter oppdateringer når Kilo starter", "settings.updates.row.check.title": "Se etter oppdateringer", "settings.updates.row.check.description": "Se etter oppdateringer manuelt og installer hvis tilgjengelig", "settings.updates.action.checkNow": "Sjekk nå", "settings.updates.action.checking": "Sjekker...", "settings.updates.toast.latest.title": "Du er oppdatert", - "settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av OpenCode.", + "settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index d8ae150d7cb..2207d5fb1b3 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -102,7 +102,7 @@ export const dict = { "dialog.model.empty": "Brak wyników modelu", "dialog.model.manage": "Zarządzaj modelami", "dialog.model.manage.description": "Dostosuj, które modele pojawiają się w wyborze modelu.", - "dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez OpenCode", + "dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez Kilo", "dialog.model.unpaid.addMore.title": "Dodaj więcej modeli od popularnych dostawców", "dialog.provider.viewAll": "Zobacz więcej dostawców", "provider.connect.title": "Połącz {{provider}}", @@ -113,7 +113,7 @@ export const dict = { "provider.connect.status.waiting": "Oczekiwanie na autoryzację...", "provider.connect.status.failed": "Autoryzacja nie powiodła się: {{error}}", "provider.connect.apiKey.description": - "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w OpenCode.", + "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.apiKey.label": "Klucz API {{provider}}", "provider.connect.apiKey.placeholder": "Klucz API", "provider.connect.apiKey.required": "Klucz API jest wymagany", @@ -127,7 +127,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Odwiedź ", "provider.connect.oauth.code.visit.link": "ten link", "provider.connect.oauth.code.visit.suffix": - ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w OpenCode.", + ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.oauth.code.label": "Kod autoryzacyjny {{method}}", "provider.connect.oauth.code.placeholder": "Kod autoryzacyjny", "provider.connect.oauth.code.required": "Kod autoryzacyjny jest wymagany", @@ -135,7 +135,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Odwiedź ", "provider.connect.oauth.auto.visit.link": "ten link", "provider.connect.oauth.auto.visit.suffix": - " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w OpenCode.", + " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.oauth.auto.confirmationCode": "Kod potwierdzający", "provider.connect.toast.connected.title": "Połączono {{provider}}", "provider.connect.toast.connected.description": "Modele {{provider}} są teraz dostępne do użycia.", @@ -278,7 +278,7 @@ export const dict = { "dialog.directory.search.placeholder": "Szukaj folderów", "dialog.directory.empty": "Nie znaleziono folderów", "dialog.server.title": "Serwery", - "dialog.server.description": "Przełącz serwer OpenCode, z którym łączy się ta aplikacja.", + "dialog.server.description": "Przełącz serwer Kilo, z którym łączy się ta aplikacja.", "dialog.server.search.placeholder": "Szukaj serwerów", "dialog.server.empty": "Brak serwerów", "dialog.server.add.title": "Dodaj serwer", @@ -386,7 +386,7 @@ export const dict = { "toast.session.unshare.failed.description": "Wystąpił błąd podczas zatrzymywania udostępniania sesji", "toast.session.listFailed.title": "Nie udało się załadować sesji dla {{project}}", "toast.update.title": "Dostępna aktualizacja", - "toast.update.description": "Nowa wersja OpenCode ({{version}}) jest teraz dostępna do instalacji.", + "toast.update.description": "Nowa wersja Kilo ({{version}}) jest teraz dostępna do instalacji.", "toast.update.action.installRestart": "Zainstaluj i zrestartuj", "toast.update.action.notYet": "Jeszcze nie", "error.page.title": "Coś poszło nie tak", @@ -396,7 +396,7 @@ export const dict = { "error.page.action.checking": "Sprawdzanie...", "error.page.action.checkUpdates": "Sprawdź aktualizacje", "error.page.action.updateTo": "Zaktualizuj do {{version}}", - "error.page.report.prefix": "Proszę zgłosić ten błąd do zespołu OpenCode", + "error.page.report.prefix": "Proszę zgłosić ten błąd do zespołu Kilo", "error.page.report.discord": "na Discordzie", "error.page.version": "Wersja: {{version}}", "error.dev.rootNotFound": @@ -412,7 +412,7 @@ export const dict = { "error.chain.didYouMean": "Czy miałeś na myśli: {{suggestions}}", "error.chain.modelNotFound": "Model nie znaleziony: {{provider}}/{{model}}", "error.chain.checkConfig": "Sprawdź swoją konfigurację (opencode.json) nazwy dostawców/modeli", - "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, OpenCode does not support MCP authentication yet.', + "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, Kilo does not support MCP authentication yet.', "error.chain.providerAuthFailed": "Uwierzytelnianie dostawcy nie powiodło się ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Nie udało się zainicjować dostawcy "{{provider}}". Sprawdź poświadczenia i konfigurację.', @@ -517,19 +517,19 @@ export const dict = { "sidebar.workspaces.enable": "Włącz przestrzenie robocze", "sidebar.workspaces.disable": "Wyłącz przestrzenie robocze", "sidebar.gettingStarted.title": "Pierwsze kroki", - "sidebar.gettingStarted.line1": "OpenCode zawiera darmowe modele, więc możesz zacząć od razu.", + "sidebar.gettingStarted.line1": "Kilo zawiera darmowe modele, więc możesz zacząć od razu.", "sidebar.gettingStarted.line2": "Połącz dowolnego dostawcę, aby używać modeli, w tym Claude, GPT, Gemini itp.", "sidebar.project.recentSessions": "Ostatnie sesje", "sidebar.project.viewAllSessions": "Zobacz wszystkie sesje", "sidebar.project.clearNotifications": "Wyczyść powiadomienia", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Pulpit", "settings.section.server": "Serwer", "settings.tab.general": "Ogólne", "settings.tab.shortcuts": "Skróty", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.", + "settings.desktop.wsl.description": "Run the Kilo server inside WSL on Windows.", "settings.general.section.appearance": "Wygląd", "settings.general.section.notifications": "Powiadomienia systemowe", "settings.general.section.updates": "Aktualizacje", @@ -537,11 +537,11 @@ export const dict = { "settings.general.section.feed": "Kanał", "settings.general.section.display": "Ekran", "settings.general.row.language.title": "Język", - "settings.general.row.language.description": "Zmień język wyświetlania dla OpenCode", + "settings.general.row.language.description": "Zmień język wyświetlania dla Kilo", "settings.general.row.appearance.title": "Wygląd", - "settings.general.row.appearance.description": "Dostosuj wygląd OpenCode na swoim urządzeniu", + "settings.general.row.appearance.description": "Dostosuj wygląd Kilo na swoim urządzeniu", "settings.general.row.theme.title": "Motyw", - "settings.general.row.theme.description": "Dostosuj motyw OpenCode.", + "settings.general.row.theme.description": "Dostosuj motyw Kilo.", "settings.general.row.font.title": "Czcionka", "settings.general.row.font.description": "Dostosuj czcionkę mono używaną w blokach kodu", "settings.general.row.shellToolPartsExpanded.title": "Rozwijaj elementy narzędzia shell", @@ -557,13 +557,13 @@ export const dict = { "settings.general.row.releaseNotes.title": "Informacje o wydaniu", "settings.general.row.releaseNotes.description": 'Pokazuj wyskakujące okna "Co nowego" po aktualizacjach', "settings.updates.row.startup.title": "Sprawdzaj aktualizacje przy uruchomieniu", - "settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania OpenCode", + "settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania Kilo", "settings.updates.row.check.title": "Sprawdź aktualizacje", "settings.updates.row.check.description": "Ręcznie sprawdź aktualizacje i zainstaluj, jeśli są dostępne", "settings.updates.action.checkNow": "Sprawdź teraz", "settings.updates.action.checking": "Sprawdzanie...", "settings.updates.toast.latest.title": "Masz najnowszą wersję", - "settings.updates.toast.latest.description": "Korzystasz z najnowszej wersji OpenCode.", + "settings.updates.toast.latest.description": "Korzystasz z najnowszej wersji Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index a7d328924a4..25f63fd3b78 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -112,7 +112,7 @@ export const dict = { "dialog.model.manage": "Управление моделями", "dialog.model.manage.description": "Настройте какие модели появляются в выборе модели", - "dialog.model.unpaid.freeModels.title": "Бесплатные модели от OpenCode", + "dialog.model.unpaid.freeModels.title": "Бесплатные модели от Kilo", "dialog.model.unpaid.addMore.title": "Добавьте больше моделей от популярных провайдеров", "dialog.provider.viewAll": "Показать больше провайдеров", @@ -125,7 +125,7 @@ export const dict = { "provider.connect.status.waiting": "Ожидание авторизации...", "provider.connect.status.failed": "Ошибка авторизации: {{error}}", "provider.connect.apiKey.description": - "Введите ваш API ключ {{provider}} для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + "Введите ваш API ключ {{provider}} для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.apiKey.label": "{{provider}} API ключ", "provider.connect.apiKey.placeholder": "API ключ", "provider.connect.apiKey.required": "API ключ обязателен", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Посетите ", "provider.connect.oauth.code.visit.link": "эту ссылку", "provider.connect.oauth.code.visit.suffix": - " чтобы получить код авторизации для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + " чтобы получить код авторизации для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.oauth.code.label": "{{method}} код авторизации", "provider.connect.oauth.code.placeholder": "Код авторизации", "provider.connect.oauth.code.required": "Код авторизации обязателен", @@ -147,7 +147,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Посетите ", "provider.connect.oauth.auto.visit.link": "эту ссылку", "provider.connect.oauth.auto.visit.suffix": - " и введите код ниже для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + " и введите код ниже для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.oauth.auto.confirmationCode": "Код подтверждения", "provider.connect.toast.connected.title": "{{provider}} подключён", "provider.connect.toast.connected.description": "Модели {{provider}} теперь доступны.", @@ -303,7 +303,7 @@ export const dict = { "dialog.directory.empty": "Папки не найдены", "dialog.server.title": "Серверы", - "dialog.server.description": "Переключите сервер OpenCode к которому подключается приложение.", + "dialog.server.description": "Переключите сервер Kilo к которому подключается приложение.", "dialog.server.search.placeholder": "Поиск серверов", "dialog.server.empty": "Серверов пока нет", "dialog.server.add.title": "Добавить сервер", @@ -430,7 +430,7 @@ export const dict = { "toast.session.listFailed.title": "Не удалось загрузить сессии для {{project}}", "toast.update.title": "Доступно обновление", - "toast.update.description": "Новая версия OpenCode ({{version}}) доступна для установки.", + "toast.update.description": "Новая версия Kilo ({{version}}) доступна для установки.", "toast.update.action.installRestart": "Установить и перезапустить", "toast.update.action.notYet": "Пока нет", @@ -441,7 +441,7 @@ export const dict = { "error.page.action.checking": "Проверка...", "error.page.action.checkUpdates": "Проверить обновления", "error.page.action.updateTo": "Обновить до {{version}}", - "error.page.report.prefix": "Пожалуйста, сообщите об этой ошибке команде OpenCode", + "error.page.report.prefix": "Пожалуйста, сообщите об этой ошибке команде Kilo", "error.page.report.discord": "в Discord", "error.page.version": "Версия: {{version}}", @@ -461,7 +461,7 @@ export const dict = { "error.chain.modelNotFound": "Модель не найдена: {{provider}}/{{model}}", "error.chain.checkConfig": "Проверьте названия провайдера/модели в конфиге (opencode.json)", "error.chain.mcpFailed": - 'MCP сервер "{{name}}" завершился с ошибкой. Обратите внимание, что OpenCode пока не поддерживает MCP авторизацию.', + 'MCP сервер "{{name}}" завершился с ошибкой. Обратите внимание, что Kilo пока не поддерживает MCP авторизацию.', "error.chain.providerAuthFailed": "Ошибка аутентификации провайдера ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Не удалось инициализировать провайдера "{{provider}}". Проверьте учётные данные и конфигурацию.', @@ -580,21 +580,21 @@ export const dict = { "sidebar.workspaces.enable": "Включить рабочие пространства", "sidebar.workspaces.disable": "Отключить рабочие пространства", "sidebar.gettingStarted.title": "Начало работы", - "sidebar.gettingStarted.line1": "OpenCode включает бесплатные модели, чтобы вы могли начать сразу.", + "sidebar.gettingStarted.line1": "Kilo включает бесплатные модели, чтобы вы могли начать сразу.", "sidebar.gettingStarted.line2": "Подключите любого провайдера для использования моделей, включая Claude, GPT, Gemini и др.", "sidebar.project.recentSessions": "Недавние сессии", "sidebar.project.viewAllSessions": "Посмотреть все сессии", "sidebar.project.clearNotifications": "Очистить уведомления", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Приложение", "settings.section.server": "Сервер", "settings.tab.general": "Основные", "settings.tab.shortcuts": "Горячие клавиши", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "Интеграция с WSL", - "settings.desktop.wsl.description": "Запускать сервер OpenCode внутри WSL на Windows.", + "settings.desktop.wsl.description": "Запускать сервер Kilo внутри WSL на Windows.", "settings.general.section.appearance": "Внешний вид", "settings.general.section.notifications": "Системные уведомления", @@ -604,11 +604,11 @@ export const dict = { "settings.general.section.display": "Дисплей", "settings.general.row.language.title": "Язык", - "settings.general.row.language.description": "Изменить язык отображения OpenCode", + "settings.general.row.language.description": "Изменить язык отображения Kilo", "settings.general.row.appearance.title": "Внешний вид", - "settings.general.row.appearance.description": "Настройте как OpenCode выглядит на вашем устройстве", + "settings.general.row.appearance.description": "Настройте как Kilo выглядит на вашем устройстве", "settings.general.row.theme.title": "Тема", - "settings.general.row.theme.description": "Настройте оформление OpenCode.", + "settings.general.row.theme.description": "Настройте оформление Kilo.", "settings.general.row.font.title": "Шрифт", "settings.general.row.font.description": "Настройте моноширинный шрифт для блоков кода", @@ -627,13 +627,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Показывать всплывающие окна "Что нового" после обновлений', "settings.updates.row.startup.title": "Проверять обновления при запуске", - "settings.updates.row.startup.description": "Автоматически проверять обновления при запуске OpenCode", + "settings.updates.row.startup.description": "Автоматически проверять обновления при запуске Kilo", "settings.updates.row.check.title": "Проверить обновления", "settings.updates.row.check.description": "Проверить обновления вручную и установить, если доступны", "settings.updates.action.checkNow": "Проверить сейчас", "settings.updates.action.checking": "Проверка...", "settings.updates.toast.latest.title": "У вас последняя версия", - "settings.updates.toast.latest.description": "Вы используете последнюю версию OpenCode.", + "settings.updates.toast.latest.description": "Вы используете последнюю версию Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 1e9773bf021..22ca0889b1f 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -112,7 +112,7 @@ export const dict = { "dialog.model.manage": "จัดการโมเดล", "dialog.model.manage.description": "ปรับแต่งโมเดลที่จะปรากฏในตัวเลือกโมเดล", - "dialog.model.unpaid.freeModels.title": "โมเดลฟรีที่จัดหาให้โดย OpenCode", + "dialog.model.unpaid.freeModels.title": "โมเดลฟรีที่จัดหาให้โดย Kilo", "dialog.model.unpaid.addMore.title": "เพิ่มโมเดลเพิ่มเติมจากผู้ให้บริการยอดนิยม", "dialog.provider.viewAll": "แสดงผู้ให้บริการเพิ่มเติม", @@ -125,7 +125,7 @@ export const dict = { "provider.connect.status.waiting": "รอการอนุญาต...", "provider.connect.status.failed": "การอนุญาตล้มเหลว: {{error}}", "provider.connect.apiKey.description": - "ป้อนคีย์ API ของ {{provider}} เพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + "ป้อนคีย์ API ของ {{provider}} เพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.apiKey.label": "คีย์ API ของ {{provider}}", "provider.connect.apiKey.placeholder": "คีย์ API", "provider.connect.apiKey.required": "ต้องใช้คีย์ API", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "เยี่ยมชม ", "provider.connect.oauth.code.visit.link": "ลิงก์นี้", "provider.connect.oauth.code.visit.suffix": - " เพื่อรวบรวมรหัสการอนุญาตของคุณเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + " เพื่อรวบรวมรหัสการอนุญาตของคุณเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.oauth.code.label": "รหัสการอนุญาต {{method}}", "provider.connect.oauth.code.placeholder": "รหัสการอนุญาต", "provider.connect.oauth.code.required": "ต้องใช้รหัสการอนุญาต", @@ -147,7 +147,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "เยี่ยมชม ", "provider.connect.oauth.auto.visit.link": "ลิงก์นี้", "provider.connect.oauth.auto.visit.suffix": - " และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + " และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.oauth.auto.confirmationCode": "รหัสยืนยัน", "provider.connect.toast.connected.title": "{{provider}} ที่เชื่อมต่อแล้ว", "provider.connect.toast.connected.description": "โมเดล {{provider}} พร้อมใช้งานแล้ว", @@ -303,7 +303,7 @@ export const dict = { "dialog.directory.empty": "ไม่พบโฟลเดอร์", "dialog.server.title": "เซิร์ฟเวอร์", - "dialog.server.description": "สลับเซิร์ฟเวอร์ OpenCode ที่แอปนี้เชื่อมต่อด้วย", + "dialog.server.description": "สลับเซิร์ฟเวอร์ Kilo ที่แอปนี้เชื่อมต่อด้วย", "dialog.server.search.placeholder": "ค้นหาเซิร์ฟเวอร์", "dialog.server.empty": "ยังไม่มีเซิร์ฟเวอร์", "dialog.server.add.title": "เพิ่มเซิร์ฟเวอร์", @@ -429,7 +429,7 @@ export const dict = { "toast.session.listFailed.title": "ไม่สามารถโหลดเซสชันสำหรับ {{project}}", "toast.update.title": "มีการอัปเดต", - "toast.update.description": "เวอร์ชันใหม่ของ OpenCode ({{version}}) พร้อมใช้งานสำหรับติดตั้ง", + "toast.update.description": "เวอร์ชันใหม่ของ Kilo ({{version}}) พร้อมใช้งานสำหรับติดตั้ง", "toast.update.action.installRestart": "ติดตั้งและรีสตาร์ท", "toast.update.action.notYet": "ยังไม่", @@ -440,7 +440,7 @@ export const dict = { "error.page.action.checking": "กำลังตรวจสอบ...", "error.page.action.checkUpdates": "ตรวจสอบการอัปเดต", "error.page.action.updateTo": "อัปเดตเป็น {{version}}", - "error.page.report.prefix": "โปรดรายงานข้อผิดพลาดนี้ให้ทีม OpenCode", + "error.page.report.prefix": "โปรดรายงานข้อผิดพลาดนี้ให้ทีม Kilo", "error.page.report.discord": "บน Discord", "error.page.version": "เวอร์ชัน: {{version}}", @@ -458,7 +458,7 @@ export const dict = { "error.chain.didYouMean": "คุณหมายถึง: {{suggestions}}", "error.chain.modelNotFound": "ไม่พบโมเดล: {{provider}}/{{model}}", "error.chain.checkConfig": "ตรวจสอบการกำหนดค่าของคุณ (opencode.json) ชื่อผู้ให้บริการ/โมเดล", - "error.chain.mcpFailed": 'เซิร์ฟเวอร์ MCP "{{name}}" ล้มเหลว โปรดทราบว่า OpenCode ยังไม่รองรับการตรวจสอบสิทธิ์ MCP', + "error.chain.mcpFailed": 'เซิร์ฟเวอร์ MCP "{{name}}" ล้มเหลว โปรดทราบว่า Kilo ยังไม่รองรับการตรวจสอบสิทธิ์ MCP', "error.chain.providerAuthFailed": "การตรวจสอบสิทธิ์ผู้ให้บริการล้มเหลว ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'ไม่สามารถเริ่มต้นผู้ให้บริการ "{{provider}}" ตรวจสอบข้อมูลรับรองและการกำหนดค่า', "error.chain.configJsonInvalid": "ไฟล์กำหนดค่าที่ {{path}} ไม่ใช่ JSON(C) ที่ถูกต้อง", @@ -574,13 +574,13 @@ export const dict = { "sidebar.workspaces.enable": "เปิดใช้งานพื้นที่ทำงาน", "sidebar.workspaces.disable": "ปิดใช้งานพื้นที่ทำงาน", "sidebar.gettingStarted.title": "เริ่มต้นใช้งาน", - "sidebar.gettingStarted.line1": "OpenCode รวมถึงโมเดลฟรีเพื่อให้คุณเริ่มต้นได้ทันที", + "sidebar.gettingStarted.line1": "Kilo รวมถึงโมเดลฟรีเพื่อให้คุณเริ่มต้นได้ทันที", "sidebar.gettingStarted.line2": "เชื่อมต่อผู้ให้บริการใด ๆ เพื่อใช้โมเดล รวมถึง Claude, GPT, Gemini ฯลฯ", "sidebar.project.recentSessions": "เซสชันล่าสุด", "sidebar.project.viewAllSessions": "ดูเซสชันทั้งหมด", "sidebar.project.clearNotifications": "ล้างการแจ้งเตือน", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "เดสก์ท็อป", "settings.section.server": "เซิร์ฟเวอร์", @@ -588,7 +588,7 @@ export const dict = { "settings.tab.shortcuts": "ทางลัด", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "การรวม WSL", - "settings.desktop.wsl.description": "เรียกใช้เซิร์ฟเวอร์ OpenCode ภายใน WSL บน Windows", + "settings.desktop.wsl.description": "เรียกใช้เซิร์ฟเวอร์ Kilo ภายใน WSL บน Windows", "settings.general.section.appearance": "รูปลักษณ์", "settings.general.section.notifications": "การแจ้งเตือนระบบ", @@ -598,11 +598,11 @@ export const dict = { "settings.general.section.display": "การแสดงผล", "settings.general.row.language.title": "ภาษา", - "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ OpenCode", + "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ Kilo", "settings.general.row.appearance.title": "รูปลักษณ์", - "settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ OpenCode มีลักษณะบนอุปกรณ์ของคุณ", + "settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ Kilo มีลักษณะบนอุปกรณ์ของคุณ", "settings.general.row.theme.title": "ธีม", - "settings.general.row.theme.description": "ปรับแต่งวิธีการที่ OpenCode มีธีม", + "settings.general.row.theme.description": "ปรับแต่งวิธีการที่ Kilo มีธีม", "settings.general.row.font.title": "ฟอนต์", "settings.general.row.font.description": "ปรับแต่งฟอนต์โมโนที่ใช้ในบล็อกโค้ด", @@ -619,13 +619,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "แสดงป๊อปอัพ What's New หลังจากอัปเดต", "settings.updates.row.startup.title": "ตรวจสอบการอัปเดตเมื่อเริ่มต้น", - "settings.updates.row.startup.description": "ตรวจสอบการอัปเดตโดยอัตโนมัติเมื่อ OpenCode เปิดใช้งาน", + "settings.updates.row.startup.description": "ตรวจสอบการอัปเดตโดยอัตโนมัติเมื่อ Kilo เปิดใช้งาน", "settings.updates.row.check.title": "ตรวจสอบการอัปเดต", "settings.updates.row.check.description": "ตรวจสอบการอัปเดตด้วยตนเองและติดตั้งหากมี", "settings.updates.action.checkNow": "ตรวจสอบทันที", "settings.updates.action.checking": "กำลังตรวจสอบ...", "settings.updates.toast.latest.title": "คุณเป็นเวอร์ชันล่าสุดแล้ว", - "settings.updates.toast.latest.description": "คุณกำลังใช้งาน OpenCode เวอร์ชันล่าสุด", + "settings.updates.toast.latest.description": "คุณกำลังใช้งาน Kilo เวอร์ชันล่าสุด", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 62c7bb9ff23..8ed8818421d 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -138,7 +138,7 @@ export const dict = { "dialog.model.empty": "未找到模型", "dialog.model.manage": "管理模型", "dialog.model.manage.description": "自定义模型选择器中显示的模型。", - "dialog.model.unpaid.freeModels.title": "OpenCode 提供的免费模型", + "dialog.model.unpaid.freeModels.title": "Kilo 提供的免费模型", "dialog.model.unpaid.addMore.title": "从热门提供商添加更多模型", "dialog.provider.viewAll": "查看更多提供商", @@ -151,7 +151,7 @@ export const dict = { "provider.connect.status.waiting": "等待授权...", "provider.connect.status.failed": "授权失败:{{error}}", "provider.connect.apiKey.description": - "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。", + "输入你的 {{provider}} API 密钥以连接帐户,并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.apiKey.label": "{{provider}} API 密钥", "provider.connect.apiKey.placeholder": "API 密钥", "provider.connect.apiKey.required": "API 密钥为必填项", @@ -162,14 +162,14 @@ export const dict = { "provider.connect.opencodeZen.visit.suffix": " 获取你的 API 密钥。", "provider.connect.oauth.code.visit.prefix": "访问 ", "provider.connect.oauth.code.visit.link": "此链接", - "provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的帐户并在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的帐户并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.code.label": "{{method}} 授权码", "provider.connect.oauth.code.placeholder": "授权码", "provider.connect.oauth.code.required": "授权码为必填项", "provider.connect.oauth.code.invalid": "授权码无效", "provider.connect.oauth.auto.visit.prefix": "访问 ", "provider.connect.oauth.auto.visit.link": "此链接", - "provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的帐户并在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的帐户并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.auto.confirmationCode": "确认码", "provider.connect.toast.connected.title": "{{provider}} 已连接", "provider.connect.toast.connected.description": "现在可以使用 {{provider}} 模型了。", @@ -323,7 +323,7 @@ export const dict = { "dialog.directory.empty": "未找到文件夹", "dialog.server.title": "服务器", - "dialog.server.description": "切换此应用连接的 OpenCode 服务器。", + "dialog.server.description": "切换此应用连接的 Kilo 服务器。", "dialog.server.search.placeholder": "搜索服务器", "dialog.server.empty": "暂无服务器", "dialog.server.add.title": "添加服务器", @@ -434,7 +434,7 @@ export const dict = { "toast.session.unshare.failed.description": "取消分享会话时发生错误", "toast.session.listFailed.title": "无法加载 {{project}} 的会话", "toast.update.title": "有可用更新", - "toast.update.description": "OpenCode 有新版本 ({{version}}) 可安装。", + "toast.update.description": "Kilo 有新版本 ({{version}}) 可安装。", "toast.update.action.installRestart": "安装并重启", "toast.update.action.notYet": "稍后", @@ -445,7 +445,7 @@ export const dict = { "error.page.action.checking": "检查中...", "error.page.action.checkUpdates": "检查更新", "error.page.action.updateTo": "更新到 {{version}}", - "error.page.report.prefix": "请将此错误报告给 OpenCode 团队", + "error.page.report.prefix": "请将此错误报告给 Kilo 团队", "error.page.report.discord": "在 Discord 上", "error.page.version": "版本:{{version}}", "error.dev.rootNotFound": "未找到根元素。你是不是忘了把它添加到 index.html?或者 id 属性拼写错了?", @@ -462,7 +462,7 @@ export const dict = { "error.chain.didYouMean": "你是不是想输入:{{suggestions}}", "error.chain.modelNotFound": "未找到模型:{{provider}}/{{model}}", "error.chain.checkConfig": "请检查你的配置 (opencode.json) 中的 provider/model 名称", - "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: OpenCode 暂不支持 MCP 认证。', + "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: Kilo 暂不支持 MCP 认证。', "error.chain.providerAuthFailed": "提供商认证失败({{provider}}):{{message}}", "error.chain.providerInitFailed": '无法初始化提供商 "{{provider}}"。请检查凭据和配置。', "error.chain.configJsonInvalid": "配置文件 {{path}} 不是有效的 JSON(C)", @@ -573,13 +573,13 @@ export const dict = { "sidebar.workspaces.enable": "启用工作区", "sidebar.workspaces.disable": "禁用工作区", "sidebar.gettingStarted.title": "入门", - "sidebar.gettingStarted.line1": "OpenCode 提供免费模型,你可以立即开始使用。", + "sidebar.gettingStarted.line1": "Kilo 提供免费模型,你可以立即开始使用。", "sidebar.gettingStarted.line2": "连接任意提供商即可使用更多模型,如 Claude、GPT、Gemini 等。", "sidebar.project.recentSessions": "最近会话", "sidebar.project.viewAllSessions": "查看全部会话", "sidebar.project.clearNotifications": "清除通知", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "桌面", "settings.section.server": "服务器", @@ -589,7 +589,7 @@ export const dict = { "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL 集成", - "settings.desktop.wsl.description": "在 Windows 的 WSL 环境中运行 OpenCode 服务器。", + "settings.desktop.wsl.description": "在 Windows 的 WSL 环境中运行 Kilo 服务器。", "settings.general.section.appearance": "外观", "settings.general.section.notifications": "系统通知", @@ -598,11 +598,11 @@ export const dict = { "settings.general.section.feed": "动态", "settings.general.section.display": "显示", "settings.general.row.language.title": "语言", - "settings.general.row.language.description": "更改 OpenCode 的显示语言", + "settings.general.row.language.description": "更改 Kilo 的显示语言", "settings.general.row.appearance.title": "外观", - "settings.general.row.appearance.description": "自定义 OpenCode 在你的设备上的外观", + "settings.general.row.appearance.description": "自定义 Kilo 在你的设备上的外观", "settings.general.row.theme.title": "主题", - "settings.general.row.theme.description": "自定义 OpenCode 的主题。", + "settings.general.row.theme.description": "自定义 Kilo 的主题。", "settings.general.row.font.title": "字体", "settings.general.row.font.description": "自定义代码块使用的等宽字体", "settings.general.row.shellToolPartsExpanded.title": "展开 shell 工具部分", @@ -616,13 +616,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "更新后显示“新功能”弹窗", "settings.updates.row.startup.title": "启动时检查更新", - "settings.updates.row.startup.description": "在 OpenCode 启动时自动检查更新", + "settings.updates.row.startup.description": "在 Kilo 启动时自动检查更新", "settings.updates.row.check.title": "检查更新", "settings.updates.row.check.description": "手动检查更新并在有更新时安装", "settings.updates.action.checkNow": "立即检查", "settings.updates.action.checking": "正在检查...", "settings.updates.toast.latest.title": "已是最新版本", - "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", + "settings.updates.toast.latest.description": "你正在使用最新版本的 Kilo。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index cb8f068f63b..fa5dee31bd6 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -116,7 +116,7 @@ export const dict = { "dialog.model.manage": "管理模型", "dialog.model.manage.description": "自訂模型選擇器中顯示的模型。", - "dialog.model.unpaid.freeModels.title": "OpenCode 提供的免費模型", + "dialog.model.unpaid.freeModels.title": "Kilo 提供的免費模型", "dialog.model.unpaid.addMore.title": "從熱門提供者新增更多模型", "dialog.provider.viewAll": "查看更多提供者", @@ -129,7 +129,7 @@ export const dict = { "provider.connect.status.waiting": "等待授權...", "provider.connect.status.failed": "授權失敗: {{error}}", "provider.connect.apiKey.description": - "輸入你的 {{provider}} API 金鑰以連線帳戶,並在 OpenCode 中使用 {{provider}} 模型。", + "輸入你的 {{provider}} API 金鑰以連線帳戶,並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.apiKey.label": "{{provider}} API 金鑰", "provider.connect.apiKey.placeholder": "API 金鑰", "provider.connect.apiKey.required": "API 金鑰為必填", @@ -140,7 +140,7 @@ export const dict = { "provider.connect.opencodeZen.visit.suffix": " 取得你的 API 金鑰。", "provider.connect.oauth.code.visit.prefix": "造訪 ", "provider.connect.oauth.code.visit.link": "此連結", - "provider.connect.oauth.code.visit.suffix": " 取得授權碼,以連線你的帳戶並在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.code.visit.suffix": " 取得授權碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.code.label": "{{method}} 授權碼", "provider.connect.oauth.code.placeholder": "授權碼", "provider.connect.oauth.code.required": "授權碼為必填", @@ -148,7 +148,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "造訪 ", "provider.connect.oauth.auto.visit.link": "此連結", "provider.connect.oauth.auto.visit.suffix": - " 並輸入以下程式碼,以連線你的帳戶並在 OpenCode 中使用 {{provider}} 模型。", + " 並輸入以下程式碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.auto.confirmationCode": "確認碼", "provider.connect.toast.connected.title": "{{provider}} 已連線", "provider.connect.toast.connected.description": "現在可以使用 {{provider}} 模型了。", @@ -303,7 +303,7 @@ export const dict = { "dialog.directory.empty": "找不到資料夾", "dialog.server.title": "伺服器", - "dialog.server.description": "切換此應用程式連線的 OpenCode 伺服器。", + "dialog.server.description": "切換此應用程式連線的 Kilo 伺服器。", "dialog.server.search.placeholder": "搜尋伺服器", "dialog.server.empty": "暫無伺服器", "dialog.server.add.title": "新增伺服器", @@ -427,7 +427,7 @@ export const dict = { "toast.session.listFailed.title": "無法載入 {{project}} 的工作階段", "toast.update.title": "有可用更新", - "toast.update.description": "OpenCode 有新版本 ({{version}}) 可安裝。", + "toast.update.description": "Kilo 有新版本 ({{version}}) 可安裝。", "toast.update.action.installRestart": "安裝並重新啟動", "toast.update.action.notYet": "稍後", @@ -438,7 +438,7 @@ export const dict = { "error.page.action.checking": "檢查中...", "error.page.action.checkUpdates": "檢查更新", "error.page.action.updateTo": "更新到 {{version}}", - "error.page.report.prefix": "請將此錯誤回報給 OpenCode 團隊", + "error.page.report.prefix": "請將此錯誤回報給 Kilo 團隊", "error.page.report.discord": "在 Discord 上", "error.page.version": "版本: {{version}}", @@ -456,7 +456,7 @@ export const dict = { "error.chain.didYouMean": "你是不是想輸入: {{suggestions}}", "error.chain.modelNotFound": "找不到模型: {{provider}}/{{model}}", "error.chain.checkConfig": "請檢查你的設定 (opencode.json) 中的 provider/model 名稱", - "error.chain.mcpFailed": 'MCP 伺服器 "{{name}}" 啟動失敗。注意: OpenCode 暫不支援 MCP 認證。', + "error.chain.mcpFailed": 'MCP 伺服器 "{{name}}" 啟動失敗。注意: Kilo 暫不支援 MCP 認證。', "error.chain.providerAuthFailed": "提供者認證失敗 ({{provider}}): {{message}}", "error.chain.providerInitFailed": '無法初始化提供者 "{{provider}}"。請檢查憑證和設定。', "error.chain.configJsonInvalid": "設定檔 {{path}} 不是有效的 JSON(C)", @@ -570,20 +570,20 @@ export const dict = { "sidebar.workspaces.enable": "啟用工作區", "sidebar.workspaces.disable": "停用工作區", "sidebar.gettingStarted.title": "開始使用", - "sidebar.gettingStarted.line1": "OpenCode 提供免費模型,你可以立即開始使用。", + "sidebar.gettingStarted.line1": "Kilo 提供免費模型,你可以立即開始使用。", "sidebar.gettingStarted.line2": "連線任意提供者即可使用更多模型,如 Claude、GPT、Gemini 等。", "sidebar.project.recentSessions": "最近工作階段", "sidebar.project.viewAllSessions": "查看全部工作階段", "sidebar.project.clearNotifications": "清除通知", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "桌面", "settings.section.server": "伺服器", "settings.tab.general": "一般", "settings.tab.shortcuts": "快速鍵", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.", + "settings.desktop.wsl.description": "Run the Kilo server inside WSL on Windows.", "settings.general.section.appearance": "外觀", "settings.general.section.notifications": "系統通知", @@ -593,11 +593,11 @@ export const dict = { "settings.general.section.display": "顯示", "settings.general.row.language.title": "語言", - "settings.general.row.language.description": "變更 OpenCode 的顯示語言", + "settings.general.row.language.description": "變更 Kilo 的顯示語言", "settings.general.row.appearance.title": "外觀", - "settings.general.row.appearance.description": "自訂 OpenCode 在你的裝置上的外觀", + "settings.general.row.appearance.description": "自訂 Kilo 在你的裝置上的外觀", "settings.general.row.theme.title": "主題", - "settings.general.row.theme.description": "自訂 OpenCode 的主題。", + "settings.general.row.theme.description": "自訂 Kilo 的主題。", "settings.general.row.font.title": "字型", "settings.general.row.font.description": "自訂程式碼區塊使用的等寬字型", @@ -613,13 +613,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "更新後顯示「新功能」彈出視窗", "settings.updates.row.startup.title": "啟動時檢查更新", - "settings.updates.row.startup.description": "在 OpenCode 啟動時自動檢查更新", + "settings.updates.row.startup.description": "在 Kilo 啟動時自動檢查更新", "settings.updates.row.check.title": "檢查更新", "settings.updates.row.check.description": "手動檢查更新並在有更新時安裝", "settings.updates.action.checkNow": "立即檢查", "settings.updates.action.checking": "檢查中...", "settings.updates.toast.latest.title": "已是最新版本", - "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", + "settings.updates.toast.latest.description": "你正在使用最新版本的 Kilo。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/pages/error.tsx b/packages/app/src/pages/error.tsx index a30d86d1809..48a3ee8473b 100644 --- a/packages/app/src/pages/error.tsx +++ b/packages/app/src/pages/error.tsx @@ -299,7 +299,7 @@ export const ErrorPage: Component = (props) => {

@@ -2041,7 +2041,7 @@ export default function Layout(props: ParentProps) { settingsKeybind={() => command.keybind("settings.open")} onOpenSettings={openSettings} helpLabel={() => language.t("sidebar.help")} - onOpenHelp={() => platform.openLink("https://opencode.ai/desktop-feedback")} + onOpenHelp={() => platform.openLink("https://kilo.ai/desktop-feedback")} renderPanel={() => } /> diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts index 6a1e7c0123d..be8679c7bf1 100644 --- a/packages/app/src/pages/layout/helpers.ts +++ b/packages/app/src/pages/layout/helpers.ts @@ -1,5 +1,5 @@ import { getFilename } from "@opencode-ai/util/path" -import { type Session } from "@opencode-ai/sdk/v2/client" +import { type Session } from "@kilocode/sdk/v2/client" export const workspaceKey = (directory: string) => { const drive = directory.match(/^([A-Za-z]:)[\\/]+$/) diff --git a/packages/app/src/pages/layout/sidebar-items.tsx b/packages/app/src/pages/layout/sidebar-items.tsx index 194f75f815b..0a461ca79f8 100644 --- a/packages/app/src/pages/layout/sidebar-items.tsx +++ b/packages/app/src/pages/layout/sidebar-items.tsx @@ -13,11 +13,11 @@ import { MessageNav } from "@opencode-ai/ui/message-nav" import { Spinner } from "@opencode-ai/ui/spinner" import { Tooltip } from "@opencode-ai/ui/tooltip" import { getFilename } from "@opencode-ai/util/path" -import { type Message, type Session, type TextPart, type UserMessage } from "@opencode-ai/sdk/v2/client" +import { type Message, type Session, type TextPart, type UserMessage } from "@kilocode/sdk/v2/client" import { For, Match, Show, Switch, createMemo, onCleanup, type Accessor, type JSX } from "solid-js" import { agentColor } from "@/utils/agent" -const OPENCODE_PROJECT_ID = "4b0ea68d7af9a6031a7ffda7ad66e0cb83315750" +const KILO_PROJECT_ID = "4b0ea68d7af9a6031a7ffda7ad66e0cb83315750" export const ProjectIcon = (props: { project: LocalProject; class?: string; notify?: boolean }): JSX.Element => { const notification = useNotification() @@ -33,7 +33,7 @@ export const ProjectIcon = (props: { project: LocalProject; class?: string; noti diff --git a/packages/app/src/pages/session/composer/session-composer-state.ts b/packages/app/src/pages/session/composer/session-composer-state.ts index ed65867ef00..18f1c4553c5 100644 --- a/packages/app/src/pages/session/composer/session-composer-state.ts +++ b/packages/app/src/pages/session/composer/session-composer-state.ts @@ -1,6 +1,6 @@ import { createEffect, createMemo, on, onCleanup } from "solid-js" import { createStore } from "solid-js/store" -import type { PermissionRequest, QuestionRequest, Todo } from "@opencode-ai/sdk/v2" +import type { PermissionRequest, QuestionRequest, Todo } from "@kilocode/sdk/v2" import { useParams } from "@solidjs/router" import { showToast } from "@opencode-ai/ui/toast" import { useGlobalSync } from "@/context/global-sync" diff --git a/packages/app/src/pages/session/composer/session-permission-dock.tsx b/packages/app/src/pages/session/composer/session-permission-dock.tsx index 06ff4f4aa71..25a6de40d8a 100644 --- a/packages/app/src/pages/session/composer/session-permission-dock.tsx +++ b/packages/app/src/pages/session/composer/session-permission-dock.tsx @@ -1,5 +1,5 @@ import { For, Show } from "solid-js" -import type { PermissionRequest } from "@opencode-ai/sdk/v2" +import type { PermissionRequest } from "@kilocode/sdk/v2" import { Button } from "@opencode-ai/ui/button" import { DockPrompt } from "@opencode-ai/ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx index fd2ced3dc81..6013c80d636 100644 --- a/packages/app/src/pages/session/composer/session-question-dock.tsx +++ b/packages/app/src/pages/session/composer/session-question-dock.tsx @@ -4,7 +4,7 @@ import { Button } from "@opencode-ai/ui/button" import { DockPrompt } from "@opencode-ai/ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" import { showToast } from "@opencode-ai/ui/toast" -import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" +import type { QuestionAnswer, QuestionRequest } from "@kilocode/sdk/v2" import { useLanguage } from "@/context/language" import { useSDK } from "@/context/sdk" diff --git a/packages/app/src/pages/session/composer/session-request-tree.ts b/packages/app/src/pages/session/composer/session-request-tree.ts index f9673e25494..1c69c7c36b0 100644 --- a/packages/app/src/pages/session/composer/session-request-tree.ts +++ b/packages/app/src/pages/session/composer/session-request-tree.ts @@ -1,4 +1,4 @@ -import type { PermissionRequest, QuestionRequest, Session } from "@opencode-ai/sdk/v2/client" +import type { PermissionRequest, QuestionRequest, Session } from "@kilocode/sdk/v2/client" function sessionTreeRequest(session: Session[], request: Record, sessionID?: string) { if (!sessionID) return diff --git a/packages/app/src/pages/session/composer/session-todo-dock.tsx b/packages/app/src/pages/session/composer/session-todo-dock.tsx index 27998276023..56dca1f9674 100644 --- a/packages/app/src/pages/session/composer/session-todo-dock.tsx +++ b/packages/app/src/pages/session/composer/session-todo-dock.tsx @@ -1,4 +1,4 @@ -import type { Todo } from "@opencode-ai/sdk/v2" +import type { Todo } from "@kilocode/sdk/v2" import { Checkbox } from "@opencode-ai/ui/checkbox" import { DockTray } from "@opencode-ai/ui/dock-surface" import { IconButton } from "@opencode-ai/ui/icon-button" diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index b8410903550..2c583b1fd47 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -9,7 +9,7 @@ import { Dialog } from "@opencode-ai/ui/dialog" import { InlineInput } from "@opencode-ai/ui/inline-input" import { SessionTurn } from "@opencode-ai/ui/session-turn" import { ScrollView } from "@opencode-ai/ui/scroll-view" -import type { UserMessage } from "@opencode-ai/sdk/v2" +import type { UserMessage } from "@kilocode/sdk/v2" import { showToast } from "@opencode-ai/ui/toast" import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture" import { SessionContextUsage } from "@/components/session-context-usage" diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx index 9349e993768..96030fb5320 100644 --- a/packages/app/src/pages/session/review-tab.tsx +++ b/packages/app/src/pages/session/review-tab.tsx @@ -1,6 +1,6 @@ import { createEffect, on, onCleanup, type JSX } from "solid-js" import { createStore } from "solid-js/store" -import type { FileDiff } from "@opencode-ai/sdk/v2" +import type { FileDiff } from "@kilocode/sdk/v2" import { SessionReview } from "@opencode-ai/ui/session-review" import type { SelectedLineRange } from "@/context/file" import { useSDK } from "@/context/sdk" diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index 461351878b6..00385548357 100644 --- a/packages/app/src/pages/session/use-session-commands.tsx +++ b/packages/app/src/pages/session/use-session-commands.tsx @@ -18,7 +18,7 @@ import { DialogFork } from "@/components/dialog-fork" import { showToast } from "@opencode-ai/ui/toast" import { findLast } from "@opencode-ai/util/array" import { extractPromptFromParts } from "@/utils/prompt" -import { UserMessage } from "@opencode-ai/sdk/v2" +import { UserMessage } from "@kilocode/sdk/v2" import { canAddSelectionContext } from "@/pages/session/session-command-helpers" export type SessionCommandContext = { diff --git a/packages/app/src/pages/session/use-session-hash-scroll.ts b/packages/app/src/pages/session/use-session-hash-scroll.ts index b704e460bc0..1ce93d1d4d5 100644 --- a/packages/app/src/pages/session/use-session-hash-scroll.ts +++ b/packages/app/src/pages/session/use-session-hash-scroll.ts @@ -1,5 +1,5 @@ import { createEffect, createMemo, on, onCleanup } from "solid-js" -import { UserMessage } from "@opencode-ai/sdk/v2" +import { UserMessage } from "@kilocode/sdk/v2" export const messageIdFromHash = (hash: string) => { const value = hash.startsWith("#") ? hash.slice(1) : hash diff --git a/packages/app/src/utils/prompt.ts b/packages/app/src/utils/prompt.ts index 35aec0071aa..2736d0e51a1 100644 --- a/packages/app/src/utils/prompt.ts +++ b/packages/app/src/utils/prompt.ts @@ -1,4 +1,4 @@ -import type { AgentPart as MessageAgentPart, FilePart, Part, TextPart } from "@opencode-ai/sdk/v2" +import type { AgentPart as MessageAgentPart, FilePart, Part, TextPart } from "@kilocode/sdk/v2" import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt" type Inline = diff --git a/packages/app/src/utils/server.ts b/packages/app/src/utils/server.ts index 17f4a3adcec..08bfdaa4249 100644 --- a/packages/app/src/utils/server.ts +++ b/packages/app/src/utils/server.ts @@ -1,4 +1,4 @@ -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import type { ServerConnection } from "@/context/server" export function createSdkForServer({ diff --git a/packages/console/app/package.json b/packages/console/app/package.json index ad5813ced67..443bcd84ea5 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.2.15", + "version": "7.0.30", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 8f65e0c4578..b14e5d125b5 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.2.15", + "version": "7.0.30", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 6cdf752432c..aadb9c1ceff 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.2.15", + "version": "7.0.30", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 09344f7fa23..26e481b9886 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.2.15", + "version": "7.0.30", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/console/resource/package.json b/packages/console/resource/package.json index 6e874331d24..4665a1f35f8 100644 --- a/packages/console/resource/package.json +++ b/packages/console/resource/package.json @@ -18,5 +18,6 @@ "@tsconfig/node22": "22.0.2", "@types/node": "catalog:", "cloudflare": "5.2.0" - } + }, + "version": "7.0.30" } diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 4fe999e700a..c572ae131f1 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.2.15", + "version": "7.0.30", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/desktop/src-tauri/Cargo.toml b/packages/desktop/src-tauri/Cargo.toml index b228c7b6162..94a0ba33dfb 100644 --- a/packages/desktop/src-tauri/Cargo.toml +++ b/packages/desktop/src-tauri/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "opencode-desktop" +name = "kilo-desktop" version = "0.0.0" description = "The open source AI coding agent" authors = ["Anomaly Innovations"] @@ -11,7 +11,7 @@ edition = "2024" # The `_lib` suffix may seem redundant but it is necessary # to make the lib name unique and wouldn't conflict with the bin name. # This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 -name = "opencode_lib" +name = "kilo_lib" crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] diff --git a/packages/desktop/src-tauri/src/cli.rs b/packages/desktop/src-tauri/src/cli.rs index af1a45cf3a3..ed78185e730 100644 --- a/packages/desktop/src-tauri/src/cli.rs +++ b/packages/desktop/src-tauri/src/cli.rs @@ -37,7 +37,7 @@ impl CommandWrapper for WinCreationFlags { } } -const CLI_INSTALL_DIR: &str = ".opencode/bin"; +const CLI_INSTALL_DIR: &str = ".kilo/bin"; const CLI_BINARY_NAME: &str = "opencode"; #[derive(serde::Deserialize, Debug)] @@ -111,7 +111,7 @@ pub fn get_sidecar_path(app: &tauri::AppHandle) -> std::path::PathBuf { .expect("Failed to get current binary") .parent() .expect("Failed to get parent dir") - .join("opencode-cli") + .join("kilo-cli") } fn is_cli_installed() -> bool { @@ -244,14 +244,14 @@ pub fn spawn_command( let mut envs = vec![ ( - "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY".to_string(), + "KILO_EXPERIMENTAL_ICON_DISCOVERY".to_string(), "true".to_string(), ), ( - "OPENCODE_EXPERIMENTAL_FILEWATCHER".to_string(), + "KILO_EXPERIMENTAL_FILEWATCHER".to_string(), "true".to_string(), ), - ("OPENCODE_CLIENT".to_string(), "desktop".to_string()), + ("KILO_CLIENT".to_string(), "desktop".to_string()), ( "XDG_STATE_HOME".to_string(), state_dir.to_string_lossy().to_string(), @@ -272,23 +272,23 @@ pub fn spawn_command( "BIN=\"$HOME/.opencode/bin/opencode\"".to_string(), "if [ ! -x \"$BIN\" ]; then".to_string(), format!( - " curl -fsSL https://opencode.ai/install | bash -s -- --version {} --no-modify-path", + " curl -fsSL https://kilo.ai/install | bash -s -- --version {} --no-modify-path", shell_escape(&version) ), "fi".to_string(), ]; let mut env_prefix = vec![ - "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY=true".to_string(), - "OPENCODE_EXPERIMENTAL_FILEWATCHER=true".to_string(), - "OPENCODE_CLIENT=desktop".to_string(), + "KILO_EXPERIMENTAL_ICON_DISCOVERY=true".to_string(), + "KILO_EXPERIMENTAL_FILEWATCHER=true".to_string(), + "KILO_CLIENT=desktop".to_string(), "XDG_STATE_HOME=\"$HOME/.local/state\"".to_string(), ]; env_prefix.extend( envs.iter() - .filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY") - .filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_FILEWATCHER") - .filter(|(key, _)| key != "OPENCODE_CLIENT") + .filter(|(key, _)| key != "KILO_EXPERIMENTAL_ICON_DISCOVERY") + .filter(|(key, _)| key != "KILO_EXPERIMENTAL_FILEWATCHER") + .filter(|(key, _)| key != "KILO_CLIENT") .filter(|(key, _)| key != "XDG_STATE_HOME") .map(|(key, value)| format!("{}={}", key, shell_escape(value))), ); @@ -428,8 +428,8 @@ pub fn serve( tracing::info!(port, "Spawning sidecar"); let envs = [ - ("OPENCODE_SERVER_USERNAME", "opencode".to_string()), - ("OPENCODE_SERVER_PASSWORD", password.to_string()), + ("KILO_SERVER_USERNAME", "opencode".to_string()), + ("KILO_SERVER_PASSWORD", password.to_string()), ]; let (events, child) = spawn_command( diff --git a/packages/desktop/src-tauri/src/constants.rs b/packages/desktop/src-tauri/src/constants.rs index 9d50d00e202..d4068baac63 100644 --- a/packages/desktop/src-tauri/src/constants.rs +++ b/packages/desktop/src-tauri/src/constants.rs @@ -1,6 +1,6 @@ use tauri_plugin_window_state::StateFlags; -pub const SETTINGS_STORE: &str = "opencode.settings.dat"; +pub const SETTINGS_STORE: &str = "kilo.settings.dat"; pub const DEFAULT_SERVER_URL_KEY: &str = "defaultServerUrl"; pub const WSL_ENABLED_KEY: &str = "wslEnabled"; pub const UPDATER_ENABLED: bool = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some(); diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index 71fe8407f02..e746de7f2a2 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -294,7 +294,7 @@ pub fn run() { #[cfg(all(target_os = "macos", not(debug_assertions)))] let _ = std::process::Command::new("killall") - .arg("opencode-cli") + .arg("kilo-cli") .output(); let mut builder = tauri::Builder::default() @@ -635,9 +635,9 @@ async fn setup_server_connection(app: AppHandle) -> ServerConnection { } fn get_sidecar_port() -> u32 { - option_env!("OPENCODE_PORT") + option_env!("KILO_PORT") .map(|s| s.to_string()) - .or_else(|| std::env::var("OPENCODE_PORT").ok()) + .or_else(|| std::env::var("KILO_PORT").ok()) .and_then(|port_str| port_str.parse().ok()) .unwrap_or_else(|| { TcpListener::bind("127.0.0.1:0") @@ -667,7 +667,7 @@ fn opencode_db_path() -> Result { } }; - Ok(data_home.join("opencode").join("opencode.db")) + Ok(data_home.join("opencode").join("kilo.db")) } // Creates a `once` listener for the specified event and returns a future that resolves diff --git a/packages/desktop/src-tauri/src/linux_display.rs b/packages/desktop/src-tauri/src/linux_display.rs index 0179cf8bbb3..ad9a139e739 100644 --- a/packages/desktop/src-tauri/src/linux_display.rs +++ b/packages/desktop/src-tauri/src/linux_display.rs @@ -15,9 +15,9 @@ struct DisplayConfig { fn dir() -> Option { Some(dirs::data_dir()?.join(if cfg!(debug_assertions) { - "ai.opencode.desktop.dev" + "ai.kilo.desktop.dev" } else { - "ai.opencode.desktop" + "ai.kilo.desktop" })) } diff --git a/packages/desktop/src-tauri/src/main.rs b/packages/desktop/src-tauri/src/main.rs index c0ce2a445ae..a1b861ecd51 100644 --- a/packages/desktop/src-tauri/src/main.rs +++ b/packages/desktop/src-tauri/src/main.rs @@ -74,5 +74,5 @@ fn main() { } } - opencode_lib::run() + kilo_lib::run() } diff --git a/packages/desktop/src-tauri/src/windows.rs b/packages/desktop/src-tauri/src/windows.rs index f361cbe38d5..734173d34e8 100644 --- a/packages/desktop/src-tauri/src/windows.rs +++ b/packages/desktop/src-tauri/src/windows.rs @@ -60,9 +60,9 @@ impl MainWindow { .maximized(true) .initialization_script(format!( r#" - window.__OPENCODE__ ??= {{}}; - window.__OPENCODE__.updaterEnabled = {UPDATER_ENABLED}; - window.__OPENCODE__.wsl = {wsl_enabled}; + window.__KILO__ ??= {{}}; + window.__KILO__.updaterEnabled = {UPDATER_ENABLED}; + window.__KILO__.wsl = {wsl_enabled}; "# )); diff --git a/packages/desktop/src-tauri/tauri.conf.json b/packages/desktop/src-tauri/tauri.conf.json index d5ca15b8a71..f0679fe6316 100644 --- a/packages/desktop/src-tauri/tauri.conf.json +++ b/packages/desktop/src-tauri/tauri.conf.json @@ -1,8 +1,8 @@ { "$schema": "https://schema.tauri.app/config/2", - "productName": "OpenCode Dev", - "identifier": "ai.opencode.desktop.dev", - "mainBinaryName": "OpenCode", + "productName": "Kilo", + "identifier": "ai.kilo.desktop.dev", + "mainBinaryName": "Kilo", "version": "../package.json", "build": { "beforeDevCommand": "bun run dev", @@ -33,7 +33,7 @@ ], "active": true, "targets": ["deb", "rpm", "dmg", "nsis", "app"], - "externalBin": ["sidecars/opencode-cli"], + "externalBin": ["sidecars/kilo-cli"], "linux": { "rpm": { "compression": { diff --git a/packages/desktop/src-tauri/tauri.prod.conf.json b/packages/desktop/src-tauri/tauri.prod.conf.json index 0416c59cbb9..5e5f4958ca9 100644 --- a/packages/desktop/src-tauri/tauri.prod.conf.json +++ b/packages/desktop/src-tauri/tauri.prod.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", - "productName": "OpenCode", - "identifier": "ai.opencode.desktop", + "productName": "Kilo", + "identifier": "ai.kilo.desktop", "bundle": { "createUpdaterArtifacts": true, "icon": [ @@ -32,7 +32,7 @@ "plugins": { "updater": { "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYwMDM5Nzg5OUMzOUExMDQKUldRRW9UbWNpWmNEOENYT01CV0lhOXR1UFhpaXJsK1Z3aU9lZnNtNzE0TDROWVMwVW9XQnFOelkK", - "endpoints": ["https://github.com/anomalyco/opencode/releases/latest/download/latest.json"] + "endpoints": ["https://github.com/Kilo-Org/kilocode/releases/latest/download/latest.json"] } } } diff --git a/packages/desktop/src/i18n/ar.ts b/packages/desktop/src/i18n/ar.ts index fdbf0a80470..22b1475613a 100644 --- a/packages/desktop/src/i18n/ar.ts +++ b/packages/desktop/src/i18n/ar.ts @@ -11,11 +11,11 @@ export const dict = { "desktop.updater.checkFailed.title": "فشل التحقق من التحديثات", "desktop.updater.checkFailed.message": "فشل التحقق من وجود تحديثات", "desktop.updater.none.title": "لا توجد تحديثات متاحة", - "desktop.updater.none.message": "أنت تستخدم بالفعل أحدث إصدار من OpenCode", + "desktop.updater.none.message": "أنت تستخدم بالفعل أحدث إصدار من Kilo", "desktop.updater.downloadFailed.title": "فشل التحديث", "desktop.updater.downloadFailed.message": "فشل تنزيل التحديث", "desktop.updater.downloaded.title": "تم تنزيل التحديث", - "desktop.updater.downloaded.prompt": "تم تنزيل إصدار {{version}} من OpenCode، هل ترغب في تثبيته وإعادة تشغيله؟", + "desktop.updater.downloaded.prompt": "تم تنزيل إصدار {{version}} من Kilo، هل ترغب في تثبيته وإعادة تشغيله؟", "desktop.updater.installFailed.title": "فشل التحديث", "desktop.updater.installFailed.message": "فشل تثبيت التحديث", diff --git a/packages/desktop/src/i18n/br.ts b/packages/desktop/src/i18n/br.ts index 75fe2dc32bc..e0b16d99b97 100644 --- a/packages/desktop/src/i18n/br.ts +++ b/packages/desktop/src/i18n/br.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Falha ao verificar atualizações", "desktop.updater.checkFailed.message": "Falha ao verificar atualizações", "desktop.updater.none.title": "Nenhuma atualização disponível", - "desktop.updater.none.message": "Você já está usando a versão mais recente do OpenCode", + "desktop.updater.none.message": "Você já está usando a versão mais recente do Kilo", "desktop.updater.downloadFailed.title": "Falha na atualização", "desktop.updater.downloadFailed.message": "Falha ao baixar a atualização", "desktop.updater.downloaded.title": "Atualização baixada", "desktop.updater.downloaded.prompt": - "A versão {{version}} do OpenCode foi baixada. Você gostaria de instalá-la e reiniciar?", + "A versão {{version}} do Kilo foi baixada. Você gostaria de instalá-la e reiniciar?", "desktop.updater.installFailed.title": "Falha na atualização", "desktop.updater.installFailed.message": "Falha ao instalar a atualização", diff --git a/packages/desktop/src/i18n/bs.ts b/packages/desktop/src/i18n/bs.ts index 58c266f5305..5403217dfca 100644 --- a/packages/desktop/src/i18n/bs.ts +++ b/packages/desktop/src/i18n/bs.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Provjera ažuriranja nije uspjela", "desktop.updater.checkFailed.message": "Nije moguće provjeriti ažuriranja", "desktop.updater.none.title": "Nema dostupnog ažuriranja", - "desktop.updater.none.message": "Već koristiš najnoviju verziju OpenCode-a", + "desktop.updater.none.message": "Već koristiš najnoviju verziju Kilo-a", "desktop.updater.downloadFailed.title": "Ažuriranje nije uspjelo", "desktop.updater.downloadFailed.message": "Neuspjelo preuzimanje ažuriranja", "desktop.updater.downloaded.title": "Ažuriranje preuzeto", "desktop.updater.downloaded.prompt": - "Verzija {{version}} OpenCode-a je preuzeta. Želiš li da je instaliraš i ponovo pokreneš aplikaciju?", + "Verzija {{version}} Kilo-a je preuzeta. Želiš li da je instaliraš i ponovo pokreneš aplikaciju?", "desktop.updater.installFailed.title": "Ažuriranje nije uspjelo", "desktop.updater.installFailed.message": "Neuspjela instalacija ažuriranja", diff --git a/packages/desktop/src/i18n/da.ts b/packages/desktop/src/i18n/da.ts index 2109495f761..eccf7434672 100644 --- a/packages/desktop/src/i18n/da.ts +++ b/packages/desktop/src/i18n/da.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Opdateringstjek mislykkedes", "desktop.updater.checkFailed.message": "Kunne ikke tjekke for opdateringer", "desktop.updater.none.title": "Ingen opdatering tilgængelig", - "desktop.updater.none.message": "Du bruger allerede den nyeste version af OpenCode", + "desktop.updater.none.message": "Du bruger allerede den nyeste version af Kilo", "desktop.updater.downloadFailed.title": "Opdatering mislykkedes", "desktop.updater.downloadFailed.message": "Kunne ikke downloade opdateringen", "desktop.updater.downloaded.title": "Opdatering downloadet", "desktop.updater.downloaded.prompt": - "Version {{version}} af OpenCode er blevet downloadet. Vil du installere den og genstarte?", + "Version {{version}} af Kilo er blevet downloadet. Vil du installere den og genstarte?", "desktop.updater.installFailed.title": "Opdatering mislykkedes", "desktop.updater.installFailed.message": "Kunne ikke installere opdateringen", diff --git a/packages/desktop/src/i18n/de.ts b/packages/desktop/src/i18n/de.ts index 38ad8096e31..81349a8ab7f 100644 --- a/packages/desktop/src/i18n/de.ts +++ b/packages/desktop/src/i18n/de.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Updateprüfung fehlgeschlagen", "desktop.updater.checkFailed.message": "Updates konnten nicht geprüft werden", "desktop.updater.none.title": "Kein Update verfügbar", - "desktop.updater.none.message": "Sie verwenden bereits die neueste Version von OpenCode", + "desktop.updater.none.message": "Sie verwenden bereits die neueste Version von Kilo", "desktop.updater.downloadFailed.title": "Update fehlgeschlagen", "desktop.updater.downloadFailed.message": "Update konnte nicht heruntergeladen werden", "desktop.updater.downloaded.title": "Update heruntergeladen", "desktop.updater.downloaded.prompt": - "Version {{version}} von OpenCode wurde heruntergeladen. Möchten Sie sie installieren und neu starten?", + "Version {{version}} von Kilo wurde heruntergeladen. Möchten Sie sie installieren und neu starten?", "desktop.updater.installFailed.title": "Update fehlgeschlagen", "desktop.updater.installFailed.message": "Update konnte nicht installiert werden", diff --git a/packages/desktop/src/i18n/en.ts b/packages/desktop/src/i18n/en.ts index 4c30380d562..57feb5f815d 100644 --- a/packages/desktop/src/i18n/en.ts +++ b/packages/desktop/src/i18n/en.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Update Check Failed", "desktop.updater.checkFailed.message": "Failed to check for updates", "desktop.updater.none.title": "No Update Available", - "desktop.updater.none.message": "You are already using the latest version of OpenCode", + "desktop.updater.none.message": "You are already using the latest version of Kilo", "desktop.updater.downloadFailed.title": "Update Failed", "desktop.updater.downloadFailed.message": "Failed to download update", "desktop.updater.downloaded.title": "Update Downloaded", "desktop.updater.downloaded.prompt": - "Version {{version}} of OpenCode has been downloaded, would you like to install it and relaunch?", + "Version {{version}} of Kilo has been downloaded, would you like to install it and relaunch?", "desktop.updater.installFailed.title": "Update Failed", "desktop.updater.installFailed.message": "Failed to install update", diff --git a/packages/desktop/src/i18n/es.ts b/packages/desktop/src/i18n/es.ts index 80504a8f248..a86119e4787 100644 --- a/packages/desktop/src/i18n/es.ts +++ b/packages/desktop/src/i18n/es.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Comprobación de actualizaciones fallida", "desktop.updater.checkFailed.message": "No se pudieron buscar actualizaciones", "desktop.updater.none.title": "No hay actualizaciones disponibles", - "desktop.updater.none.message": "Ya estás usando la versión más reciente de OpenCode", + "desktop.updater.none.message": "Ya estás usando la versión más reciente de Kilo", "desktop.updater.downloadFailed.title": "Actualización fallida", "desktop.updater.downloadFailed.message": "No se pudo descargar la actualización", "desktop.updater.downloaded.title": "Actualización descargada", "desktop.updater.downloaded.prompt": - "Se ha descargado la versión {{version}} de OpenCode. ¿Quieres instalarla y reiniciar?", + "Se ha descargado la versión {{version}} de Kilo. ¿Quieres instalarla y reiniciar?", "desktop.updater.installFailed.title": "Actualización fallida", "desktop.updater.installFailed.message": "No se pudo instalar la actualización", diff --git a/packages/desktop/src/i18n/fr.ts b/packages/desktop/src/i18n/fr.ts index 4f0bb2b16c6..72af95e14f3 100644 --- a/packages/desktop/src/i18n/fr.ts +++ b/packages/desktop/src/i18n/fr.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Échec de la vérification des mises à jour", "desktop.updater.checkFailed.message": "Impossible de vérifier les mises à jour", "desktop.updater.none.title": "Aucune mise à jour disponible", - "desktop.updater.none.message": "Vous utilisez déjà la dernière version d'OpenCode", + "desktop.updater.none.message": "Vous utilisez déjà la dernière version d'Kilo", "desktop.updater.downloadFailed.title": "Échec de la mise à jour", "desktop.updater.downloadFailed.message": "Impossible de télécharger la mise à jour", "desktop.updater.downloaded.title": "Mise à jour téléchargée", "desktop.updater.downloaded.prompt": - "La version {{version}} d'OpenCode a été téléchargée. Voulez-vous l'installer et redémarrer ?", + "La version {{version}} d'Kilo a été téléchargée. Voulez-vous l'installer et redémarrer ?", "desktop.updater.installFailed.title": "Échec de la mise à jour", "desktop.updater.installFailed.message": "Impossible d'installer la mise à jour", diff --git a/packages/desktop/src/i18n/ja.ts b/packages/desktop/src/i18n/ja.ts index fc485c6f401..0bd9178928b 100644 --- a/packages/desktop/src/i18n/ja.ts +++ b/packages/desktop/src/i18n/ja.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "アップデートの確認に失敗しました", "desktop.updater.checkFailed.message": "アップデートを確認できませんでした", "desktop.updater.none.title": "利用可能なアップデートはありません", - "desktop.updater.none.message": "すでに最新バージョンの OpenCode を使用しています", + "desktop.updater.none.message": "すでに最新バージョンの Kilo を使用しています", "desktop.updater.downloadFailed.title": "アップデートに失敗しました", "desktop.updater.downloadFailed.message": "アップデートをダウンロードできませんでした", "desktop.updater.downloaded.title": "アップデートをダウンロードしました", "desktop.updater.downloaded.prompt": - "OpenCode のバージョン {{version}} がダウンロードされました。インストールして再起動しますか?", + "Kilo のバージョン {{version}} がダウンロードされました。インストールして再起動しますか?", "desktop.updater.installFailed.title": "アップデートに失敗しました", "desktop.updater.installFailed.message": "アップデートをインストールできませんでした", diff --git a/packages/desktop/src/i18n/ko.ts b/packages/desktop/src/i18n/ko.ts index be27cec86ac..5baddce1679 100644 --- a/packages/desktop/src/i18n/ko.ts +++ b/packages/desktop/src/i18n/ko.ts @@ -11,11 +11,11 @@ export const dict = { "desktop.updater.checkFailed.title": "업데이트 확인 실패", "desktop.updater.checkFailed.message": "업데이트를 확인하지 못했습니다", "desktop.updater.none.title": "사용 가능한 업데이트 없음", - "desktop.updater.none.message": "이미 최신 버전의 OpenCode를 사용하고 있습니다", + "desktop.updater.none.message": "이미 최신 버전의 Kilo를 사용하고 있습니다", "desktop.updater.downloadFailed.title": "업데이트 실패", "desktop.updater.downloadFailed.message": "업데이트를 다운로드하지 못했습니다", "desktop.updater.downloaded.title": "업데이트 다운로드 완료", - "desktop.updater.downloaded.prompt": "OpenCode {{version}} 버전을 다운로드했습니다. 설치하고 다시 실행할까요?", + "desktop.updater.downloaded.prompt": "Kilo {{version}} 버전을 다운로드했습니다. 설치하고 다시 실행할까요?", "desktop.updater.installFailed.title": "업데이트 실패", "desktop.updater.installFailed.message": "업데이트를 설치하지 못했습니다", diff --git a/packages/desktop/src/i18n/no.ts b/packages/desktop/src/i18n/no.ts index e39bd7f3b44..7344384c9ea 100644 --- a/packages/desktop/src/i18n/no.ts +++ b/packages/desktop/src/i18n/no.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Oppdateringssjekk mislyktes", "desktop.updater.checkFailed.message": "Kunne ikke se etter oppdateringer", "desktop.updater.none.title": "Ingen oppdatering tilgjengelig", - "desktop.updater.none.message": "Du bruker allerede den nyeste versjonen av OpenCode", + "desktop.updater.none.message": "Du bruker allerede den nyeste versjonen av Kilo", "desktop.updater.downloadFailed.title": "Oppdatering mislyktes", "desktop.updater.downloadFailed.message": "Kunne ikke laste ned oppdateringen", "desktop.updater.downloaded.title": "Oppdatering lastet ned", "desktop.updater.downloaded.prompt": - "Versjon {{version}} av OpenCode er lastet ned. Vil du installere den og starte på nytt?", + "Versjon {{version}} av Kilo er lastet ned. Vil du installere den og starte på nytt?", "desktop.updater.installFailed.title": "Oppdatering mislyktes", "desktop.updater.installFailed.message": "Kunne ikke installere oppdateringen", diff --git a/packages/desktop/src/i18n/pl.ts b/packages/desktop/src/i18n/pl.ts index d3ad7ce64f8..e44ba609366 100644 --- a/packages/desktop/src/i18n/pl.ts +++ b/packages/desktop/src/i18n/pl.ts @@ -11,12 +11,12 @@ export const dict = { "desktop.updater.checkFailed.title": "Nie udało się sprawdzić aktualizacji", "desktop.updater.checkFailed.message": "Nie udało się sprawdzić aktualizacji", "desktop.updater.none.title": "Brak dostępnych aktualizacji", - "desktop.updater.none.message": "Korzystasz już z najnowszej wersji OpenCode", + "desktop.updater.none.message": "Korzystasz już z najnowszej wersji Kilo", "desktop.updater.downloadFailed.title": "Aktualizacja nie powiodła się", "desktop.updater.downloadFailed.message": "Nie udało się pobrać aktualizacji", "desktop.updater.downloaded.title": "Aktualizacja pobrana", "desktop.updater.downloaded.prompt": - "Pobrano wersję {{version}} OpenCode. Czy chcesz ją zainstalować i uruchomić ponownie?", + "Pobrano wersję {{version}} Kilo. Czy chcesz ją zainstalować i uruchomić ponownie?", "desktop.updater.installFailed.title": "Aktualizacja nie powiodła się", "desktop.updater.installFailed.message": "Nie udało się zainstalować aktualizacji", diff --git a/packages/desktop/src/i18n/ru.ts b/packages/desktop/src/i18n/ru.ts index 8e09cc45b49..4ce1ed80d9e 100644 --- a/packages/desktop/src/i18n/ru.ts +++ b/packages/desktop/src/i18n/ru.ts @@ -11,11 +11,11 @@ export const dict = { "desktop.updater.checkFailed.title": "Не удалось проверить обновления", "desktop.updater.checkFailed.message": "Не удалось проверить обновления", "desktop.updater.none.title": "Обновлений нет", - "desktop.updater.none.message": "Вы уже используете последнюю версию OpenCode", + "desktop.updater.none.message": "Вы уже используете последнюю версию Kilo", "desktop.updater.downloadFailed.title": "Обновление не удалось", "desktop.updater.downloadFailed.message": "Не удалось скачать обновление", "desktop.updater.downloaded.title": "Обновление загружено", - "desktop.updater.downloaded.prompt": "Версия OpenCode {{version}} загружена. Хотите установить и перезапустить?", + "desktop.updater.downloaded.prompt": "Версия Kilo {{version}} загружена. Хотите установить и перезапустить?", "desktop.updater.installFailed.title": "Обновление не удалось", "desktop.updater.installFailed.message": "Не удалось установить обновление", diff --git a/packages/desktop/src/i18n/zh.ts b/packages/desktop/src/i18n/zh.ts index aeb3a54e03e..fd5d27f7989 100644 --- a/packages/desktop/src/i18n/zh.ts +++ b/packages/desktop/src/i18n/zh.ts @@ -11,11 +11,11 @@ export const dict = { "desktop.updater.checkFailed.title": "检查更新失败", "desktop.updater.checkFailed.message": "无法检查更新", "desktop.updater.none.title": "没有可用更新", - "desktop.updater.none.message": "你已经在使用最新版本的 OpenCode", + "desktop.updater.none.message": "你已经在使用最新版本的 Kilo", "desktop.updater.downloadFailed.title": "更新失败", "desktop.updater.downloadFailed.message": "无法下载更新", "desktop.updater.downloaded.title": "更新已下载", - "desktop.updater.downloaded.prompt": "已下载 OpenCode {{version}} 版本,是否安装并重启?", + "desktop.updater.downloaded.prompt": "已下载 Kilo {{version}} 版本,是否安装并重启?", "desktop.updater.installFailed.title": "更新失败", "desktop.updater.installFailed.message": "无法安装更新", diff --git a/packages/desktop/src/i18n/zht.ts b/packages/desktop/src/i18n/zht.ts index 7fd677aca44..49942c1cfda 100644 --- a/packages/desktop/src/i18n/zht.ts +++ b/packages/desktop/src/i18n/zht.ts @@ -11,11 +11,11 @@ export const dict = { "desktop.updater.checkFailed.title": "檢查更新失敗", "desktop.updater.checkFailed.message": "無法檢查更新", "desktop.updater.none.title": "沒有可用更新", - "desktop.updater.none.message": "你已在使用最新版的 OpenCode", + "desktop.updater.none.message": "你已在使用最新版的 Kilo", "desktop.updater.downloadFailed.title": "更新失敗", "desktop.updater.downloadFailed.message": "無法下載更新", "desktop.updater.downloaded.title": "更新已下載", - "desktop.updater.downloaded.prompt": "已下載 OpenCode {{version}} 版本,是否安裝並重新啟動?", + "desktop.updater.downloaded.prompt": "已下載 Kilo {{version}} 版本,是否安裝並重新啟動?", "desktop.updater.installFailed.title": "更新失敗", "desktop.updater.installFailed.message": "無法安裝更新", diff --git a/packages/desktop/src/menu.ts b/packages/desktop/src/menu.ts index 9fcb6115b1e..65cc8e7c339 100644 --- a/packages/desktop/src/menu.ts +++ b/packages/desktop/src/menu.ts @@ -16,7 +16,7 @@ export async function createMenu(trigger: (id: string) => void) { const menu = await Menu.new({ items: [ await Submenu.new({ - text: "OpenCode", + text: "Kilo", items: [ await PredefinedMenuItem.new({ item: { About: null }, @@ -159,8 +159,8 @@ export async function createMenu(trigger: (id: string) => void) { items: [ // missing native macos search await MenuItem.new({ - action: () => openUrl("https://opencode.ai/docs"), - text: "OpenCode Documentation", + action: () => openUrl("https://kilo.ai/docs"), + text: "Kilo Documentation", }), await MenuItem.new({ action: () => openUrl("https://discord.com/invite/opencode"), @@ -176,11 +176,11 @@ export async function createMenu(trigger: (id: string) => void) { item: "Separator", }), await MenuItem.new({ - action: () => openUrl("https://github.com/anomalyco/opencode/issues/new?template=feature_request.yml"), + action: () => openUrl("https://github.com/Kilo-Org/kilocode/issues/new?template=feature_request.yml"), text: "Share Feedback", }), await MenuItem.new({ - action: () => openUrl("https://github.com/anomalyco/opencode/issues/new?template=bug_report.yml"), + action: () => openUrl("https://github.com/Kilo-Org/kilocode/issues/new?template=bug_report.yml"), text: "Report a Bug", }), ], diff --git a/packages/desktop/src/updater.ts b/packages/desktop/src/updater.ts index 73266963388..b933521bf65 100644 --- a/packages/desktop/src/updater.ts +++ b/packages/desktop/src/updater.ts @@ -6,7 +6,7 @@ import { type as ostype } from "@tauri-apps/plugin-os" import { initI18n, t } from "./i18n" import { commands } from "./bindings" -export const UPDATER_ENABLED = window.__OPENCODE__?.updaterEnabled ?? false +export const UPDATER_ENABLED = window.__KILO__?.updaterEnabled ?? false export async function runUpdater({ alertOnFail }: { alertOnFail: boolean }) { await initI18n() diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index cc46f7530fb..27e9bd198b4 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.2.15", + "version": "7.0.30", "private": true, "type": "module", "license": "MIT", diff --git a/packages/enterprise/src/core/share.ts b/packages/enterprise/src/core/share.ts index d7f5c8b8d52..f1eee3311af 100644 --- a/packages/enterprise/src/core/share.ts +++ b/packages/enterprise/src/core/share.ts @@ -1,4 +1,4 @@ -import { FileDiff, Message, Model, Part, Session } from "@opencode-ai/sdk/v2" +import { FileDiff, Message, Model, Part, Session } from "@kilocode/sdk/v2" import { fn } from "@opencode-ai/util/fn" import { iife } from "@opencode-ai/util/iife" import { Identifier } from "@opencode-ai/util/identifier" diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx index eb830e4a643..18adca22586 100644 --- a/packages/enterprise/src/routes/share/[shareID].tsx +++ b/packages/enterprise/src/routes/share/[shareID].tsx @@ -1,4 +1,4 @@ -import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2" +import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@kilocode/sdk/v2" import { SessionTurn } from "@opencode-ai/ui/session-turn" import { SessionReview } from "@opencode-ai/ui/session-review" import { DataProvider } from "@opencode-ai/ui/context" diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index e9f246af890..2c88ee1788d 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,36 +1,36 @@ -id = "opencode" -name = "OpenCode" +id = "kilo" +name = "Kilo" description = "The open source coding agent." version = "1.2.15" schema_version = 1 authors = ["Anomaly"] -repository = "https://github.com/anomalyco/opencode" +repository = "https://github.com/Kilo-Org/kilocode" [agent_servers.opencode] -name = "OpenCode" +name = "Kilo" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.2.15/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.2.15/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.2.15/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.2.15/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.15/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.2.15/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 63e50b99211..b75c798f70c 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.2.15", + "version": "7.0.30", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 9252468153b..d389dfab687 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.2.15", - "name": "opencode", + "version": "7.0.30", + "name": "@kilocode/cli", "type": "module", "license": "MIT", "private": true, @@ -73,7 +73,7 @@ "@ai-sdk/provider-utils": "3.0.21", "@ai-sdk/togetherai": "1.0.34", "@ai-sdk/vercel": "1.0.33", - "@ai-sdk/xai": "2.0.51", + "@ai-sdk/xai": "2.0.56", "@aws-sdk/credential-providers": "3.993.0", "@clack/prompts": "1.0.0-alpha.1", "@gitlab/gitlab-ai-provider": "3.6.0", @@ -84,9 +84,9 @@ "@octokit/graphql": "9.0.2", "@octokit/rest": "catalog:", "@openauthjs/openauth": "catalog:", - "@opencode-ai/plugin": "workspace:*", + "@kilocode/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "@opencode-ai/util": "workspace:*", "@openrouter/ai-sdk-provider": "1.5.4", "@opentui/core": "0.1.81", @@ -130,9 +130,13 @@ "xdg-basedir": "5.1.0", "yargs": "18.0.0", "zod": "catalog:", - "zod-to-json-schema": "3.24.5" + "zod-to-json-schema": "3.24.5", + "@kilocode/kilo-gateway": "workspace:*", + "@kilocode/kilo-telemetry": "workspace:*", + "simple-git": "3.31.1" }, "overrides": { "drizzle-orm": "1.0.0-beta.12-a5629fb" - } + }, + "peerDependencies": {} } diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 34e80d71a08..c73583130f1 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -15,7 +15,7 @@ process.chdir(dir) import { Script } from "@opencode-ai/script" import pkg from "../package.json" -const modelsUrl = process.env.OPENCODE_MODELS_URL || "https://models.dev" +const modelsUrl = process.env.KILO_MODELS_URL || "https://models.dev" // Fetch and generate models.dev snapshot const modelsData = process.env.MODELS_DEV_API_JSON ? await Bun.file(process.env.MODELS_DEV_API_JSON).text() @@ -185,12 +185,12 @@ for (const item of targets) { }, entrypoints: ["./src/index.ts", parserWorker, workerPath], define: { - OPENCODE_VERSION: `'${Script.version}'`, - OPENCODE_MIGRATIONS: JSON.stringify(migrations), + KILO_VERSION: `'${Script.version}'`, + KILO_MIGRATIONS: JSON.stringify(migrations), OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath, - OPENCODE_WORKER_PATH: workerPath, - OPENCODE_CHANNEL: `'${Script.channel}'`, - OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "", + KILO_WORKER_PATH: workerPath, + KILO_CHANNEL: `'${Script.channel}'`, + KILO_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "", }, }) diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index fbc1c83ba6d..e12cf6e1058 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -49,7 +49,7 @@ const tasks = Object.entries(binaries).map(async ([name]) => { await Promise.all(tasks) await $`cd ./dist/${pkg.name} && bun pm pack && npm publish *.tgz --access public --tag ${Script.channel}` -const image = "ghcr.io/anomalyco/opencode" +const image = "ghcr.io/Kilo-Org/kilocode" const platforms = "linux/amd64,linux/arm64" const tags = [`${image}:${version}`, `${image}:${Script.channel}`] const tagFlags = tags.flatMap((t) => ["-t", t]) @@ -76,17 +76,17 @@ if (!Script.preview) { "options=('!debug' '!strip')", "pkgrel=1", "pkgdesc='The AI coding agent built for the terminal.'", - "url='https://github.com/anomalyco/opencode'", + "url='https://github.com/Kilo-Org/kilocode'", "arch=('aarch64' 'x86_64')", "license=('MIT')", "provides=('opencode')", "conflicts=('opencode')", "depends=('ripgrep')", "", - `source_aarch64=("\${pkgname}_\${pkgver}_aarch64.tar.gz::https://github.com/anomalyco/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-arm64.tar.gz")`, + `source_aarch64=("\${pkgname}_\${pkgver}_aarch64.tar.gz::https://github.com/Kilo-Org/kilocode/releases/download/v\${pkgver}\${_subver}/opencode-linux-arm64.tar.gz")`, `sha256sums_aarch64=('${arm64Sha}')`, - `source_x86_64=("\${pkgname}_\${pkgver}_x86_64.tar.gz::https://github.com/anomalyco/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-x64.tar.gz")`, + `source_x86_64=("\${pkgname}_\${pkgver}_x86_64.tar.gz::https://github.com/Kilo-Org/kilocode/releases/download/v\${pkgver}\${_subver}/opencode-linux-x64.tar.gz")`, `sha256sums_x86_64=('${x64Sha}')`, "", "package() {", @@ -121,14 +121,14 @@ if (!Script.preview) { "# This file was generated by GoReleaser. DO NOT EDIT.", "class Opencode < Formula", ` desc "The AI coding agent built for the terminal."`, - ` homepage "https://github.com/anomalyco/opencode"`, + ` homepage "https://github.com/Kilo-Org/kilocode"`, ` version "${Script.version.split("-")[0]}"`, "", ` depends_on "ripgrep"`, "", " on_macos do", " if Hardware::CPU.intel?", - ` url "https://github.com/anomalyco/opencode/releases/download/v${Script.version}/opencode-darwin-x64.zip"`, + ` url "https://github.com/Kilo-Org/kilocode/releases/download/v${Script.version}/opencode-darwin-x64.zip"`, ` sha256 "${macX64Sha}"`, "", " def install", @@ -136,7 +136,7 @@ if (!Script.preview) { " end", " end", " if Hardware::CPU.arm?", - ` url "https://github.com/anomalyco/opencode/releases/download/v${Script.version}/opencode-darwin-arm64.zip"`, + ` url "https://github.com/Kilo-Org/kilocode/releases/download/v${Script.version}/opencode-darwin-arm64.zip"`, ` sha256 "${macArm64Sha}"`, "", " def install", @@ -147,14 +147,14 @@ if (!Script.preview) { "", " on_linux do", " if Hardware::CPU.intel? and Hardware::CPU.is_64_bit?", - ` url "https://github.com/anomalyco/opencode/releases/download/v${Script.version}/opencode-linux-x64.tar.gz"`, + ` url "https://github.com/Kilo-Org/kilocode/releases/download/v${Script.version}/opencode-linux-x64.tar.gz"`, ` sha256 "${x64Sha}"`, " def install", ' bin.install "opencode"', " end", " end", " if Hardware::CPU.arm? and Hardware::CPU.is_64_bit?", - ` url "https://github.com/anomalyco/opencode/releases/download/v${Script.version}/opencode-linux-arm64.tar.gz"`, + ` url "https://github.com/Kilo-Org/kilocode/releases/download/v${Script.version}/opencode-linux-arm64.tar.gz"`, ` sha256 "${arm64Sha}"`, " def install", ' bin.install "opencode"', diff --git a/packages/opencode/src/acp/agent.ts b/packages/opencode/src/acp/agent.ts index 8b338f1b571..8c4920d0f6e 100644 --- a/packages/opencode/src/acp/agent.ts +++ b/packages/opencode/src/acp/agent.ts @@ -41,7 +41,7 @@ import { Config } from "@/config/config" import { Todo } from "@/session/todo" import { z } from "zod" import { LoadAPIKeyError } from "ai" -import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2" +import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@kilocode/sdk/v2" import { applyPatch } from "diff" type ModeOption = { id: string; name: string; description?: string } diff --git a/packages/opencode/src/acp/session.ts b/packages/opencode/src/acp/session.ts index b96ebc1c895..07ad27d98b5 100644 --- a/packages/opencode/src/acp/session.ts +++ b/packages/opencode/src/acp/session.ts @@ -1,7 +1,7 @@ import { RequestError, type McpServer } from "@agentclientprotocol/sdk" import type { ACPSessionState } from "./types" import { Log } from "@/util/log" -import type { OpencodeClient } from "@opencode-ai/sdk/v2" +import type { OpencodeClient } from "@kilocode/sdk/v2" const log = Log.create({ service: "acp-session-manager" }) diff --git a/packages/opencode/src/acp/types.ts b/packages/opencode/src/acp/types.ts index de8ac508122..d6491366737 100644 --- a/packages/opencode/src/acp/types.ts +++ b/packages/opencode/src/acp/types.ts @@ -1,5 +1,5 @@ import type { McpServer } from "@agentclientprotocol/sdk" -import type { OpencodeClient } from "@opencode-ai/sdk/v2" +import type { OpencodeClient } from "@kilocode/sdk/v2" export interface ACPSessionState { id: string diff --git a/packages/opencode/src/cli/cmd/acp.ts b/packages/opencode/src/cli/cmd/acp.ts index 99a9a81ab9c..5a0febb83b3 100644 --- a/packages/opencode/src/cli/cmd/acp.ts +++ b/packages/opencode/src/cli/cmd/acp.ts @@ -4,7 +4,7 @@ import { cmd } from "./cmd" import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk" import { ACP } from "@/acp/agent" import { Server } from "@/server/server" -import { createOpencodeClient } from "@opencode-ai/sdk/v2" +import { createOpencodeClient } from "@kilocode/sdk/v2" import { withNetworkOptions, resolveNetworkOptions } from "../network" const log = Log.create({ service: "acp-command" }) diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts index 95635916413..e608ac7228e 100644 --- a/packages/opencode/src/cli/cmd/auth.ts +++ b/packages/opencode/src/cli/cmd/auth.ts @@ -10,7 +10,7 @@ import { Config } from "../../config/config" import { Global } from "../../global" import { Plugin } from "../../plugin" import { Instance } from "../../project/instance" -import type { Hooks } from "@opencode-ai/plugin" +import type { Hooks } from "@kilocode/plugin" import { Process } from "../../util/process" import { text } from "node:stream/consumers" diff --git a/packages/opencode/src/cli/cmd/import.ts b/packages/opencode/src/cli/cmd/import.ts index 4d65060f18f..26869826589 100644 --- a/packages/opencode/src/cli/cmd/import.ts +++ b/packages/opencode/src/cli/cmd/import.ts @@ -1,5 +1,5 @@ import type { Argv } from "yargs" -import type { Session as SDKSession, Message, Part } from "@opencode-ai/sdk/v2" +import type { Session as SDKSession, Message, Part } from "@kilocode/sdk/v2" import { Session } from "../../session" import { cmd } from "./cmd" import { bootstrap } from "../bootstrap" diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts index f3781f1abd8..5ca8e073ad8 100644 --- a/packages/opencode/src/cli/cmd/run.ts +++ b/packages/opencode/src/cli/cmd/run.ts @@ -7,7 +7,7 @@ import { Flag } from "../../flag/flag" import { bootstrap } from "../bootstrap" import { EOL } from "os" import { Filesystem } from "../../util/filesystem" -import { createOpencodeClient, type Message, type OpencodeClient, type ToolPart } from "@opencode-ai/sdk/v2" +import { createOpencodeClient, type Message, type OpencodeClient, type ToolPart } from "@kilocode/sdk/v2" import { Server } from "../../server/server" import { Provider } from "../../provider/provider" import { Agent } from "../../agent/agent" diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx index d88dfdd86f1..277b39a3575 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx @@ -8,7 +8,7 @@ import { DialogPrompt } from "../ui/dialog-prompt" import { Link } from "../ui/link" import { useTheme } from "../context/theme" import { TextAttributes } from "@opentui/core" -import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2" +import type { ProviderAuthAuthorization } from "@kilocode/sdk/v2" import { DialogModel } from "./dialog-model" import { useKeyboard } from "@opentui/solid" import { Clipboard } from "@tui/util/clipboard" diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx index d49dd5c7b69..739b6c1992c 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx @@ -5,7 +5,7 @@ import { onMount } from "solid-js" import { createStore, produce, unwrap } from "solid-js/store" import { createSimpleContext } from "../../context/helper" import { appendFile, writeFile } from "fs/promises" -import type { AgentPart, FilePart, TextPart } from "@opencode-ai/sdk/v2" +import type { AgentPart, FilePart, TextPart } from "@kilocode/sdk/v2" export type PromptInfo = { input: string diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index d63c248fb83..3c1543803fe 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -21,7 +21,7 @@ import { useRenderer } from "@opentui/solid" import { Editor } from "@tui/util/editor" import { useExit } from "../../context/exit" import { Clipboard } from "../../util/clipboard" -import type { FilePart } from "@opencode-ai/sdk/v2" +import type { FilePart } from "@kilocode/sdk/v2" import { TuiEvent } from "../../event" import { iife } from "@/util/iife" import { Locale } from "@/util/locale" diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx index 7fa7e05c3d2..40139867c4f 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx @@ -1,4 +1,4 @@ -import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2" +import { createOpencodeClient, type Event } from "@kilocode/sdk/v2" import { createSimpleContext } from "./helper" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { batch, onCleanup, onMount } from "solid-js" diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 269ed7ae0bd..87cf87719c6 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -17,7 +17,7 @@ import type { ProviderListResponse, ProviderAuthMethod, VcsInfo, -} from "@opencode-ai/sdk/v2" +} from "@kilocode/sdk/v2" import { createStore, produce, reconcile } from "solid-js/store" import { useSDK } from "@tui/context/sdk" import { Binary } from "@opencode-ai/util/binary" @@ -27,7 +27,7 @@ import { useExit } from "./exit" import { useArgs } from "./args" import { batch, onMount } from "solid-js" import { Log } from "@/util/log" -import type { Path } from "@opencode-ai/sdk" +import type { Path } from "@kilocode/sdk" export const { use: useSync, provider: SyncProvider } = createSimpleContext({ name: "Sync", diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx index 62154cce563..70e98c7e78b 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx @@ -1,7 +1,7 @@ import { createMemo, onMount } from "solid-js" import { useSync } from "@tui/context/sync" import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select" -import type { TextPart } from "@opencode-ai/sdk/v2" +import type { TextPart } from "@kilocode/sdk/v2" import { Locale } from "@/util/locale" import { useSDK } from "@tui/context/sdk" import { useRoute } from "@tui/context/route" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx index 87248a6a8ba..19277020e85 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx @@ -1,7 +1,7 @@ import { createMemo, onMount } from "solid-js" import { useSync } from "@tui/context/sync" import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select" -import type { TextPart } from "@opencode-ai/sdk/v2" +import type { TextPart } from "@kilocode/sdk/v2" import { Locale } from "@/util/locale" import { DialogMessage } from "./dialog-message" import { useDialog } from "../../ui/dialog" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx index 0c5ea9a8572..e0ec96de05b 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx @@ -4,7 +4,7 @@ import { useSync } from "@tui/context/sync" import { pipe, sumBy } from "remeda" import { useTheme } from "@tui/context/theme" import { SplitBorder } from "@tui/component/border" -import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2" +import type { AssistantMessage, Session } from "@kilocode/sdk/v2" import { useCommandDialog } from "@tui/component/dialog-command" import { useKeybind } from "../../context/keybind" import { useTerminalDimensions } from "@opentui/solid" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index f20267e0820..f816a0d972d 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -28,7 +28,7 @@ import { RGBA, } from "@opentui/core" import { Prompt, type PromptRef } from "@tui/component/prompt" -import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencode-ai/sdk/v2" +import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@kilocode/sdk/v2" import { useLocal } from "@tui/context/local" import { Locale } from "@/util/locale" import type { Tool } from "@/tool/tool" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx index a50cd96fc84..4371debfac6 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx @@ -4,7 +4,7 @@ import { Portal, useKeyboard, useRenderer, useTerminalDimensions, type JSX } fro import type { TextareaRenderable } from "@opentui/core" import { useKeybind } from "../../context/keybind" import { useTheme, selectedForeground } from "../../context/theme" -import type { PermissionRequest } from "@opencode-ai/sdk/v2" +import type { PermissionRequest } from "@kilocode/sdk/v2" import { useSDK } from "../../context/sdk" import { SplitBorder } from "../../component/border" import { useSync } from "../../context/sync" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx index 1565a300818..fb5fc6f2373 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx @@ -4,7 +4,7 @@ import { useKeyboard } from "@opentui/solid" import type { TextareaRenderable } from "@opentui/core" import { useKeybind } from "../../context/keybind" import { selectedForeground, tint, useTheme } from "../../context/theme" -import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" +import type { QuestionAnswer, QuestionRequest } from "@kilocode/sdk/v2" import { useSDK } from "../../context/sdk" import { SplitBorder } from "../../component/border" import { useTextareaKeybindings } from "../../component/textarea-keybindings" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx index 42ac5fbe080..c4e0727ed14 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx @@ -4,7 +4,7 @@ import { createStore } from "solid-js/store" import { useTheme } from "../../context/theme" import { Locale } from "@/util/locale" import path from "path" -import type { AssistantMessage } from "@opencode-ai/sdk/v2" +import type { AssistantMessage } from "@kilocode/sdk/v2" import { Global } from "@/global" import { Installation } from "@/installation" import { useKeybind } from "../../context/keybind" diff --git a/packages/opencode/src/cli/cmd/tui/thread.ts b/packages/opencode/src/cli/cmd/tui/thread.ts index 750347d9d63..43e54b0c171 100644 --- a/packages/opencode/src/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/cli/cmd/tui/thread.ts @@ -9,7 +9,7 @@ import { iife } from "@/util/iife" import { Log } from "@/util/log" import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network" import { Filesystem } from "@/util/filesystem" -import type { Event } from "@opencode-ai/sdk/v2" +import type { Event } from "@kilocode/sdk/v2" import type { EventSource } from "./context/sdk" import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32" import { TuiConfig } from "@/config/tui" diff --git a/packages/opencode/src/cli/cmd/tui/util/transcript.ts b/packages/opencode/src/cli/cmd/tui/util/transcript.ts index 420c9dde1bf..a7b0628d46c 100644 --- a/packages/opencode/src/cli/cmd/tui/util/transcript.ts +++ b/packages/opencode/src/cli/cmd/tui/util/transcript.ts @@ -1,4 +1,4 @@ -import type { AssistantMessage, Part, UserMessage } from "@opencode-ai/sdk/v2" +import type { AssistantMessage, Part, UserMessage } from "@kilocode/sdk/v2" import { Locale } from "@/util/locale" export type TranscriptOptions = { diff --git a/packages/opencode/src/cli/cmd/tui/worker.ts b/packages/opencode/src/cli/cmd/tui/worker.ts index bb5495c4811..78d89020c90 100644 --- a/packages/opencode/src/cli/cmd/tui/worker.ts +++ b/packages/opencode/src/cli/cmd/tui/worker.ts @@ -7,7 +7,7 @@ import { Rpc } from "@/util/rpc" import { upgrade } from "@/cli/upgrade" import { Config } from "@/config/config" import { GlobalBus } from "@/bus/global" -import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2" +import { createOpencodeClient, type Event } from "@kilocode/sdk/v2" import type { BunWebSocketData } from "hono/bun" import { Flag } from "@/flag/flag" diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts index 56931b2ed62..abb9e585aef 100644 --- a/packages/opencode/src/plugin/codex.ts +++ b/packages/opencode/src/plugin/codex.ts @@ -1,4 +1,4 @@ -import type { Hooks, PluginInput } from "@opencode-ai/plugin" +import type { Hooks, PluginInput } from "@kilocode/plugin" import { Log } from "../util/log" import { Installation } from "../installation" import { Auth, OAUTH_DUMMY_KEY } from "../auth" diff --git a/packages/opencode/src/plugin/copilot.ts b/packages/opencode/src/plugin/copilot.ts index 39ea0d00d28..a4f0256877b 100644 --- a/packages/opencode/src/plugin/copilot.ts +++ b/packages/opencode/src/plugin/copilot.ts @@ -1,4 +1,4 @@ -import type { Hooks, PluginInput } from "@opencode-ai/plugin" +import type { Hooks, PluginInput } from "@kilocode/plugin" import { Installation } from "@/installation" import { iife } from "@/util/iife" diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index e65d21bfd60..1fa11a773fe 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -1,8 +1,8 @@ -import type { Hooks, PluginInput, Plugin as PluginInstance } from "@opencode-ai/plugin" +import type { Hooks, PluginInput, Plugin as PluginInstance } from "@kilocode/plugin" import { Config } from "../config/config" import { Bus } from "../bus" import { Log } from "../util/log" -import { createOpencodeClient } from "@opencode-ai/sdk" +import { createOpencodeClient } from "@kilocode/sdk" import { Server } from "../server/server" import { BunProc } from "../bun" import { Instance } from "../project/instance" diff --git a/packages/opencode/src/provider/auth.ts b/packages/opencode/src/provider/auth.ts index e6681ff0891..46d1f8381bc 100644 --- a/packages/opencode/src/provider/auth.ts +++ b/packages/opencode/src/provider/auth.ts @@ -3,7 +3,7 @@ import { Plugin } from "../plugin" import { map, filter, pipe, fromEntries, mapValues } from "remeda" import z from "zod" import { fn } from "@/util/fn" -import type { AuthOuathResult, Hooks } from "@opencode-ai/plugin" +import type { AuthOuathResult, Hooks } from "@kilocode/plugin" import { NamedError } from "@opencode-ai/util/error" import { Auth } from "@/auth" diff --git a/packages/opencode/src/share/share-next.ts b/packages/opencode/src/share/share-next.ts index c36616b7ef9..9bff9246845 100644 --- a/packages/opencode/src/share/share-next.ts +++ b/packages/opencode/src/share/share-next.ts @@ -7,7 +7,7 @@ import { MessageV2 } from "@/session/message-v2" import { Database, eq } from "@/storage/db" import { SessionShareTable } from "./share.sql" import { Log } from "@/util/log" -import type * as SDK from "@opencode-ai/sdk/v2" +import type * as SDK from "@kilocode/sdk/v2" export namespace ShareNext { const log = Log.create({ service: "share-next" }) diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index c6d7fbc1e4b..539acbd2946 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -17,7 +17,7 @@ import { Tool } from "./tool" import { Instance } from "../project/instance" import { Config } from "../config/config" import path from "path" -import { type ToolContext as PluginToolContext, type ToolDefinition } from "@opencode-ai/plugin" +import { type ToolContext as PluginToolContext, type ToolDefinition } from "@kilocode/plugin" import z from "zod" import { Plugin } from "../plugin" import { WebSearchTool } from "./websearch" diff --git a/packages/opencode/test/acp/event-subscription.test.ts b/packages/opencode/test/acp/event-subscription.test.ts index 1abf578281d..543cc02b508 100644 --- a/packages/opencode/test/acp/event-subscription.test.ts +++ b/packages/opencode/test/acp/event-subscription.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from "bun:test" import { ACP } from "../../src/acp/agent" import type { AgentSideConnection } from "@agentclientprotocol/sdk" -import type { Event, EventMessagePartUpdated, ToolStatePending, ToolStateRunning } from "@opencode-ai/sdk/v2" +import type { Event, EventMessagePartUpdated, ToolStatePending, ToolStateRunning } from "@kilocode/sdk/v2" import { Instance } from "../../src/project/instance" import { tmpdir } from "../fixture/fixture" diff --git a/packages/opencode/test/cli/plugin-auth-picker.test.ts b/packages/opencode/test/cli/plugin-auth-picker.test.ts index 3ce9094e92c..30a9843deee 100644 --- a/packages/opencode/test/cli/plugin-auth-picker.test.ts +++ b/packages/opencode/test/cli/plugin-auth-picker.test.ts @@ -1,6 +1,6 @@ import { test, expect, describe } from "bun:test" import { resolvePluginProviders } from "../../src/cli/cmd/auth" -import type { Hooks } from "@opencode-ai/plugin" +import type { Hooks } from "@kilocode/plugin" function hookWithAuth(provider: string): Hooks { return { diff --git a/packages/opencode/test/cli/tui/transcript.test.ts b/packages/opencode/test/cli/tui/transcript.test.ts index 7a5fa6b8f1c..4ebb8a7393b 100644 --- a/packages/opencode/test/cli/tui/transcript.test.ts +++ b/packages/opencode/test/cli/tui/transcript.test.ts @@ -5,7 +5,7 @@ import { formatPart, formatTranscript, } from "../../../src/cli/cmd/tui/util/transcript" -import type { AssistantMessage, Part, UserMessage } from "@opencode-ai/sdk/v2" +import type { AssistantMessage, Part, UserMessage } from "@kilocode/sdk/v2" describe("transcript", () => { describe("formatAssistantHeader", () => { diff --git a/packages/opencode/test/tool/registry.test.ts b/packages/opencode/test/tool/registry.test.ts index 706a9e12caf..0f7ffcec4ac 100644 --- a/packages/opencode/test/tool/registry.test.ts +++ b/packages/opencode/test/tool/registry.test.ts @@ -88,7 +88,7 @@ describe("tool.registry", () => { JSON.stringify({ name: "custom-tools", dependencies: { - "@opencode-ai/plugin": "^0.0.0", + "@kilocode/plugin": "^0.0.0", cowsay: "^1.6.0", }, }), diff --git a/packages/plugin/package.json b/packages/plugin/package.json index e476c41e2fb..afc4aaac3d5 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", - "name": "@opencode-ai/plugin", - "version": "1.2.15", + "name": "@kilocode/plugin", + "version": "7.0.30", "type": "module", "license": "MIT", "scripts": { @@ -16,7 +16,7 @@ "dist" ], "dependencies": { - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "zod": "catalog:" }, "devDependencies": { @@ -24,5 +24,6 @@ "@types/node": "catalog:", "typescript": "catalog:", "@typescript/native-preview": "catalog:" - } + }, + "peerDependencies": {} } diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 76370d1d5a7..b189cb1d0d3 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -10,7 +10,7 @@ import type { Part, Auth, Config, -} from "@opencode-ai/sdk" +} from "@kilocode/sdk" import type { BunShell } from "./shell" import { type ToolDefinition } from "./tool" diff --git a/packages/script/package.json b/packages/script/package.json index 45de3bcb99f..9484f1ba285 100644 --- a/packages/script/package.json +++ b/packages/script/package.json @@ -7,5 +7,8 @@ }, "exports": { ".": "./src/index.ts" - } + }, + "version": "7.0.30", + "dependencies": {}, + "peerDependencies": {} } diff --git a/packages/sdk/js/example/example.ts b/packages/sdk/js/example/example.ts index 42838a82a7e..3aa144f2ca8 100644 --- a/packages/sdk/js/example/example.ts +++ b/packages/sdk/js/example/example.ts @@ -1,4 +1,4 @@ -import { createOpencodeClient, createOpencodeServer } from "@opencode-ai/sdk" +import { createOpencodeClient, createOpencodeServer } from "@kilocode/sdk" import { pathToFileURL } from "bun" const server = await createOpencodeServer() diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index ffbdf219824..b77b67fa14e 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", - "name": "@opencode-ai/sdk", - "version": "1.2.15", + "name": "@kilocode/sdk", + "version": "7.0.30", "type": "module", "license": "MIT", "scripts": { @@ -39,5 +39,6 @@ "dependencies": {}, "publishConfig": { "directory": "dist" - } + }, + "peerDependencies": {} } diff --git a/packages/slack/package.json b/packages/slack/package.json index 72ffe20d5e3..985b862054e 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.2.15", + "version": "7.0.30", "type": "module", "license": "MIT", "scripts": { @@ -8,7 +8,7 @@ "typecheck": "tsgo --noEmit" }, "dependencies": { - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "@slack/bolt": "^3.17.1" }, "devDependencies": { diff --git a/packages/slack/src/index.ts b/packages/slack/src/index.ts index d07e3dfb416..20602b06994 100644 --- a/packages/slack/src/index.ts +++ b/packages/slack/src/index.ts @@ -1,5 +1,5 @@ import { App } from "@slack/bolt" -import { createOpencode, type ToolPart } from "@opencode-ai/sdk" +import { createOpencode, type ToolPart } from "@kilocode/sdk" const app = new App({ token: process.env.SLACK_BOT_TOKEN, diff --git a/packages/ui/package.json b/packages/ui/package.json index 0cdccdc54cc..58393d7fb36 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.2.15", + "version": "7.0.30", "type": "module", "license": "MIT", "exports": { @@ -41,7 +41,7 @@ }, "dependencies": { "@kobalte/core": "catalog:", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "@opencode-ai/util": "workspace:*", "@pierre/diffs": "catalog:", "@shikijs/transformers": "3.9.2", diff --git a/packages/ui/src/components/favicon.tsx b/packages/ui/src/components/favicon.tsx index 94cc82489fd..b9f15ac5076 100644 --- a/packages/ui/src/components/favicon.tsx +++ b/packages/ui/src/components/favicon.tsx @@ -7,7 +7,7 @@ export const Favicon = () => { - + ) } diff --git a/packages/ui/src/components/message-nav.tsx b/packages/ui/src/components/message-nav.tsx index d151633faab..5941fd0d3a7 100644 --- a/packages/ui/src/components/message-nav.tsx +++ b/packages/ui/src/components/message-nav.tsx @@ -1,4 +1,4 @@ -import { UserMessage } from "@opencode-ai/sdk/v2" +import { UserMessage } from "@kilocode/sdk/v2" import { ComponentProps, For, Match, Show, splitProps, Switch } from "solid-js" import { DiffChanges } from "./diff-changes" import { Tooltip } from "@kobalte/core/tooltip" diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 8fbad45bd8a..b25a10dfd10 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -25,7 +25,7 @@ import { Todo, QuestionAnswer, QuestionInfo, -} from "@opencode-ai/sdk/v2" +} from "@kilocode/sdk/v2" import { useData } from "../context" import { useDiffComponent } from "../context/diff" import { useCodeComponent } from "../context/code" diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx index 7f737032e78..7fbeddb9a1b 100644 --- a/packages/ui/src/components/session-review.tsx +++ b/packages/ui/src/components/session-review.tsx @@ -14,7 +14,7 @@ import { getDirectory, getFilename } from "@opencode-ai/util/path" import { checksum } from "@opencode-ai/util/encode" import { createEffect, createMemo, createSignal, For, Match, Show, Switch, type JSX } from "solid-js" import { createStore } from "solid-js/store" -import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2" +import { type FileContent, type FileDiff } from "@kilocode/sdk/v2" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { type SelectedLineRange } from "@pierre/diffs" import { Dynamic } from "solid-js/web" diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index 0eceb754c81..221fb115cb5 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -1,4 +1,4 @@ -import { AssistantMessage, type FileDiff, Message as MessageType, Part as PartType } from "@opencode-ai/sdk/v2/client" +import { AssistantMessage, type FileDiff, Message as MessageType, Part as PartType } from "@kilocode/sdk/v2/client" import { useData } from "../context" import { useDiffComponent } from "../context/diff" diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx index e116199eb23..6ccb248c218 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/ui/src/context/data.tsx @@ -1,4 +1,4 @@ -import type { Message, Session, Part, FileDiff, SessionStatus, ProviderListResponse } from "@opencode-ai/sdk/v2" +import type { Message, Session, Part, FileDiff, SessionStatus, ProviderListResponse } from "@kilocode/sdk/v2" import { createSimpleContext } from "./helper" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" diff --git a/packages/ui/src/context/marked.tsx b/packages/ui/src/context/marked.tsx index c5ff3c767f6..1ea1999f8de 100644 --- a/packages/ui/src/context/marked.tsx +++ b/packages/ui/src/context/marked.tsx @@ -6,9 +6,9 @@ import { bundledLanguages, type BundledLanguage } from "shiki" import { createSimpleContext } from "./helper" import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/diffs" -registerCustomTheme("OpenCode", () => { +registerCustomTheme("Kilo", () => { return Promise.resolve({ - name: "OpenCode", + name: "Kilo", colors: { "editor.background": "var(--color-background-stronger)", "editor.foreground": "var(--text-base)", @@ -428,7 +428,7 @@ async function highlightCodeBlocks(html: string): Promise { const matches = [...html.matchAll(codeBlockRegex)] if (matches.length === 0) return html - const highlighter = await getSharedHighlighter({ themes: ["OpenCode"], langs: [] }) + const highlighter = await getSharedHighlighter({ themes: ["Kilo"], langs: [] }) let result = html for (const match of matches) { @@ -450,7 +450,7 @@ async function highlightCodeBlocks(html: string): Promise { const highlighted = highlighter.codeToHtml(code, { lang: language, - theme: "OpenCode", + theme: "Kilo", tabindex: false, }) result = result.replace(fullMatch, () => highlighted) @@ -479,7 +479,7 @@ export const { use: useMarked, provider: MarkedProvider } = createSimpleContext( }), markedShiki({ async highlight(code, lang) { - const highlighter = await getSharedHighlighter({ themes: ["OpenCode"], langs: [] }) + const highlighter = await getSharedHighlighter({ themes: ["Kilo"], langs: [] }) if (!(lang in bundledLanguages)) { lang = "text" } @@ -488,7 +488,7 @@ export const { use: useMarked, provider: MarkedProvider } = createSimpleContext( } return highlighter.codeToHtml(code, { lang: lang || "text", - theme: "OpenCode", + theme: "Kilo", tabindex: false, }) }, diff --git a/packages/util/package.json b/packages/util/package.json index 36a235639ee..7fdb52470b0 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.2.15", + "version": "7.0.30", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index daf2ad3480f..48aa0d55a62 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.2.15", + "version": "7.0.30", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/script/changelog.ts b/script/changelog.ts index 5fc30a228bf..f291091997a 100755 --- a/script/changelog.ts +++ b/script/changelog.ts @@ -1,7 +1,7 @@ #!/usr/bin/env bun import { $ } from "bun" -import { createOpencode } from "@opencode-ai/sdk/v2" +import { createOpencode } from "@kilocode/sdk/v2" import { parseArgs } from "util" import { Script } from "@opencode-ai/script" @@ -12,7 +12,7 @@ type Release = { } export async function getLatestRelease(skip?: string) { - const data = await fetch("https://api.github.com/repos/anomalyco/opencode/releases?per_page=100").then((res) => { + const data = await fetch("https://api.github.com/repos/Kilo-Org/kilocode/releases?per_page=100").then((res) => { if (!res.ok) throw new Error(res.statusText) return res.json() }) @@ -43,7 +43,7 @@ export async function getCommits(from: string, to: string): Promise { // Get commit data with GitHub usernames from the API const compare = - await $`gh api "/repos/anomalyco/opencode/compare/${fromRef}...${toRef}" --jq '.commits[] | {sha: .sha, login: .author.login, message: .commit.message}'`.text() + await $`gh api "/repos/Kilo-Org/kilocode/compare/${fromRef}...${toRef}" --jq '.commits[] | {sha: .sha, login: .author.login, message: .commit.message}'`.text() const commitData = new Map() for (const line of compare.split("\n").filter(Boolean)) { @@ -201,7 +201,7 @@ export async function getContributors(from: string, to: string) { const fromRef = from.startsWith("v") ? from : `v${from}` const toRef = to === "HEAD" ? to : to.startsWith("v") ? to : `v${to}` const compare = - await $`gh api "/repos/anomalyco/opencode/compare/${fromRef}...${toRef}" --jq '.commits[] | {login: .author.login, message: .commit.message}'`.text() + await $`gh api "/repos/Kilo-Org/kilocode/compare/${fromRef}...${toRef}" --jq '.commits[] | {login: .author.login, message: .commit.message}'`.text() const contributors = new Map>() for (const line of compare.split("\n").filter(Boolean)) { diff --git a/script/duplicate-pr.ts b/script/duplicate-pr.ts index b77737c1d41..04f51da5d4d 100755 --- a/script/duplicate-pr.ts +++ b/script/duplicate-pr.ts @@ -2,7 +2,7 @@ import path from "path" import { pathToFileURL } from "bun" -import { createOpencode } from "@opencode-ai/sdk" +import { createOpencode } from "@kilocode/sdk" import { parseArgs } from "util" async function main() { diff --git a/script/stats.ts b/script/stats.ts index 318b590af7c..96101fd4ccb 100755 --- a/script/stats.ts +++ b/script/stats.ts @@ -73,7 +73,7 @@ async function fetchReleases(): Promise { const per = 100 while (true) { - const url = `https://api.github.com/repos/anomalyco/opencode/releases?page=${page}&per_page=${per}` + const url = `https://api.github.com/repos/Kilo-Org/kilocode/releases?page=${page}&per_page=${per}` const response = await fetch(url) if (!response.ok) { @@ -188,7 +188,7 @@ async function save(githubTotal: number, npmDownloads: number) { ) } -console.log("Fetching GitHub releases for anomalyco/opencode...\n") +console.log("Fetching GitHub releases for Kilo-Org/kilocode...\n") const releases = await fetchReleases() console.log(`\nFetched ${releases.length} releases total\n`) diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index a041b65223d..089281799de 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.2.15", + "version": "7.0.30", "publisher": "sst-dev", "repository": { "type": "git", From 223098ccaf80e7e7df7b0b8378e7a75b219b74e1 Mon Sep 17 00:00:00 2001 From: Kevin van Dijk Date: Thu, 26 Feb 2026 14:49:25 +0100 Subject: [PATCH 18/23] Rename for Kilo --- packages/opencode/src/config/migrate-tui-config.ts | 14 ++++++++------ packages/opencode/src/config/tui.ts | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/opencode/src/config/migrate-tui-config.ts b/packages/opencode/src/config/migrate-tui-config.ts index b426e4fbd10..30d7affb2f6 100644 --- a/packages/opencode/src/config/migrate-tui-config.ts +++ b/packages/opencode/src/config/migrate-tui-config.ts @@ -134,16 +134,17 @@ async function backupAndStripLegacy(file: string, source: string) { }) } +// kilocode_change start: use kilo directory everywhere async function opencodeFiles(input: { directories: string[]; managed: string }) { - const project = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + const project = Flag.KILO_DISABLE_PROJECT_CONFIG ? [] - : await ConfigPaths.projectFiles("opencode", Instance.directory, Instance.worktree) - const files = [...project, ...ConfigPaths.fileInDirectory(Global.Path.config, "opencode")] + : await ConfigPaths.projectFiles("kilo", Instance.directory, Instance.worktree) + const files = [...project, ...ConfigPaths.fileInDirectory(Global.Path.config, "kilo")] for (const dir of unique(input.directories)) { - files.push(...ConfigPaths.fileInDirectory(dir, "opencode")) + files.push(...ConfigPaths.fileInDirectory(dir, "kilo")) } - if (Flag.OPENCODE_CONFIG) files.push(Flag.OPENCODE_CONFIG) - files.push(...ConfigPaths.fileInDirectory(input.managed, "opencode")) + if (Flag.KILO_CONFIG) files.push(Flag.KILO_CONFIG) + files.push(...ConfigPaths.fileInDirectory(input.managed, "kilo")) const existing = await Promise.all( unique(files).map(async (file) => { @@ -153,3 +154,4 @@ async function opencodeFiles(input: { directories: string[]; managed: string }) ) return existing.filter((file): file is string => !!file) } +// kilocode_change end diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts index f0964f63b35..a00a514212e 100644 --- a/packages/opencode/src/config/tui.ts +++ b/packages/opencode/src/config/tui.ts @@ -22,11 +22,11 @@ export namespace TuiConfig { } function customPath() { - return Flag.OPENCODE_TUI_CONFIG + return Flag.KILO_TUI_CONFIG } const state = Instance.state(async () => { - let projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + let projectFiles = Flag.KILO_DISABLE_PROJECT_CONFIG ? [] : await ConfigPaths.projectFiles("tui", Instance.directory, Instance.worktree) const directories = await ConfigPaths.directories(Instance.directory, Instance.worktree) @@ -34,7 +34,7 @@ export namespace TuiConfig { const managed = Config.managedConfigDir() await migrateTuiConfig({ directories, custom, managed }) // Re-compute after migration since migrateTuiConfig may have created new tui.json files - projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG + projectFiles = Flag.KILO_DISABLE_PROJECT_CONFIG ? [] : await ConfigPaths.projectFiles("tui", Instance.directory, Instance.worktree) @@ -54,7 +54,7 @@ export namespace TuiConfig { } for (const dir of unique(directories)) { - if (!dir.endsWith(".opencode") && dir !== Flag.OPENCODE_CONFIG_DIR) continue + if (!dir.endsWith(".kilo") && dir !== Flag.KILO_CONFIG_DIR) continue // kilocode_change for (const file of ConfigPaths.fileInDirectory(dir, "tui")) { result = mergeInfo(result, await loadFile(file)) } From ecd9c898383f511690340411f4af4fa03592b4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Thu, 26 Feb 2026 15:41:03 -0300 Subject: [PATCH 19/23] fix: e2e test --- .../e2e/session/session-composer-dock.spec.ts | 2 + packages/opencode/src/session/index.ts | 89 ++++++++++++------- packages/opencode/src/session/prompt.ts | 1 + packages/opencode/src/session/summary.ts | 5 +- 4 files changed, 63 insertions(+), 34 deletions(-) diff --git a/packages/app/e2e/session/session-composer-dock.spec.ts b/packages/app/e2e/session/session-composer-dock.spec.ts index e9cfc03e485..1c057049af4 100644 --- a/packages/app/e2e/session/session-composer-dock.spec.ts +++ b/packages/app/e2e/session/session-composer-dock.spec.ts @@ -144,6 +144,7 @@ test("blocked question flow unblocks after submit", async ({ page, sdk, gotoSess { header: "Need input", question: "Pick one option", + multiple: true, // kilocode_change options: [ { label: "Continue", description: "Continue now" }, { label: "Stop", description: "Stop here" }, @@ -269,6 +270,7 @@ test("child session question request blocks parent dock and unblocks after submi { header: "Child input", question: "Pick one child option", + multiple: true, // kilocode_change options: [ { label: "Continue", description: "Continue child" }, { label: "Stop", description: "Stop child" }, diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index ed791555148..69b61e1b882 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -688,6 +688,9 @@ export namespace Session { const { KiloSessions } = await import("@/kilo-sessions/kilo-sessions") await KiloSessions.remove(sessionID).catch(() => {}) // kilocode_change platformOverrides.delete(sessionID) // kilocode_change - clean up platform override + // kilocode_change start - cancel running processor before deleting to avoid FK constraint errors + SessionPrompt.cancel(sessionID) + // kilocode_change end // CASCADE delete handles messages and parts automatically Database.use((db) => { db.delete(SessionTable).where(eq(SessionTable.id, sessionID)).run() @@ -705,22 +708,32 @@ export namespace Session { export const updateMessage = fn(MessageV2.Info, async (msg) => { const time_created = msg.time.created const { id, sessionID, ...data } = msg - Database.use((db) => { - db.insert(MessageTable) - .values({ - id, - session_id: sessionID, - time_created, - data, - }) - .onConflictDoUpdate({ target: MessageTable.id, set: { data } }) - .run() - Database.effect(() => - Bus.publish(MessageV2.Event.Updated, { - info: msg, - }), - ) - }) + // kilocode_change start - ignore FK errors when session was deleted while processor was still running + try { + Database.use((db) => { + db.insert(MessageTable) + .values({ + id, + session_id: sessionID, + time_created, + data, + }) + .onConflictDoUpdate({ target: MessageTable.id, set: { data } }) + .run() + Database.effect(() => + Bus.publish(MessageV2.Event.Updated, { + info: msg, + }), + ) + }) + } catch (e: any) { + if (e?.code === "SQLITE_CONSTRAINT_FOREIGNKEY") { + log.warn("skipping message update for deleted session", { id: msg.id, sessionID: msg.sessionID }) + } else { + throw e + } + } + // kilocode_change end return msg }) @@ -774,23 +787,33 @@ export namespace Session { export const updatePart = fn(UpdatePartInput, async (part) => { const { id, messageID, sessionID, ...data } = part const time = Date.now() - Database.use((db) => { - db.insert(PartTable) - .values({ - id, - message_id: messageID, - session_id: sessionID, - time_created: time, - data, - }) - .onConflictDoUpdate({ target: PartTable.id, set: { data } }) - .run() - Database.effect(() => - Bus.publish(MessageV2.Event.PartUpdated, { - part, - }), - ) - }) + // kilocode_change start - ignore FK errors when session was deleted while processor was still running + try { + Database.use((db) => { + db.insert(PartTable) + .values({ + id, + message_id: messageID, + session_id: sessionID, + time_created: time, + data, + }) + .onConflictDoUpdate({ target: PartTable.id, set: { data } }) + .run() + Database.effect(() => + Bus.publish(MessageV2.Event.PartUpdated, { + part, + }), + ) + }) + } catch (e: any) { + if (e?.code === "SQLITE_CONSTRAINT_FOREIGNKEY") { + log.warn("skipping part update for deleted session", { id: part.id, sessionID: part.sessionID }) + } else { + throw e + } + } + // kilocode_change end return part }) diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index ca5c8a2c996..b3dbde6f37c 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -768,6 +768,7 @@ export namespace SessionPrompt { SessionCompaction.prune({ sessionID }) // kilocode_change start finished = true + abort.throwIfAborted() // kilocode_change end for await (const item of MessageV2.stream(sessionID)) { if (item.info.role === "user") continue diff --git a/packages/opencode/src/session/summary.ts b/packages/opencode/src/session/summary.ts index 349336ba788..f724067f665 100644 --- a/packages/opencode/src/session/summary.ts +++ b/packages/opencode/src/session/summary.ts @@ -101,7 +101,10 @@ export namespace SessionSummary { const messages = input.messages.filter( (m) => m.info.id === input.messageID || (m.info.role === "assistant" && m.info.parentID === input.messageID), ) - const msgWithParts = messages.find((m) => m.info.id === input.messageID)! + // kilocode_change start - session may have been deleted before summarization completed + const msgWithParts = messages.find((m) => m.info.id === input.messageID) + if (!msgWithParts) return + // kilocode_change end const userMsg = msgWithParts.info as MessageV2.User const diffs = await computeDiff({ messages }) userMsg.summary = { From 653639d737b5bac5c26ebc191128781f5f7932f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Thu, 26 Feb 2026 16:03:54 -0300 Subject: [PATCH 20/23] fix: win32 tests --- packages/app/e2e/session/session-composer-dock.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/app/e2e/session/session-composer-dock.spec.ts b/packages/app/e2e/session/session-composer-dock.spec.ts index 1c057049af4..1151d1a298f 100644 --- a/packages/app/e2e/session/session-composer-dock.spec.ts +++ b/packages/app/e2e/session/session-composer-dock.spec.ts @@ -134,6 +134,7 @@ test("default dock shows prompt input", async ({ page, sdk, gotoSession }) => { }) test("blocked question flow unblocks after submit", async ({ page, sdk, gotoSession }) => { + test.skip(process.platform === "win32", "Skipping on Windows due interaction issues") // kilocode_change await withDockSession(sdk, "e2e composer dock question", async (session) => { await withDockSeed(sdk, session.id, async () => { await gotoSession(session.id) @@ -251,6 +252,7 @@ test("child session question request blocks parent dock and unblocks after submi sdk, gotoSession, }) => { + test.skip(process.platform === "win32", "Skipping on Windows due interaction issues") // kilocode_change await withDockSession(sdk, "e2e composer dock child question parent", async (session) => { await gotoSession(session.id) @@ -377,6 +379,7 @@ test("todo dock transitions and collapse behavior", async ({ page, sdk, gotoSess }) test("keyboard focus stays off prompt while blocked", async ({ page, sdk, gotoSession }) => { + test.skip(process.platform === "win32", "Skipping on Windows due interaction issues") // kilocode_change await withDockSession(sdk, "e2e composer dock keyboard", async (session) => { await withDockSeed(sdk, session.id, async () => { await gotoSession(session.id) From 057fdffa898dba77a193714fea11892ced605c08 Mon Sep 17 00:00:00 2001 From: Kevin van Dijk Date: Mon, 2 Mar 2026 22:02:25 +0100 Subject: [PATCH 21/23] Include opencode directory --- packages/opencode/src/config/tui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts index a00a514212e..f1ac45b8e51 100644 --- a/packages/opencode/src/config/tui.ts +++ b/packages/opencode/src/config/tui.ts @@ -54,7 +54,7 @@ export namespace TuiConfig { } for (const dir of unique(directories)) { - if (!dir.endsWith(".kilo") && dir !== Flag.KILO_CONFIG_DIR) continue // kilocode_change + if (!dir.endsWith(".kilo") || (dir.endsWith(".opencode") && dir !== Flag.KILO_CONFIG_DIR)) continue // kilocode_change for (const file of ConfigPaths.fileInDirectory(dir, "tui")) { result = mergeInfo(result, await loadFile(file)) } From 2146e6461104c3acdeb7adfba9d42addbe368048 Mon Sep 17 00:00:00 2001 From: Kevin van Dijk Date: Mon, 2 Mar 2026 22:16:53 +0100 Subject: [PATCH 22/23] Update naming --- packages/opencode/test/config/tui.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/opencode/test/config/tui.test.ts b/packages/opencode/test/config/tui.test.ts index f9de5b041b4..506af45888c 100644 --- a/packages/opencode/test/config/tui.test.ts +++ b/packages/opencode/test/config/tui.test.ts @@ -7,11 +7,11 @@ import { TuiConfig } from "../../src/config/tui" import { Global } from "../../src/global" import { Filesystem } from "../../src/util/filesystem" -const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR! +const managedConfigDir = process.env.KILO_TEST_MANAGED_CONFIG_DIR! afterEach(async () => { - delete process.env.OPENCODE_CONFIG - delete process.env.OPENCODE_TUI_CONFIG + delete process.env.KILO_CONFIG + delete process.env.KILO_TUI_CONFIG await fs.rm(path.join(Global.Path.config, "tui.json"), { force: true }).catch(() => {}) await fs.rm(path.join(Global.Path.config, "tui.jsonc"), { force: true }).catch(() => {}) await fs.rm(managedConfigDir, { force: true, recursive: true }).catch(() => {}) @@ -322,13 +322,13 @@ test("top-level keys in tui.json take precedence over nested tui key", async () }) }) -test("project config takes precedence over OPENCODE_TUI_CONFIG (matches OPENCODE_CONFIG)", async () => { +test("project config takes precedence over KILO_TUI_CONFIG (matches KILO_CONFIG)", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ theme: "project", diff_style: "auto" })) const custom = path.join(dir, "custom-tui.json") await Bun.write(custom, JSON.stringify({ theme: "custom", diff_style: "stacked" })) - process.env.OPENCODE_TUI_CONFIG = custom + process.env.KILO_TUI_CONFIG = custom }, }) @@ -362,12 +362,12 @@ test("merges keybind overrides across precedence layers", async () => { }) }) -test("OPENCODE_TUI_CONFIG provides settings when no project config exists", async () => { +test("KILO_TUI_CONFIG provides settings when no project config exists", async () => { await using tmp = await tmpdir({ init: async (dir) => { const custom = path.join(dir, "custom-tui.json") await Bun.write(custom, JSON.stringify({ theme: "from-env", diff_style: "stacked" })) - process.env.OPENCODE_TUI_CONFIG = custom + process.env.KILO_TUI_CONFIG = custom }, }) @@ -381,14 +381,14 @@ test("OPENCODE_TUI_CONFIG provides settings when no project config exists", asyn }) }) -test("does not derive tui path from OPENCODE_CONFIG", async () => { +test("does not derive tui path from KILO_CONFIG", async () => { await using tmp = await tmpdir({ init: async (dir) => { const customDir = path.join(dir, "custom") await fs.mkdir(customDir, { recursive: true }) await Bun.write(path.join(customDir, "opencode.json"), JSON.stringify({ model: "test/model" })) await Bun.write(path.join(customDir, "tui.json"), JSON.stringify({ theme: "should-not-load" })) - process.env.OPENCODE_CONFIG = path.join(customDir, "opencode.json") + process.env.KILO_CONFIG = path.join(customDir, "opencode.json") }, }) From 36e6b930912c55e5f92e734ffb66b971a25f08f4 Mon Sep 17 00:00:00 2001 From: Kevin van Dijk Date: Mon, 2 Mar 2026 22:22:43 +0100 Subject: [PATCH 23/23] Update packages/opencode/src/config/tui.ts Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com> --- packages/opencode/src/config/tui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts index f1ac45b8e51..afcd3e600dd 100644 --- a/packages/opencode/src/config/tui.ts +++ b/packages/opencode/src/config/tui.ts @@ -54,7 +54,7 @@ export namespace TuiConfig { } for (const dir of unique(directories)) { - if (!dir.endsWith(".kilo") || (dir.endsWith(".opencode") && dir !== Flag.KILO_CONFIG_DIR)) continue // kilocode_change + if (!dir.endsWith(".kilo") && !dir.endsWith(".opencode") && dir !== Flag.KILO_CONFIG_DIR) continue // kilocode_change for (const file of ConfigPaths.fileInDirectory(dir, "tui")) { result = mergeInfo(result, await loadFile(file)) }