+
+ {/* Header row: Status dot, title, version, update badge, icon buttons */}
+
+
+ {/* Status indicator */}
+
+
CLIProxy Plus
+
+ {/* Version in header */}
+ {currentVersion && (
+
+ v{currentVersion}
+
)}
- />
-
CLIProxy Plus
- {hasUpdate && (
-
v${updateCheck?.latestVersion}`}
- >
-
- Update
-
- )}
+
+ {/* Clickable Update/Downgrade badge */}
+ {(hasUpdate || isUnstable) && targetVersion && (
+
handleInstallVersion(targetVersion)}
+ title={`Click to ${isUnstable ? 'downgrade' : 'update'}`}
+ >
+ {isUnstable ? (
+ <>
+
+ {targetVersion}
+ >
+ ) : (
+ <>
+
+ {targetVersion}
+ >
+ )}
+
+ )}
+
+
+ {/* Right side: status icon + control buttons when running */}
+
+ {isLoading ? (
+
+ ) : isRunning ? (
+ <>
+ {/* Icon buttons: Restart, Stop, Settings/Close */}
+
restartProxy.mutate()}
+ disabled={isActioning}
+ isPending={restartProxy.isPending}
+ />
+ stopProxy.mutate()}
+ disabled={isActioning}
+ isPending={stopProxy.isPending}
+ variant="destructive-ghost"
+ />
+ setIsExpanded(!isExpanded)}
+ className={isExpanded ? 'bg-muted' : undefined}
+ />
+ >
+ ) : (
+
+ )}
+
-
- {isLoading ? (
-
- ) : isRunning ? (
-
- ) : (
-
- )}
-
-
-
- {isRunning && status ? (
- <>
+ {/* Stats row when running */}
+ {isRunning && status && (
Port {status.port}
{status.sessionCount !== undefined && status.sessionCount > 0 && (
@@ -265,254 +376,138 @@ export function ProxyStatusWidget() {
)}
- {/* Control buttons when running: Restart | Update/Downgrade | Stop | Settings */}
-
- {/* Restart button - pure restart, no version change */}
+ )}
+
+ {/* Expanded section: Version Management */}
+ {isRunning && (
+
+
+ {/* Section header */}
+ Version Management
+
+ {/* Version picker row */}
+
+ {/* Dropdown - full width, no truncation */}
+
+
+
+
+
+ {versionsData?.versions.slice(0, 20).map((v) => {
+ const vIsUnstable =
+ versionsData?.maxStableVersion &&
+ isNewerVersionClient(v, versionsData.maxStableVersion);
+ return (
+
+
+ v{v}
+ {v === versionsData.latestStable && (
+ (stable)
+ )}
+ {vIsUnstable && (
+ ⚠
+ )}
+
+
+ );
+ })}
+
+
+
+ {/* Install button */}
+ handleInstallVersion(selectedVersion)}
+ disabled={installVersion.isPending || !selectedVersion}
+ >
+ {installVersion.isPending ? (
+
+ ) : (
+
+ )}
+ Install
+
+
+
+ {/* Stability warning for selected version */}
+ {selectedVersion &&
+ versionsData?.maxStableVersion &&
+ isNewerVersionClient(selectedVersion, versionsData.maxStableVersion) && (
+
+
+
Versions above {versionsData.maxStableVersion} have known issues
+
+ )}
+
+ {/* Sync time */}
+ {updateCheck?.checkedAt && (
+
+ Last checked {formatTimeAgo(updateCheck.checkedAt)}
+
+ )}
+
+
+ )}
+
+ {/* Not running state */}
+ {!isRunning && (
+
+
Not running
restartProxy.mutate()}
- disabled={isActioning}
- title="Restart CLIProxy service (no version change)"
+ onClick={() => startProxy.mutate()}
+ disabled={startProxy.isPending}
>
- {restartProxy.isPending ? (
+ {startProxy.isPending ? (
) : (
-
+
)}
- Restart
-
-
- {/* Update/Downgrade button - version change */}
-
{
- const targetVersion = isUnstable
- ? updateCheck?.maxStableVersion || versionsData?.latestStable
- : updateCheck?.latestVersion;
- if (targetVersion) handleInstallVersion(targetVersion);
- }}
- disabled={isActioning || (!hasUpdate && !isUnstable)}
- title={
- isUnstable
- ? `Downgrade to stable v${updateCheck?.maxStableVersion}`
- : hasUpdate
- ? `Update to v${updateCheck?.latestVersion}`
- : 'Already on latest version'
- }
- >
- {isActioning && !restartProxy.isPending ? (
-
- ) : isUnstable ? (
-
- ) : hasUpdate ? (
-
- ) : null}
- {isUnstable ? 'Downgrade' : hasUpdate ? 'Update' : 'Latest'}
-
-
- {/* Stop button */}
-
stopProxy.mutate()}
- disabled={isActioning}
- title="Stop CLIProxy service"
- >
- {stopProxy.isPending ? (
-
- ) : (
-
- )}
- Stop
-
-
- {/* Settings gear - toggle version picker */}
-
setShowVersionSettings(!showVersionSettings)}
- title="Version settings"
- >
-
+ Start
+ )}
- {/* Version Settings (collapsible) */}
-
-
-
- {/* Current version */}
-
- Current:
-
- v{updateCheck?.currentVersion}
- {isUnstable && ' (unstable)'}
-
-
-
- {/* Version picker row */}
-
- {/* Dropdown */}
-
{
- setSelectedVersion(v);
- setManualVersion('');
- }}
- disabled={versionsLoading}
- >
-
-
-
-
- {versionsData?.versions.slice(0, 20).map((v) => (
-
- v{v}
- {v === versionsData.latestStable && ' (stable)'}
- {v === versionsData.latest &&
- v !== versionsData.latestStable &&
- ' (latest)'}
-
- ))}
-
-
-
- {/* Manual input */}
-
{
- setManualVersion(e.target.value);
- setSelectedVersion('');
- }}
- className="h-7 text-xs w-24"
- />
-
- {/* Install button */}
-
handleInstallVersion(manualVersion || selectedVersion)}
- disabled={installVersion.isPending || (!selectedVersion && !manualVersion)}
- >
- {installVersion.isPending ? (
-
- ) : (
-
- )}
- Install
-
-
-
- {/* Stability warning */}
- {(selectedVersion || manualVersion) &&
- versionsData &&
- isNewerVersionClient(
- manualVersion || selectedVersion,
- versionsData.maxStableVersion
- ) && (
-
-
-
- Versions above {versionsData.maxStableVersion} have known stability issues
-
-
- )}
-
-
-
- >
- ) : (
-
-
Not running
-
startProxy.mutate()}
- disabled={startProxy.isPending}
- >
- {startProxy.isPending ? (
-
- ) : (
-
- )}
- Start
-
-
- )}
-
- {/* Version sync indicator */}
- {updateCheck?.currentVersion && (
-
-
- {isUnstable && (
-
- )}
-
- v{updateCheck.currentVersion}
-
- {isUnstable && (
- (unstable)
- )}
-
- {updateCheck.checkedAt && (
-
- Synced {formatTimeAgo(updateCheck.checkedAt)}
-
- )}
-
- )}
-
- {/* Unstable Version Confirmation Dialog */}
-
-
-
-
-
- Install Unstable Version?
-
-
-
- You are about to install v{pendingInstallVersion} , which is above
- the maximum stable version{' '}
- v{versionsData?.maxStableVersion || '6.6.80'} .
-
-
- This version has known stability issues and may cause unexpected behavior.
-
- Are you sure you want to proceed?
-
-
-
- Cancel
-
- Install Anyway
-
-
-
-
-
+ {/* Unstable Version Confirmation Dialog */}
+
+
+
+
+
+ Install Unstable Version?
+
+
+
+ You are about to install v{pendingInstallVersion} , which is above
+ the maximum stable version{' '}
+ v{versionsData?.maxStableVersion || '6.6.80'} .
+
+
+ This version has known stability issues and may cause unexpected behavior.
+
+ Are you sure you want to proceed?
+
+
+
+ Cancel
+
+ Install Anyway
+
+
+
+
+