Decouple bundled UI from runtime API and add remote instance tooling (#1228)

Add a packaged-client runtime boundary so the shared UI can talk to local,
desktop, remote, and VS Code runtimes through the right transport instead of
assuming one same-origin web server.

Centralize OpenChamber-owned API access behind RuntimeAPIs, runtimeFetch, and
runtime URL helpers, while keeping official OpenCode traffic on the SDK path.
Support runtime switching, remote host selection, desktop client credentials,
and headless connection links for pairing packaged clients with remote
OpenChamber servers.

Harden the new auth model by moving long-lived client tokens out of browser
URLs, introducing short-lived scoped URL tokens for browser-owned transports,
restricting URL-token access to explicit readable/realtime routes, and making
client-token management session-scoped or self-scoped as appropriate.

Update browser-owned assets and preview proxy flows to work with the split
runtime model, including authenticated project icons, preview token propagation,
CSP-safe preview bridge injection, and preview proxy auth that survives
short-lived URL-token expiry.

Tighten Electron security boundaries for packaged clients by gating privileged
preload state to trusted origins and requiring explicit confirmation before
connect deep-links import or switch remote runtimes.

Also refresh agent guidance and project skills so future runtime/API, auth,
preview, UI, CLI, settings, locale, and drag-to-reorder work follows the new
architecture.
This commit is contained in:
Bohdan Triapitsyn
2026-06-02 00:43:05 +03:00
committed by GitHub
parent a4314c189b
commit 2031e3b4a8
282 changed files with 16524 additions and 4259 deletions
+101
View File
@@ -27,6 +27,107 @@ export const dict: Record<I18nKey, string> = {
'layout.mainTab.files': '檔案',
'layout.mainTab.terminal': '終端機',
'layout.mainTab.context': '上下文',
'mobile.nav.aria': '行動導覽',
'mobile.nav.changes': '變更',
'mobile.nav.settings': '設定',
'mobile.surface.closeAria': '關閉',
'mobile.header.openMenuAria': '開啟選單',
'mobile.menu.titleAria': '工作區工具',
'mobile.menu.files': '檔案',
'mobile.menu.changes': '變更',
'mobile.menu.settings': '設定',
'mobile.sessions.newChatCta': '在 {project} 中新增聊天',
'mobile.sessions.dateGroup.today': '今天',
'mobile.sessions.dateGroup.yesterday': '昨天',
'mobile.sessions.dateGroup.thisWeek': '本週稍早',
'mobile.sessions.dateGroup.older': '更早',
'mobile.sessions.section.worktrees': '工作樹',
'mobile.sessions.section.otherProjects': '切換專案',
'mobile.sessions.section.projects': '專案',
'mobile.sessions.empty.noProjectsTitle': '尚無專案',
'mobile.sessions.empty.noProjectsDescription': '新增專案即可開始與程式碼聊天。',
'mobile.sessions.empty.noSessionsTitle': '尚無會話',
'mobile.sessions.empty.noSessionsDescription': '開始第一個聊天後會顯示在這裡。',
'mobile.sessions.empty.searchTitle': '沒有結果',
'mobile.sessions.empty.searchDescription': '請嘗試其他搜尋詞。',
'mobile.sessions.showArchived': '顯示已封存 ({count})',
'mobile.sessions.hideArchived': '隱藏已封存',
'mobile.sessions.activeWorktreeAria': '作用中的工作樹',
'mobile.sessions.activeProjectAria': '作用中的專案',
'mobile.sessions.startNewChat': '開始新聊天',
'mobile.sessions.newChat': '新聊天',
'mobile.sessions.editOrder': '重新排序專案',
'mobile.sessions.doneEditing': '完成',
'mobile.sessions.editOrderHint': '拖曳把手或使用箭頭重新排序專案。點選勾號完成。',
'mobile.sessions.dragHandleAria': '拖曳 {label} 以重新排序',
'mobile.sessions.moveUpAria': '將 {label} 上移',
'mobile.sessions.moveDownAria': '將 {label} 下移',
'mobile.sessions.removeProjectAria': '移除 {label}',
'mobile.sessions.cancelRemoveProjectAria': '取消移除 {label}',
'mobile.sessions.confirmRemoveProject': '刪除',
'mobile.sessions.confirmRemoveProjectAria': '確認移除 {label}',
'mobile.sessions.toast.projectRemoved': '已移除 {label}',
'mobile.sessions.showMore': '再顯示 {count} 個',
'mobile.sessions.search.section.sessions': '會話',
'mobile.sessions.search.section.archived': '已封存',
'mobile.sessions.search.section.projects': '專案',
'mobile.sessions.clearSearchAria': '清除搜尋',
'mobile.header.noProject': '選擇專案',
'mobile.header.activeSession': '作用中會話',
'mobile.header.noSession': '沒有作用中會話',
'mobile.sessions.openSheetAria': '開啟會話與專案',
'mobile.sessions.closeSheetAria': '關閉會話與專案',
'mobile.sessions.sheet.title': '會話',
'mobile.sessions.sheet.description': '切換專案、開啟會話或開始新聊天。',
'mobile.sessions.search.placeholder': '搜尋會話',
'mobile.sessions.empty': '找不到會話。',
'mobile.sessions.unassignedProject': '其他會話',
'mobile.sessions.newSessionAria': '在此專案中開始新會話',
'mobile.sessions.untitled': '未命名會話',
'mobile.sessions.project.sessionsSingle': '1 個會話',
'mobile.sessions.project.sessionsPlural': '{count} 個會話',
'mobile.files.refreshAria': '重新整理檔案',
'mobile.files.backToParentAria': '返回 {name}',
'mobile.files.rootDirectory': '專案檔案',
'mobile.files.search.placeholder': '搜尋檔案',
'mobile.files.search.empty': '找不到檔案。',
'mobile.files.parentDirectory': '上層目錄',
'mobile.files.empty.noDirectory': '選擇專案以瀏覽檔案。',
'mobile.files.empty.directory': '此目錄是空的。',
'mobile.files.error.listFailed': '載入檔案失敗',
'mobile.files.error.readUnavailable': '此執行環境無法使用檔案預覽。',
'mobile.files.file.truncated': '行動版檔案預覽已截斷。',
'mobile.files.copyPathAria': '複製檔案路徑',
'mobile.files.copyContent': '複製內容',
'mobile.files.copyContentAria': '複製檔案內容',
'mobile.files.toast.pathCopied': '路徑已複製',
'mobile.files.toast.contentCopied': '內容已複製',
'mobile.files.toast.copyFailed': '複製失敗',
'mobile.changes.placeholder.title': '變更',
'mobile.changes.placeholder.description': '工作樹檢閱、同步與提交動作會顯示在這裡。',
'mobile.changes.branchLabel': '分支:{branch}',
'mobile.changes.noRemote': '沒有可用的 remote',
'mobile.changes.cleanDescription': '此工作區沒有已變更的檔案。',
'mobile.changes.diffDetail.subtitle': '唯讀 diff',
'mobile.changes.diffDetail.loadFailed': '載入 diff 失敗',
'mobile.changes.diffDetail.missingTitle': '檔案已不再有變更',
'mobile.changes.diffDetail.missingDescription': '返回變更並重新整理清單。',
'mobile.changes.diffDetail.imageUnavailable': '行動版變更尚不支援圖片 diff。',
'mobile.settings.placeholder.title': '設定',
'mobile.settings.placeholder.description': '行動版連線與應用程式設定會顯示在這裡。',
'header.services.remoteUpdate.title': '遠端實例更新',
'header.services.remoteUpdate.checking': '正在檢查更新...',
'header.services.remoteUpdate.upToDate': '此實例已是最新。',
'header.services.remoteUpdate.available': '此實例可更新到版本 {version}。',
'header.services.remoteUpdate.error': '無法檢查遠端實例更新',
'header.services.remoteUpdate.actions.open': '更新',
'desktopHostSwitcher.status.checking': '檢查中',
'desktopHostSwitcher.status.updateRecommended': '建議更新',
'desktopHostSwitcher.status.incompatible': '不相容',
'onboarding.remoteConnection.probe.updateRecommendedMessage': '此實例正在執行不同版本的 OpenChamber。你可以連線;如果功能異常,請更新兩端應用程式。',
'onboarding.remoteConnection.probe.incompatibleMessage': '伺服器正在執行 OpenChamber,但與此應用程式版本不相容。請更新伺服器上的 OpenChamber 後重試。',
'onboarding.desktopRecovery.remoteIncompatible.title': '需要更新伺服器',
'onboarding.desktopRecovery.remoteIncompatible.description': '「{host}」上的 OpenChamber 伺服器與此應用程式版本不相容。請更新伺服器上的 OpenChamber 後重試。',
'layout.rightSidebar.git': 'Git',
'layout.rightSidebar.files': '檔案',
'layout.rightSidebar.context': '上下文',