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:
committed by
GitHub
parent
a4314c189b
commit
2031e3b4a8
@@ -198,19 +198,50 @@ export const settingsDict = {
|
||||
'settings.magicPrompts.sidebar.item.sessionFusion': 'Fusion',
|
||||
'settings.remoteInstances.sidebar.title': '원격 인스턴스',
|
||||
'settings.remoteInstances.sidebar.total': '총 {count}개',
|
||||
'settings.remoteInstances.sidebar.newSshInstanceName': '새 SSH 인스턴스',
|
||||
'settings.remoteInstances.sidebar.actions.addSshInstance': 'SSH 인스턴스 추가',
|
||||
'settings.remoteInstances.sidebar.newSshInstanceName': '새 SSH 연결',
|
||||
'settings.remoteInstances.sidebar.actions.addSshInstance': 'SSH 연결 추가',
|
||||
'settings.remoteInstances.sidebar.actions.connect': '연결',
|
||||
'settings.remoteInstances.sidebar.actions.disconnect': '연결 해제',
|
||||
'settings.remoteInstances.sidebar.actions.retry': '다시 시도',
|
||||
'settings.remoteInstances.sidebar.actions.remove': '제거',
|
||||
'settings.remoteInstances.sidebar.confirm.localPortInUseRetry': '로컬 포트가 이미 사용 중입니다. 임의의 사용 가능한 로컬 포트를 선택해 다시 시도할까요?',
|
||||
'settings.remoteInstances.sidebar.toast.createFailed': 'SSH 인스턴스를 생성하지 못했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.createFailed': 'SSH 연결을 만들지 못했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.retriedWithRandomPort': '임의의 로컬 포트로 다시 시도했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.connectFailed': '인스턴스에 연결하지 못했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.disconnectFailed': '인스턴스 연결을 해제하지 못했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.retryFailed': '연결을 다시 시도하지 못했습니다',
|
||||
'settings.remoteInstances.sidebar.toast.removeFailed': '인스턴스를 제거하지 못했습니다',
|
||||
'settings.remoteInstances.direct.sidebarTitle': '서버 링크',
|
||||
'settings.remoteInstances.direct.sidebarDescription': '링크나 토큰으로 연결',
|
||||
'settings.remoteInstances.direct.title': '다른 OpenChamber 서버',
|
||||
'settings.remoteInstances.direct.description': 'URL로 다른 OpenChamber 서버를 추가합니다. 서버가 이미 실행 중이고 연결 토큰이 있을 때 사용하세요.',
|
||||
'settings.remoteInstances.direct.field.labelPlaceholder': '라벨(선택 사항)',
|
||||
'settings.remoteInstances.direct.field.urlPlaceholder': 'https://host:port',
|
||||
'settings.remoteInstances.direct.field.tokenPlaceholder': '연결 토큰(신뢰할 수 있는 로컬 서버는 선택 사항)',
|
||||
'settings.remoteInstances.direct.note': '연결 토큰은 이 기기에 저장되며 이 앱이 해당 서버에 연결할 때만 사용됩니다.',
|
||||
'settings.remoteInstances.direct.actions.add': '서버 추가',
|
||||
'settings.remoteInstances.direct.import.description': '다른 OpenChamber 서버에서 만든 연결 링크를 붙여넣으세요.',
|
||||
'settings.remoteInstances.direct.import.placeholder': 'openchamber://connect?...',
|
||||
'settings.remoteInstances.direct.import.action': '링크 가져오기',
|
||||
'settings.remoteInstances.direct.error.invalidConnectLink': '잘못된 OpenChamber 연결 링크입니다.',
|
||||
'settings.remoteInstances.direct.state.loading': '서버를 불러오는 중...',
|
||||
'settings.remoteInstances.direct.state.empty': '아직 추가된 다른 서버가 없습니다.',
|
||||
'settings.remoteInstances.clientAuth.title': '이 서버에 연결',
|
||||
'settings.remoteInstances.clientAuth.description': 'OpenChamber Desktop이 이 서버에 연결할 수 있도록 안전한 링크나 토큰을 만듭니다.',
|
||||
'settings.remoteInstances.clientAuth.field.labelPlaceholder': '기기 이름(선택 사항)',
|
||||
'settings.remoteInstances.clientAuth.actions.create': '토큰 만들기',
|
||||
'settings.remoteInstances.clientAuth.actions.pair': '링크 만들기',
|
||||
'settings.remoteInstances.clientAuth.actions.revoke': '해지',
|
||||
'settings.remoteInstances.clientAuth.actions.clearRevoked': '해지된 항목 지우기',
|
||||
'settings.remoteInstances.clientAuth.qrAlt': 'OpenChamber connection QR code',
|
||||
'settings.remoteInstances.clientAuth.pairingUrl': '연결 링크',
|
||||
'settings.remoteInstances.clientAuth.createdToken': '지금 이 토큰을 복사하세요. 보안을 위해 다시 표시되지 않습니다.',
|
||||
'settings.remoteInstances.clientAuth.state.loading': '토큰을 불러오는 중...',
|
||||
'settings.remoteInstances.clientAuth.state.empty': '아직 연결된 기기가 없습니다.',
|
||||
'settings.remoteInstances.clientAuth.state.revoked': '해지됨',
|
||||
'settings.remoteInstances.clientAuth.state.thisDevice': '이 기기',
|
||||
'settings.remoteInstances.clientAuth.lastUsed': '마지막 사용 {date}',
|
||||
'settings.remoteInstances.clientAuth.neverUsed': '사용한 적 없음',
|
||||
'settings.remoteInstances.sidebar.phase.ready': '준비됨',
|
||||
'settings.remoteInstances.sidebar.phase.error': '오류',
|
||||
'settings.remoteInstances.sidebar.phase.reconnect': '재연결',
|
||||
@@ -221,20 +252,20 @@ export const settingsDict = {
|
||||
'settings.remoteInstances.sidebar.phase.connecting': '연결 중',
|
||||
'settings.remoteInstances.sidebar.phase.idle': '대기 중',
|
||||
'settings.remoteInstances.page.section.instance': '인스턴스',
|
||||
'settings.remoteInstances.page.section.instanceDescription': '핵심 SSH 설정입니다.',
|
||||
'settings.remoteInstances.page.section.instanceDescription': '이 연결에 사용할 SSH 명령과 표시 이름을 선택하세요.',
|
||||
'settings.remoteInstances.page.field.mode': '모드',
|
||||
'settings.remoteInstances.page.field.modeHint': 'Managed는 원격에서 OpenChamber를 설치·업데이트하고 시작합니다. External은 이미 실행 중인 서버에 연결합니다.',
|
||||
'settings.remoteInstances.page.field.modeHint': 'OpenChamber가 서버를 대신 시작할지, 이미 실행 중인 서버에 연결할지 선택하세요.',
|
||||
'settings.remoteInstances.page.field.modePlaceholder': '모드 선택',
|
||||
'settings.remoteInstances.page.field.modeManaged': 'Managed(자동 시작)',
|
||||
'settings.remoteInstances.page.field.modeExternal': 'External(이미 실행 중)',
|
||||
'settings.remoteInstances.page.field.modeManaged': '대신 시작하기',
|
||||
'settings.remoteInstances.page.field.modeExternal': '이미 실행 중',
|
||||
'settings.remoteInstances.page.field.preferredRemotePort': '기본 원격 포트',
|
||||
'settings.remoteInstances.page.field.preferredRemotePortHint': '원격 host에서 OpenChamber가 사용할 포트입니다. 비워 두면 런타임이 자동으로 선택합니다.',
|
||||
'settings.remoteInstances.page.field.preferredRemotePortHint': '원격 컴퓨터에서 사용할 포트입니다. 비워 두면 자동으로 선택합니다.',
|
||||
'settings.remoteInstances.page.field.keepServerRunning': '서버 유지',
|
||||
'settings.remoteInstances.page.field.keepServerRunningHint': '활성화하면 연결 해제 후에도 OpenChamber daemon이 원격에서 계속 실행됩니다.',
|
||||
'settings.remoteInstances.page.field.keepServerRunningHint': '연결을 끊은 뒤에도 원격 컴퓨터에서 OpenChamber를 계속 실행합니다.',
|
||||
'settings.remoteInstances.page.field.bindHost': 'Bind host',
|
||||
'settings.remoteInstances.page.field.bindHostHint': '기본 로컬 URL의 네트워크 인터페이스입니다. 로컬 전용 접속에는 127.0.0.1/localhost를 사용하세요.',
|
||||
'settings.remoteInstances.page.field.bindHostHint': '로컬 연결이 대기할 주소입니다. LAN 접근이 필요하지 않으면 127.0.0.1 또는 localhost를 사용하세요.',
|
||||
'settings.remoteInstances.page.field.preferredLocalPort': '기본 로컬 포트',
|
||||
'settings.remoteInstances.page.field.preferredLocalPortHint': '기본 OpenChamber 터널에 사용할 로컬 포트입니다. 자동 선택하려면 비워 두세요.',
|
||||
'settings.remoteInstances.page.field.preferredLocalPortHint': '이 연결에 열 로컬 포트입니다. 비워 두면 자동으로 선택합니다.',
|
||||
'settings.remoteInstances.page.field.forwardType': '포워딩 유형',
|
||||
'settings.remoteInstances.page.field.localHostPlaceholder': '127.0.0.1',
|
||||
'settings.remoteInstances.page.field.remoteHostPlaceholder': '127.0.0.1',
|
||||
@@ -243,7 +274,7 @@ export const settingsDict = {
|
||||
'settings.remoteInstances.page.preview.localSocks5': '(로컬 SOCKS5)',
|
||||
'settings.remoteInstances.page.preview.local': '(로컬)',
|
||||
'settings.remoteInstances.page.preview.remote': '(원격)',
|
||||
'settings.remoteInstances.page.toast.openLocalEndpointFailed': '로컬 엔드포인트를 열지 못했습니다',
|
||||
'settings.remoteInstances.page.toast.openLocalEndpointFailed': '로컬 주소를 열지 못했습니다',
|
||||
'settings.remoteInstances.page.toast.localUrlCopied': '로컬 URL이 복사되었습니다',
|
||||
'settings.remoteInstances.page.actions.copyLocalUrl': '로컬 URL 복사',
|
||||
'settings.remoteInstances.page.actions.open': '열기',
|
||||
@@ -945,26 +976,26 @@ export const settingsDict = {
|
||||
'settings.usage.pace.waitSeparator': ' · 대기 ',
|
||||
'settings.usage.pace.predictionLabel': '예측: ',
|
||||
'settings.remoteInstances.page.title': '원격 인스턴스',
|
||||
'settings.remoteInstances.page.description': 'SSH 연결, 원격 서버, 포워딩 설정을 관리하세요.',
|
||||
'settings.remoteInstances.page.description': 'SSH로 다른 컴퓨터에 연결하고 그곳에서 OpenChamber를 엽니다.',
|
||||
'settings.remoteInstances.page.empty.selectInstance': '설정을 보고 편집할 인스턴스를 선택하세요.',
|
||||
'settings.remoteInstances.page.empty.noExtraForwards': '추가 포트 포워딩이 설정되어 있지 않습니다.',
|
||||
'settings.remoteInstances.page.section.actions': '작업',
|
||||
'settings.remoteInstances.page.section.actionsDescription': '이 인스턴스를 연결, 재연결, 로그 확인 또는 제거합니다.',
|
||||
'settings.remoteInstances.page.section.remoteServer': '원격 서버',
|
||||
'settings.remoteInstances.page.section.remoteServerDescription': '원격 host에서 OpenChamber를 관리하고 시작하는 방식입니다.',
|
||||
'settings.remoteInstances.page.section.mainTunnel': '기본 터널',
|
||||
'settings.remoteInstances.page.section.mainTunnelDescription': '이 원격 인스턴스의 기본 로컬 엔드포인트입니다.',
|
||||
'settings.remoteInstances.page.section.actionsDescription': '연결, 재연결, 로그 보기 또는 이 연결 삭제를 할 수 있습니다.',
|
||||
'settings.remoteInstances.page.section.remoteServer': '원격 컴퓨터의 OpenChamber',
|
||||
'settings.remoteInstances.page.section.remoteServerDescription': 'SSH 연결 후 OpenChamber를 어떻게 실행할지 선택하세요.',
|
||||
'settings.remoteInstances.page.section.mainTunnel': '로컬 접근',
|
||||
'settings.remoteInstances.page.section.mainTunnelDescription': '이 원격 OpenChamber 서버를 열 때 사용할 로컬 주소를 선택하세요.',
|
||||
'settings.remoteInstances.page.section.authentication': '인증',
|
||||
'settings.remoteInstances.page.section.authenticationDescription': 'SSH와 원격 OpenChamber UI를 위한 인증 정보입니다.',
|
||||
'settings.remoteInstances.page.section.portForwards': '포트 포워딩',
|
||||
'settings.remoteInstances.page.section.portForwardsDescription': '기본 터널 외 추가 SSH 포워딩입니다.',
|
||||
'settings.remoteInstances.page.section.portForwardsDescription': '이 SSH 연결을 통해 추가로 사용할 포트를 설정합니다.',
|
||||
'settings.remoteInstances.page.field.sshCommand': 'SSH 명령어',
|
||||
'settings.remoteInstances.page.field.sshCommandPlaceholder': 'ssh user@host',
|
||||
'settings.remoteInstances.page.field.nickname': '별칭',
|
||||
'settings.remoteInstances.page.field.nicknamePlaceholder': '내 원격 host',
|
||||
'settings.remoteInstances.page.field.nicknamePlaceholder': '업무용 노트북',
|
||||
'settings.remoteInstances.page.field.connectionTimeoutSeconds': '연결 시간 초과(초)',
|
||||
'settings.remoteInstances.page.field.installMethod': '설치 방식',
|
||||
'settings.remoteInstances.page.field.installMethodHint': 'Managed 모드에서 OpenChamber를 설치하는 방식입니다.',
|
||||
'settings.remoteInstances.page.field.installMethodHint': '이 앱이 대신 시작할 때 OpenChamber를 원격 컴퓨터에 배치하는 방법입니다.',
|
||||
'settings.remoteInstances.page.field.selectInstallMethodPlaceholder': '설치 방식 선택',
|
||||
'settings.remoteInstances.page.field.installMethodDownloadRelease': '릴리스 다운로드',
|
||||
'settings.remoteInstances.page.field.installMethodUploadBundle': '번들 업로드',
|
||||
@@ -973,14 +1004,14 @@ export const settingsDict = {
|
||||
'settings.remoteInstances.page.field.sshPasswordPlaceholder': 'SSH 비밀번호 입력',
|
||||
'settings.remoteInstances.page.field.uiPasswordOptional': 'UI 비밀번호(선택 사항)',
|
||||
'settings.remoteInstances.page.field.uiPasswordPlaceholder': 'UI 비밀번호 입력',
|
||||
'settings.remoteInstances.page.field.forwardTypeHint': '로컬(-L), 원격(-R), 동적(-D) 포워딩 중 선택하세요.',
|
||||
'settings.remoteInstances.page.field.forwardTypeHint': '이 SSH 연결이 제공할 포트 접근 방식을 선택하세요.',
|
||||
'settings.remoteInstances.page.field.typePlaceholder': '유형',
|
||||
'settings.remoteInstances.page.forwardType.local': '로컬(-L)',
|
||||
'settings.remoteInstances.page.forwardType.remote': '원격(-R)',
|
||||
'settings.remoteInstances.page.forwardType.dynamic': '동적(-D)',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.local': '로컬 트래픽을 원격 대상으로 포워딩합니다.',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.remote': '원격 엔드포인트를 노출하고 로컬 머신으로 다시 포워딩합니다.',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.dynamic': '로컬 SOCKS5 proxy를 SSH로 노출합니다.',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.local': '원격 컴퓨터의 서비스에 연결되는 로컬 포트를 엽니다.',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.remote': '내 컴퓨터로 다시 연결되는 포트를 원격 컴퓨터에 엽니다.',
|
||||
'settings.remoteInstances.page.forwardTypeDescription.dynamic': 'SSH 연결을 통해 로컬 SOCKS 프록시를 엽니다.',
|
||||
'settings.remoteInstances.page.actions.create': '생성',
|
||||
'settings.remoteInstances.page.actions.cancel': '취소',
|
||||
'settings.remoteInstances.page.actions.connecting': '연결 중...',
|
||||
@@ -991,7 +1022,7 @@ export const settingsDict = {
|
||||
'settings.remoteInstances.page.actions.enableForwardAria': '포워딩 활성화',
|
||||
'settings.remoteInstances.page.actions.openLocal': '로컬 열기',
|
||||
'settings.remoteInstances.page.actions.addForward': '포워딩 추가',
|
||||
'settings.remoteInstances.page.import.sectionTitle': 'SSH config에서 가져오기',
|
||||
'settings.remoteInstances.page.import.sectionTitle': '저장된 SSH 호스트',
|
||||
'settings.remoteInstances.page.import.loading': 'SSH host 로딩 중...',
|
||||
'settings.remoteInstances.page.import.noneFound': 'SSH host를 찾을 수 없습니다.',
|
||||
'settings.remoteInstances.page.import.noneAvailable': '가져올 수 있는 SSH host가 없습니다.',
|
||||
@@ -1006,7 +1037,7 @@ export const settingsDict = {
|
||||
'settings.remoteInstances.page.phase.resolvingConfiguration': '설정 확인 중',
|
||||
'settings.remoteInstances.page.phase.checkingAuth': '인증 확인 중',
|
||||
'settings.remoteInstances.page.phase.establishingSsh': 'SSH 연결 설정 중',
|
||||
'settings.remoteInstances.page.phase.probingRemote': '원격 host 확인 중',
|
||||
'settings.remoteInstances.page.phase.probingRemote': '원격 컴퓨터 확인 중',
|
||||
'settings.remoteInstances.page.phase.installingOpenChamber': 'OpenChamber 설치 중',
|
||||
'settings.remoteInstances.page.phase.updatingOpenChamber': 'OpenChamber 업데이트 중',
|
||||
'settings.remoteInstances.page.phase.detectingServer': '서버 감지 중',
|
||||
@@ -1471,6 +1502,9 @@ export const settingsDict = {
|
||||
'settings.voice.page.preview.voiceLine': '안녕하세요! 저는 {voiceName}입니다. 이렇게 들립니다.',
|
||||
'settings.voice.page.preview.customServerLine': '안녕하세요! 사용자 정의 TTS 서버 미리보기입니다.',
|
||||
'settings.openchamber.visual.section.colorMode': '색상 모드',
|
||||
'settings.openchamber.visual.section.mobileLayout': '모바일 레이아웃',
|
||||
'settings.openchamber.visual.option.mobileLayout.default': '기본값',
|
||||
'settings.openchamber.visual.option.mobileLayout.new': '새로움',
|
||||
'settings.openchamber.visual.section.localization': '지역화',
|
||||
'settings.openchamber.visual.section.spacingAndLayout': '간격 및 레이아웃',
|
||||
'settings.openchamber.visual.section.navigation': '내비게이션',
|
||||
|
||||
Reference in New Issue
Block a user