fix: improve OpenCode update and desktop menu behavior
Restart OpenCode after successful updates so the new version is active Open native About menu into the app About dialog Update desktop View menu actions for the new layout
This commit is contained in:
@@ -2414,7 +2414,7 @@ const buildMacMenu = () => {
|
|||||||
{
|
{
|
||||||
label: app.name,
|
label: app.name,
|
||||||
submenu: [
|
submenu: [
|
||||||
{ role: 'about' },
|
{ label: 'About OpenChamber', click: () => dispatchAction('about') },
|
||||||
{
|
{
|
||||||
label: 'Check for Updates',
|
label: 'Check for Updates',
|
||||||
click: () => dispatchCheckForUpdates(),
|
click: () => dispatchCheckForUpdates(),
|
||||||
@@ -2461,10 +2461,12 @@ const buildMacMenu = () => {
|
|||||||
{
|
{
|
||||||
label: 'View',
|
label: 'View',
|
||||||
submenu: [
|
submenu: [
|
||||||
{ label: 'Git', accelerator: 'Cmd+G', click: () => dispatchAction('open-git-tab') },
|
{ label: 'Toggle Right Sidebar', accelerator: 'Cmd+B', click: () => dispatchAction('toggle-right-sidebar') },
|
||||||
{ label: 'Diff', accelerator: 'Cmd+E', click: () => dispatchAction('open-diff-tab') },
|
{ label: 'Open Git Sidebar', accelerator: 'Cmd+Shift+G', click: () => dispatchAction('open-right-sidebar-git') },
|
||||||
{ label: 'Files', click: () => dispatchAction('open-files-tab') },
|
{ label: 'Open Files Sidebar', accelerator: 'Cmd+Shift+F', click: () => dispatchAction('open-right-sidebar-files') },
|
||||||
{ label: 'Terminal', accelerator: 'Cmd+T', click: () => dispatchAction('open-terminal-tab') },
|
{ type: 'separator' },
|
||||||
|
{ label: 'Toggle Terminal Dock', accelerator: 'Cmd+J', click: () => dispatchAction('toggle-terminal') },
|
||||||
|
{ label: 'Toggle Terminal Expanded', accelerator: 'Cmd+Shift+J', click: () => dispatchAction('toggle-terminal-expanded') },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{ label: 'Light Theme', click: () => dispatchAction('theme-light') },
|
{ label: 'Light Theme', click: () => dispatchAction('theme-light') },
|
||||||
{ label: 'Dark Theme', click: () => dispatchAction('theme-dark') },
|
{ label: 'Dark Theme', click: () => dispatchAction('theme-dark') },
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
onOpenChange,
|
onOpenChange,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const showDiagnostics = import.meta.env.DEV;
|
||||||
const [version, setVersion] = React.useState<string | null>(null);
|
const [version, setVersion] = React.useState<string | null>(null);
|
||||||
const [openCodeVersion, setOpenCodeVersion] = React.useState<string | null>(null);
|
const [openCodeVersion, setOpenCodeVersion] = React.useState<string | null>(null);
|
||||||
const [isCopyingDiagnostics, setIsCopyingDiagnostics] = React.useState(false);
|
const [isCopyingDiagnostics, setIsCopyingDiagnostics] = React.useState(false);
|
||||||
@@ -29,6 +30,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
const [isPreparingDiagnostics, setIsPreparingDiagnostics] = React.useState(false);
|
const [isPreparingDiagnostics, setIsPreparingDiagnostics] = React.useState(false);
|
||||||
|
|
||||||
const handleCopyDiagnostics = React.useCallback(async () => {
|
const handleCopyDiagnostics = React.useCallback(async () => {
|
||||||
|
if (!showDiagnostics) return;
|
||||||
if (isCopyingDiagnostics) return;
|
if (isCopyingDiagnostics) return;
|
||||||
setIsCopyingDiagnostics(true);
|
setIsCopyingDiagnostics(true);
|
||||||
setCopiedDiagnostics(false);
|
setCopiedDiagnostics(false);
|
||||||
@@ -55,7 +57,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
} finally {
|
} finally {
|
||||||
setIsCopyingDiagnostics(false);
|
setIsCopyingDiagnostics(false);
|
||||||
}
|
}
|
||||||
}, [diagnosticsReport, isCopyingDiagnostics, t]);
|
}, [diagnosticsReport, isCopyingDiagnostics, showDiagnostics, t]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
@@ -107,7 +109,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!open) {
|
if (!open || !showDiagnostics) {
|
||||||
setDiagnosticsReport(null);
|
setDiagnosticsReport(null);
|
||||||
setIsPreparingDiagnostics(false);
|
setIsPreparingDiagnostics(false);
|
||||||
return;
|
return;
|
||||||
@@ -133,7 +135,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [open]);
|
}, [open, showDiagnostics]);
|
||||||
|
|
||||||
const displayVersion = version;
|
const displayVersion = version;
|
||||||
|
|
||||||
@@ -155,54 +157,58 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col items-center gap-2 pt-2">
|
{showDiagnostics && (
|
||||||
<button
|
<div className="flex flex-col items-center gap-2 pt-2">
|
||||||
onClick={handleCopyDiagnostics}
|
<button
|
||||||
disabled={isCopyingDiagnostics || isPreparingDiagnostics || !diagnosticsReport}
|
onClick={handleCopyDiagnostics}
|
||||||
className={cn(
|
disabled={isCopyingDiagnostics || isPreparingDiagnostics || !diagnosticsReport}
|
||||||
'typography-meta text-muted-foreground hover:text-foreground',
|
className={cn(
|
||||||
'underline-offset-2 hover:underline',
|
'typography-meta text-muted-foreground hover:text-foreground',
|
||||||
'disabled:opacity-50 disabled:cursor-not-allowed'
|
'underline-offset-2 hover:underline',
|
||||||
)}
|
'disabled:opacity-50 disabled:cursor-not-allowed'
|
||||||
>
|
)}
|
||||||
{copiedDiagnostics
|
>
|
||||||
? t('aboutDialog.actions.diagnosticsCopied')
|
{copiedDiagnostics
|
||||||
: isPreparingDiagnostics
|
? t('aboutDialog.actions.diagnosticsCopied')
|
||||||
? t('aboutDialog.actions.preparingDiagnostics')
|
: isPreparingDiagnostics
|
||||||
: t('aboutDialog.actions.copyDiagnostics')}
|
? t('aboutDialog.actions.preparingDiagnostics')
|
||||||
</button>
|
: t('aboutDialog.actions.copyDiagnostics')}
|
||||||
<p className="typography-micro text-muted-foreground">
|
</button>
|
||||||
{t('aboutDialog.diagnosticsDescription')}
|
<p className="typography-micro text-muted-foreground">
|
||||||
</p>
|
{t('aboutDialog.diagnosticsDescription')}
|
||||||
</div>
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex items-center gap-4 pt-2">
|
<div className="flex flex-col items-center gap-2 pt-2">
|
||||||
|
<div className="flex items-center justify-center gap-4">
|
||||||
|
<a
|
||||||
|
href="https://github.com/btriapitsyn/openchamber"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
<Icon name="github-fill" className="h-4 w-4" />
|
||||||
|
<span>GitHub</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://discord.gg/ZYRSdnwwKA"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
<Icon name="discord-fill" className="h-4 w-4" />
|
||||||
|
<span>Discord</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/btriapitsyn/openchamber"
|
href="https://x.com/openchamber_dev"
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
|
||||||
>
|
|
||||||
<Icon name="github-fill" className="h-4 w-4" />
|
|
||||||
<span>GitHub</span>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://discord.gg/ZYRSdnwwKA"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
|
||||||
>
|
|
||||||
<Icon name="discord-fill" className="h-4 w-4" />
|
|
||||||
<span>Discord</span>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://x.com/btriapitsyn"
|
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
className="flex items-center gap-1.5 typography-meta text-muted-foreground hover:text-foreground transition-colors"
|
||||||
>
|
>
|
||||||
<Icon name="twitter-xfill" className="h-4 w-4" />
|
<Icon name="twitter-xfill" className="h-4 w-4" />
|
||||||
<span>@btriapitsyn</span>
|
<span>@openchamber_dev</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -72,10 +72,11 @@ type MenuAction =
|
|||||||
| 'new-session'
|
| 'new-session'
|
||||||
| 'new-worktree-session'
|
| 'new-worktree-session'
|
||||||
| 'change-workspace'
|
| 'change-workspace'
|
||||||
| 'open-git-tab'
|
| 'toggle-right-sidebar'
|
||||||
| 'open-diff-tab'
|
| 'open-right-sidebar-git'
|
||||||
| 'open-files-tab'
|
| 'open-right-sidebar-files'
|
||||||
| 'open-terminal-tab'
|
| 'toggle-terminal'
|
||||||
|
| 'toggle-terminal-expanded'
|
||||||
| 'copy'
|
| 'copy'
|
||||||
| 'theme-light'
|
| 'theme-light'
|
||||||
| 'theme-dark'
|
| 'theme-dark'
|
||||||
@@ -97,6 +98,11 @@ export const useMenuActions = (
|
|||||||
const setActiveMainTab = useUIStore((s) => s.setActiveMainTab);
|
const setActiveMainTab = useUIStore((s) => s.setActiveMainTab);
|
||||||
const setSettingsDialogOpen = useUIStore((s) => s.setSettingsDialogOpen);
|
const setSettingsDialogOpen = useUIStore((s) => s.setSettingsDialogOpen);
|
||||||
const setAboutDialogOpen = useUIStore((s) => s.setAboutDialogOpen);
|
const setAboutDialogOpen = useUIStore((s) => s.setAboutDialogOpen);
|
||||||
|
const toggleRightSidebar = useUIStore((s) => s.toggleRightSidebar);
|
||||||
|
const setRightSidebarOpen = useUIStore((s) => s.setRightSidebarOpen);
|
||||||
|
const setRightSidebarTab = useUIStore((s) => s.setRightSidebarTab);
|
||||||
|
const toggleBottomTerminal = useUIStore((s) => s.toggleBottomTerminal);
|
||||||
|
const setBottomTerminalExpanded = useUIStore((s) => s.setBottomTerminalExpanded);
|
||||||
const checkForUpdates = useUpdateStore((state) => state.checkForUpdates);
|
const checkForUpdates = useUpdateStore((state) => state.checkForUpdates);
|
||||||
const { setThemeMode } = useThemeSystem();
|
const { setThemeMode } = useThemeSystem();
|
||||||
const checkUpdatesInFlightRef = React.useRef(false);
|
const checkUpdatesInFlightRef = React.useRef(false);
|
||||||
@@ -165,29 +171,27 @@ export const useMenuActions = (
|
|||||||
handleChangeWorkspace();
|
handleChangeWorkspace();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'open-git-tab': {
|
case 'toggle-right-sidebar':
|
||||||
const { activeMainTab } = useUIStore.getState();
|
toggleRightSidebar();
|
||||||
setActiveMainTab(activeMainTab === 'git' ? 'chat' : 'git');
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 'open-diff-tab': {
|
case 'open-right-sidebar-git':
|
||||||
const { activeMainTab } = useUIStore.getState();
|
setRightSidebarOpen(true);
|
||||||
setActiveMainTab(activeMainTab === 'diff' ? 'chat' : 'diff');
|
setRightSidebarTab('git');
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 'open-files-tab': {
|
case 'open-right-sidebar-files':
|
||||||
const { activeMainTab } = useUIStore.getState();
|
setRightSidebarOpen(true);
|
||||||
setActiveMainTab(activeMainTab === 'files' ? 'chat' : 'files');
|
setRightSidebarTab('files');
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 'open-terminal-tab': {
|
case 'toggle-terminal':
|
||||||
const { activeMainTab } = useUIStore.getState();
|
toggleBottomTerminal();
|
||||||
setActiveMainTab(activeMainTab === 'terminal' ? 'chat' : 'terminal');
|
break;
|
||||||
|
|
||||||
|
case 'toggle-terminal-expanded':
|
||||||
|
setBottomTerminalExpanded(!useUIStore.getState().isBottomTerminalExpanded);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 'copy': {
|
case 'copy': {
|
||||||
const copyEvent = new Event('openchamber:copy', { cancelable: true });
|
const copyEvent = new Event('openchamber:copy', { cancelable: true });
|
||||||
@@ -239,9 +243,14 @@ export const useMenuActions = (
|
|||||||
setSessionSwitcherOpen,
|
setSessionSwitcherOpen,
|
||||||
setCommandPaletteOpen,
|
setCommandPaletteOpen,
|
||||||
setSettingsDialogOpen,
|
setSettingsDialogOpen,
|
||||||
|
setBottomTerminalExpanded,
|
||||||
|
setRightSidebarOpen,
|
||||||
|
setRightSidebarTab,
|
||||||
setThemeMode,
|
setThemeMode,
|
||||||
|
toggleBottomTerminal,
|
||||||
toggleCommandPalette,
|
toggleCommandPalette,
|
||||||
toggleHelpDialog,
|
toggleHelpDialog,
|
||||||
|
toggleRightSidebar,
|
||||||
toggleSidebar,
|
toggleSidebar,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2208,16 +2208,16 @@ export const dict = {
|
|||||||
'updateDialog.status.updating': 'Updating...',
|
'updateDialog.status.updating': 'Updating...',
|
||||||
'updateDialog.error.updateFailed': 'Update failed',
|
'updateDialog.error.updateFailed': 'Update failed',
|
||||||
'updateDialog.error.takingLonger': 'Update is taking longer than expected. Wait a bit and refresh, or run: openchamber update',
|
'updateDialog.error.takingLonger': 'Update is taking longer than expected. Wait a bit and refresh, or run: openchamber update',
|
||||||
'opencodeUpdate.toast.available.title': 'OpenCode update available',
|
'opencodeUpdate.toast.available.title': 'OpenCode update',
|
||||||
'opencodeUpdate.toast.available.description': 'Version {version} is ready to install.',
|
'opencodeUpdate.toast.available.description': 'Version {version} available.',
|
||||||
'opencodeUpdate.toast.actions.update': 'Update',
|
'opencodeUpdate.toast.actions.update': 'Update',
|
||||||
'opencodeUpdate.toast.actions.dismiss': 'Dismiss',
|
'opencodeUpdate.toast.actions.dismiss': 'Dismiss',
|
||||||
'opencodeUpdate.toast.actions.reload': 'Reload OpenCode',
|
'opencodeUpdate.toast.actions.reload': 'Reload OpenCode',
|
||||||
'opencodeUpdate.toast.upgrading.title': 'Updating OpenCode...',
|
'opencodeUpdate.toast.upgrading.title': 'Updating OpenCode...',
|
||||||
'opencodeUpdate.toast.upgrading.description': 'Keep OpenChamber open.',
|
'opencodeUpdate.toast.upgrading.description': 'Keep OpenChamber open.',
|
||||||
'opencodeUpdate.toast.updated.title': 'OpenCode updated',
|
'opencodeUpdate.toast.updated.title': 'OpenCode updated',
|
||||||
'opencodeUpdate.toast.updated.description': 'Reload OpenCode to start using the updated version.',
|
'opencodeUpdate.toast.updated.description': 'Update installed.',
|
||||||
'opencodeUpdate.toast.updated.descriptionWithVersion': 'Version {version} is installed. Reload OpenCode to use it.',
|
'opencodeUpdate.toast.updated.descriptionWithVersion': 'Version {version} installed.',
|
||||||
'opencodeUpdate.toast.failed.title': 'Could not update OpenCode',
|
'opencodeUpdate.toast.failed.title': 'Could not update OpenCode',
|
||||||
'opencodeUpdate.toast.failed.description': 'The OpenCode upgrade failed.',
|
'opencodeUpdate.toast.failed.description': 'The OpenCode upgrade failed.',
|
||||||
'opencodeUpdate.toast.reload.message': 'Restarting OpenCode...',
|
'opencodeUpdate.toast.reload.message': 'Restarting OpenCode...',
|
||||||
|
|||||||
@@ -2174,16 +2174,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"updateDialog.status.updating": "Actualizando...",
|
"updateDialog.status.updating": "Actualizando...",
|
||||||
"updateDialog.error.updateFailed": "No se pudo actualizar",
|
"updateDialog.error.updateFailed": "No se pudo actualizar",
|
||||||
"updateDialog.error.takingLonger": "La actualización está tardando más de lo esperado. Espera un poco y refresca, o ejecuta: openchamber update",
|
"updateDialog.error.takingLonger": "La actualización está tardando más de lo esperado. Espera un poco y refresca, o ejecuta: openchamber update",
|
||||||
"opencodeUpdate.toast.available.title": "Actualización de OpenCode disponible",
|
"opencodeUpdate.toast.available.title": "Actualización de OpenCode",
|
||||||
"opencodeUpdate.toast.available.description": "La versión {version} está lista para instalar.",
|
"opencodeUpdate.toast.available.description": "Versión {version} disponible.",
|
||||||
"opencodeUpdate.toast.actions.update": "Actualizar",
|
"opencodeUpdate.toast.actions.update": "Actualizar",
|
||||||
"opencodeUpdate.toast.actions.dismiss": "Descartar",
|
"opencodeUpdate.toast.actions.dismiss": "Descartar",
|
||||||
"opencodeUpdate.toast.actions.reload": "Recargar OpenCode",
|
"opencodeUpdate.toast.actions.reload": "Recargar OpenCode",
|
||||||
"opencodeUpdate.toast.upgrading.title": "Actualizando OpenCode...",
|
"opencodeUpdate.toast.upgrading.title": "Actualizando OpenCode...",
|
||||||
"opencodeUpdate.toast.upgrading.description": "Mantén OpenChamber abierto.",
|
"opencodeUpdate.toast.upgrading.description": "Mantén OpenChamber abierto.",
|
||||||
"opencodeUpdate.toast.updated.title": "OpenCode actualizado",
|
"opencodeUpdate.toast.updated.title": "OpenCode actualizado",
|
||||||
"opencodeUpdate.toast.updated.description": "Recarga OpenCode para empezar a usar la versión actualizada.",
|
"opencodeUpdate.toast.updated.description": "Actualización instalada.",
|
||||||
"opencodeUpdate.toast.updated.descriptionWithVersion": "La versión {version} está instalada. Recarga OpenCode para usarla.",
|
"opencodeUpdate.toast.updated.descriptionWithVersion": "Versión {version} instalada.",
|
||||||
"opencodeUpdate.toast.failed.title": "No se pudo actualizar OpenCode",
|
"opencodeUpdate.toast.failed.title": "No se pudo actualizar OpenCode",
|
||||||
"opencodeUpdate.toast.failed.description": "La actualización de OpenCode falló.",
|
"opencodeUpdate.toast.failed.description": "La actualización de OpenCode falló.",
|
||||||
"opencodeUpdate.toast.reload.message": "Reiniciando OpenCode...",
|
"opencodeUpdate.toast.reload.message": "Reiniciando OpenCode...",
|
||||||
|
|||||||
@@ -2208,16 +2208,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'updateDialog.status.updating': '업데이트 중…',
|
'updateDialog.status.updating': '업데이트 중…',
|
||||||
'updateDialog.error.updateFailed': '업데이트 실패',
|
'updateDialog.error.updateFailed': '업데이트 실패',
|
||||||
'updateDialog.error.takingLonger': '업데이트가 예상보다 오래 걸립니다. 잠시 기다린 뒤 새로고침하거나 `openchamber update`를 실행하세요.',
|
'updateDialog.error.takingLonger': '업데이트가 예상보다 오래 걸립니다. 잠시 기다린 뒤 새로고침하거나 `openchamber update`를 실행하세요.',
|
||||||
'opencodeUpdate.toast.available.title': 'OpenCode 업데이트 사용 가능',
|
'opencodeUpdate.toast.available.title': 'OpenCode 업데이트',
|
||||||
'opencodeUpdate.toast.available.description': '버전 {version}을 설치할 수 있습니다.',
|
'opencodeUpdate.toast.available.description': '버전 {version} 사용 가능.',
|
||||||
'opencodeUpdate.toast.actions.update': '업데이트',
|
'opencodeUpdate.toast.actions.update': '업데이트',
|
||||||
'opencodeUpdate.toast.actions.dismiss': '닫기',
|
'opencodeUpdate.toast.actions.dismiss': '닫기',
|
||||||
'opencodeUpdate.toast.actions.reload': 'OpenCode 다시 로드',
|
'opencodeUpdate.toast.actions.reload': 'OpenCode 다시 로드',
|
||||||
'opencodeUpdate.toast.upgrading.title': 'OpenCode 업데이트 중...',
|
'opencodeUpdate.toast.upgrading.title': 'OpenCode 업데이트 중...',
|
||||||
'opencodeUpdate.toast.upgrading.description': 'OpenChamber를 열어 두세요.',
|
'opencodeUpdate.toast.upgrading.description': 'OpenChamber를 열어 두세요.',
|
||||||
'opencodeUpdate.toast.updated.title': 'OpenCode 업데이트 완료',
|
'opencodeUpdate.toast.updated.title': 'OpenCode 업데이트 완료',
|
||||||
'opencodeUpdate.toast.updated.description': '업데이트된 버전을 사용하려면 OpenCode를 다시 로드하세요.',
|
'opencodeUpdate.toast.updated.description': '업데이트가 설치되었습니다.',
|
||||||
'opencodeUpdate.toast.updated.descriptionWithVersion': '버전 {version}이 설치되었습니다. 사용하려면 OpenCode를 다시 로드하세요.',
|
'opencodeUpdate.toast.updated.descriptionWithVersion': '버전 {version}이 설치되었습니다.',
|
||||||
'opencodeUpdate.toast.failed.title': 'OpenCode를 업데이트할 수 없음',
|
'opencodeUpdate.toast.failed.title': 'OpenCode를 업데이트할 수 없음',
|
||||||
'opencodeUpdate.toast.failed.description': 'OpenCode 업그레이드에 실패했습니다.',
|
'opencodeUpdate.toast.failed.description': 'OpenCode 업그레이드에 실패했습니다.',
|
||||||
'opencodeUpdate.toast.reload.message': 'OpenCode 다시 시작 중...',
|
'opencodeUpdate.toast.reload.message': 'OpenCode 다시 시작 중...',
|
||||||
|
|||||||
@@ -2189,16 +2189,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'updateDialog.status.serverRestarting': 'Ponowne uruchamianie serwera...',
|
'updateDialog.status.serverRestarting': 'Ponowne uruchamianie serwera...',
|
||||||
'updateDialog.status.updating': 'Aktualizowanie...',
|
'updateDialog.status.updating': 'Aktualizowanie...',
|
||||||
'updateDialog.status.waitingForServer': 'Oczekiwanie na serwer...',
|
'updateDialog.status.waitingForServer': 'Oczekiwanie na serwer...',
|
||||||
'opencodeUpdate.toast.available.title': 'Dostępna aktualizacja OpenCode',
|
'opencodeUpdate.toast.available.title': 'Aktualizacja OpenCode',
|
||||||
'opencodeUpdate.toast.available.description': 'Wersja {version} jest gotowa do instalacji.',
|
'opencodeUpdate.toast.available.description': 'Wersja {version} dostępna.',
|
||||||
'opencodeUpdate.toast.actions.update': 'Aktualizuj',
|
'opencodeUpdate.toast.actions.update': 'Aktualizuj',
|
||||||
'opencodeUpdate.toast.actions.dismiss': 'Odrzuć',
|
'opencodeUpdate.toast.actions.dismiss': 'Odrzuć',
|
||||||
'opencodeUpdate.toast.actions.reload': 'Przeładuj OpenCode',
|
'opencodeUpdate.toast.actions.reload': 'Przeładuj OpenCode',
|
||||||
'opencodeUpdate.toast.upgrading.title': 'Aktualizowanie OpenCode...',
|
'opencodeUpdate.toast.upgrading.title': 'Aktualizowanie OpenCode...',
|
||||||
'opencodeUpdate.toast.upgrading.description': 'Pozostaw OpenChamber otwarte.',
|
'opencodeUpdate.toast.upgrading.description': 'Pozostaw OpenChamber otwarte.',
|
||||||
'opencodeUpdate.toast.updated.title': 'OpenCode zaktualizowany',
|
'opencodeUpdate.toast.updated.title': 'OpenCode zaktualizowany',
|
||||||
'opencodeUpdate.toast.updated.description': 'Przeładuj OpenCode, aby zacząć używać zaktualizowanej wersji.',
|
'opencodeUpdate.toast.updated.description': 'Aktualizacja zainstalowana.',
|
||||||
'opencodeUpdate.toast.updated.descriptionWithVersion': 'Wersja {version} jest zainstalowana. Przeładuj OpenCode, aby jej użyć.',
|
'opencodeUpdate.toast.updated.descriptionWithVersion': 'Wersja {version} zainstalowana.',
|
||||||
'opencodeUpdate.toast.failed.title': 'Nie udało się zaktualizować OpenCode',
|
'opencodeUpdate.toast.failed.title': 'Nie udało się zaktualizować OpenCode',
|
||||||
'opencodeUpdate.toast.failed.description': 'Aktualizacja OpenCode nie powiodła się.',
|
'opencodeUpdate.toast.failed.description': 'Aktualizacja OpenCode nie powiodła się.',
|
||||||
'opencodeUpdate.toast.reload.message': 'Ponowne uruchamianie OpenCode...',
|
'opencodeUpdate.toast.reload.message': 'Ponowne uruchamianie OpenCode...',
|
||||||
|
|||||||
@@ -2174,16 +2174,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"updateDialog.status.updating": "Atualizando...",
|
"updateDialog.status.updating": "Atualizando...",
|
||||||
"updateDialog.error.updateFailed": "Não foi possível atualizar",
|
"updateDialog.error.updateFailed": "Não foi possível atualizar",
|
||||||
"updateDialog.error.takingLonger": "A atualização está demorando mais do que o esperado. Aguarde um pouco e atualize, ou execute: openchamber update",
|
"updateDialog.error.takingLonger": "A atualização está demorando mais do que o esperado. Aguarde um pouco e atualize, ou execute: openchamber update",
|
||||||
"opencodeUpdate.toast.available.title": "Atualização do OpenCode disponível",
|
"opencodeUpdate.toast.available.title": "Atualização do OpenCode",
|
||||||
"opencodeUpdate.toast.available.description": "A versão {version} está pronta para instalar.",
|
"opencodeUpdate.toast.available.description": "Versão {version} disponível.",
|
||||||
"opencodeUpdate.toast.actions.update": "Atualizar",
|
"opencodeUpdate.toast.actions.update": "Atualizar",
|
||||||
"opencodeUpdate.toast.actions.dismiss": "Dispensar",
|
"opencodeUpdate.toast.actions.dismiss": "Dispensar",
|
||||||
"opencodeUpdate.toast.actions.reload": "Recarregar OpenCode",
|
"opencodeUpdate.toast.actions.reload": "Recarregar OpenCode",
|
||||||
"opencodeUpdate.toast.upgrading.title": "Atualizando OpenCode...",
|
"opencodeUpdate.toast.upgrading.title": "Atualizando OpenCode...",
|
||||||
"opencodeUpdate.toast.upgrading.description": "Mantenha o OpenChamber aberto.",
|
"opencodeUpdate.toast.upgrading.description": "Mantenha o OpenChamber aberto.",
|
||||||
"opencodeUpdate.toast.updated.title": "OpenCode atualizado",
|
"opencodeUpdate.toast.updated.title": "OpenCode atualizado",
|
||||||
"opencodeUpdate.toast.updated.description": "Recarregue o OpenCode para começar a usar a versão atualizada.",
|
"opencodeUpdate.toast.updated.description": "Atualização instalada.",
|
||||||
"opencodeUpdate.toast.updated.descriptionWithVersion": "A versão {version} está instalada. Recarregue o OpenCode para usá-la.",
|
"opencodeUpdate.toast.updated.descriptionWithVersion": "Versão {version} instalada.",
|
||||||
"opencodeUpdate.toast.failed.title": "Não foi possível atualizar o OpenCode",
|
"opencodeUpdate.toast.failed.title": "Não foi possível atualizar o OpenCode",
|
||||||
"opencodeUpdate.toast.failed.description": "A atualização do OpenCode falhou.",
|
"opencodeUpdate.toast.failed.description": "A atualização do OpenCode falhou.",
|
||||||
"opencodeUpdate.toast.reload.message": "Reiniciando OpenCode...",
|
"opencodeUpdate.toast.reload.message": "Reiniciando OpenCode...",
|
||||||
|
|||||||
@@ -2174,16 +2174,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"updateDialog.status.updating": "Оновлення...",
|
"updateDialog.status.updating": "Оновлення...",
|
||||||
"updateDialog.error.updateFailed": "Помилка оновлення",
|
"updateDialog.error.updateFailed": "Помилка оновлення",
|
||||||
"updateDialog.error.takingLonger": "Оновлення триває довше, ніж очікувалося. Зачекайте трохи та оновіть або запустіть: openchamber update",
|
"updateDialog.error.takingLonger": "Оновлення триває довше, ніж очікувалося. Зачекайте трохи та оновіть або запустіть: openchamber update",
|
||||||
"opencodeUpdate.toast.available.title": "Доступне оновлення OpenCode",
|
"opencodeUpdate.toast.available.title": "Оновлення OpenCode",
|
||||||
"opencodeUpdate.toast.available.description": "Версія {version} готова до встановлення.",
|
"opencodeUpdate.toast.available.description": "Версія {version} доступна.",
|
||||||
"opencodeUpdate.toast.actions.update": "Оновити",
|
"opencodeUpdate.toast.actions.update": "Оновити",
|
||||||
"opencodeUpdate.toast.actions.dismiss": "Сховати",
|
"opencodeUpdate.toast.actions.dismiss": "Сховати",
|
||||||
"opencodeUpdate.toast.actions.reload": "Перезавантажити OpenCode",
|
"opencodeUpdate.toast.actions.reload": "Перезавантажити OpenCode",
|
||||||
"opencodeUpdate.toast.upgrading.title": "Оновлення OpenCode...",
|
"opencodeUpdate.toast.upgrading.title": "Оновлення OpenCode...",
|
||||||
"opencodeUpdate.toast.upgrading.description": "Залиште OpenChamber відкритим.",
|
"opencodeUpdate.toast.upgrading.description": "Залиште OpenChamber відкритим.",
|
||||||
"opencodeUpdate.toast.updated.title": "OpenCode оновлено",
|
"opencodeUpdate.toast.updated.title": "OpenCode оновлено",
|
||||||
"opencodeUpdate.toast.updated.description": "Перезавантажте OpenCode, щоб почати використовувати оновлену версію.",
|
"opencodeUpdate.toast.updated.description": "Оновлення встановлено.",
|
||||||
"opencodeUpdate.toast.updated.descriptionWithVersion": "Версію {version} встановлено. Перезавантажте OpenCode, щоб її використовувати.",
|
"opencodeUpdate.toast.updated.descriptionWithVersion": "Версію {version} встановлено.",
|
||||||
"opencodeUpdate.toast.failed.title": "Не вдалося оновити OpenCode",
|
"opencodeUpdate.toast.failed.title": "Не вдалося оновити OpenCode",
|
||||||
"opencodeUpdate.toast.failed.description": "Оновлення OpenCode не вдалося.",
|
"opencodeUpdate.toast.failed.description": "Оновлення OpenCode не вдалося.",
|
||||||
"opencodeUpdate.toast.reload.message": "Перезапуск OpenCode...",
|
"opencodeUpdate.toast.reload.message": "Перезапуск OpenCode...",
|
||||||
|
|||||||
@@ -2174,16 +2174,16 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'updateDialog.status.updating': '更新中...',
|
'updateDialog.status.updating': '更新中...',
|
||||||
'updateDialog.error.updateFailed': '更新失败',
|
'updateDialog.error.updateFailed': '更新失败',
|
||||||
'updateDialog.error.takingLonger': '更新耗时超出预期。请稍等后刷新,或运行:openchamber update',
|
'updateDialog.error.takingLonger': '更新耗时超出预期。请稍等后刷新,或运行:openchamber update',
|
||||||
'opencodeUpdate.toast.available.title': 'OpenCode 有可用更新',
|
'opencodeUpdate.toast.available.title': 'OpenCode 更新',
|
||||||
'opencodeUpdate.toast.available.description': '版本 {version} 已可安装。',
|
'opencodeUpdate.toast.available.description': '版本 {version} 可用。',
|
||||||
'opencodeUpdate.toast.actions.update': '更新',
|
'opencodeUpdate.toast.actions.update': '更新',
|
||||||
'opencodeUpdate.toast.actions.dismiss': '忽略',
|
'opencodeUpdate.toast.actions.dismiss': '忽略',
|
||||||
'opencodeUpdate.toast.actions.reload': '重载 OpenCode',
|
'opencodeUpdate.toast.actions.reload': '重载 OpenCode',
|
||||||
'opencodeUpdate.toast.upgrading.title': '正在更新 OpenCode...',
|
'opencodeUpdate.toast.upgrading.title': '正在更新 OpenCode...',
|
||||||
'opencodeUpdate.toast.upgrading.description': '请保持 OpenChamber 打开。',
|
'opencodeUpdate.toast.upgrading.description': '请保持 OpenChamber 打开。',
|
||||||
'opencodeUpdate.toast.updated.title': 'OpenCode 已更新',
|
'opencodeUpdate.toast.updated.title': 'OpenCode 已更新',
|
||||||
'opencodeUpdate.toast.updated.description': '重载 OpenCode 以开始使用更新后的版本。',
|
'opencodeUpdate.toast.updated.description': '更新已安装。',
|
||||||
'opencodeUpdate.toast.updated.descriptionWithVersion': '版本 {version} 已安装。重载 OpenCode 后即可使用。',
|
'opencodeUpdate.toast.updated.descriptionWithVersion': '版本 {version} 已安装。',
|
||||||
'opencodeUpdate.toast.failed.title': '无法更新 OpenCode',
|
'opencodeUpdate.toast.failed.title': '无法更新 OpenCode',
|
||||||
'opencodeUpdate.toast.failed.description': 'OpenCode 升级失败。',
|
'opencodeUpdate.toast.failed.description': 'OpenCode 升级失败。',
|
||||||
'opencodeUpdate.toast.reload.message': '正在重启 OpenCode...',
|
'opencodeUpdate.toast.reload.message': '正在重启 OpenCode...',
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ This module provides OpenCode server integration utilities for the web server ru
|
|||||||
- `GET /api/config/settings`
|
- `GET /api/config/settings`
|
||||||
- `PUT /api/config/settings`
|
- `PUT /api/config/settings`
|
||||||
- `GET /api/config/opencode-resolution`
|
- `GET /api/config/opencode-resolution`
|
||||||
|
- `POST /api/opencode/upgrade` (proxies OpenCode upgrade, then restarts managed OpenCode so the new binary is active)
|
||||||
|
- `GET /api/opencode/upgrade-status`
|
||||||
- `POST /api/opencode/directory`
|
- `POST /api/opencode/directory`
|
||||||
- `GET /api/provider/:providerId/source`
|
- `GET /api/provider/:providerId/source`
|
||||||
- `DELETE /api/provider/:providerId/auth`
|
- `DELETE /api/provider/:providerId/auth`
|
||||||
|
|||||||
@@ -155,7 +155,20 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
|
|||||||
error: payload?.error || response.statusText || 'Failed to upgrade OpenCode',
|
error: payload?.error || response.statusText || 'Failed to upgrade OpenCode',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.json(payload ?? { success: true });
|
|
||||||
|
try {
|
||||||
|
await refreshOpenCodeAfterConfigChange('OpenCode upgrade');
|
||||||
|
} catch (restartError) {
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
upgraded: true,
|
||||||
|
error: restartError instanceof Error
|
||||||
|
? `OpenCode upgraded, but restart failed: ${restartError.message}`
|
||||||
|
: 'OpenCode upgraded, but restart failed',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({ ...(payload ?? { success: true }), restarted: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to upgrade OpenCode:', error);
|
console.error('Failed to upgrade OpenCode:', error);
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
|
|||||||
Reference in New Issue
Block a user