feat(ui): add dispose instance and rehydrate
Adds a dispose instance action to the instance info view, POSTing to /instance/dispose and rehydrating per-instance stores; also handles server.instance.disposed events and adds danger button styling.
This commit is contained in:
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "Enable streaming to watch your OpenCode server activity.",
|
||||
"infoView.logs.empty.waiting": "Waiting for server output...",
|
||||
"infoView.logs.scrollToBottom": "Scroll to bottom",
|
||||
|
||||
"infoView.dispose.actions.dispose": "Dispose instance",
|
||||
"infoView.dispose.actions.disposing": "Disposing...",
|
||||
"infoView.dispose.confirm.title": "Dispose instance?",
|
||||
"infoView.dispose.confirm.message": "This clears cached per-project state for this directory and reloads the instance.",
|
||||
"infoView.dispose.confirm.confirmLabel": "Dispose",
|
||||
"infoView.dispose.confirm.cancelLabel": "Cancel",
|
||||
"infoView.dispose.toast.success": "Instance disposed. Reloading...",
|
||||
"infoView.dispose.toast.error": "Failed to dispose instance.",
|
||||
} as const
|
||||
|
||||
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "Activa el streaming para ver la actividad de tu servidor de OpenCode.",
|
||||
"infoView.logs.empty.waiting": "Esperando la salida del servidor...",
|
||||
"infoView.logs.scrollToBottom": "Desplazarse al final",
|
||||
|
||||
"infoView.dispose.actions.dispose": "Desechar instancia",
|
||||
"infoView.dispose.actions.disposing": "Desechando...",
|
||||
"infoView.dispose.confirm.title": "¿Desechar instancia?",
|
||||
"infoView.dispose.confirm.message": "Esto borra el estado en caché por proyecto para este directorio y recarga la instancia.",
|
||||
"infoView.dispose.confirm.confirmLabel": "Desechar",
|
||||
"infoView.dispose.confirm.cancelLabel": "Cancelar",
|
||||
"infoView.dispose.toast.success": "Instancia desechada. Recargando...",
|
||||
"infoView.dispose.toast.error": "No se pudo desechar la instancia.",
|
||||
} as const
|
||||
|
||||
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "Activez le streaming pour suivre l'activité de votre serveur OpenCode.",
|
||||
"infoView.logs.empty.waiting": "En attente de la sortie du serveur...",
|
||||
"infoView.logs.scrollToBottom": "Aller en bas",
|
||||
|
||||
"infoView.dispose.actions.dispose": "Réinitialiser l'instance",
|
||||
"infoView.dispose.actions.disposing": "Réinitialisation...",
|
||||
"infoView.dispose.confirm.title": "Réinitialiser l'instance ?",
|
||||
"infoView.dispose.confirm.message": "Cela efface l'état en cache pour ce répertoire et recharge l'instance.",
|
||||
"infoView.dispose.confirm.confirmLabel": "Réinitialiser",
|
||||
"infoView.dispose.confirm.cancelLabel": "Annuler",
|
||||
"infoView.dispose.toast.success": "Instance réinitialisée. Rechargement...",
|
||||
"infoView.dispose.toast.error": "Impossible de réinitialiser l'instance.",
|
||||
} as const
|
||||
|
||||
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "ストリーミングを有効にして OpenCode サーバーの動作を監視します。",
|
||||
"infoView.logs.empty.waiting": "サーバー出力を待機中...",
|
||||
"infoView.logs.scrollToBottom": "最下部へスクロール",
|
||||
|
||||
"infoView.dispose.actions.dispose": "インスタンスを破棄",
|
||||
"infoView.dispose.actions.disposing": "破棄しています...",
|
||||
"infoView.dispose.confirm.title": "インスタンスを破棄しますか?",
|
||||
"infoView.dispose.confirm.message": "このディレクトリのプロジェクト状態キャッシュをクリアし、インスタンスを再読み込みします。",
|
||||
"infoView.dispose.confirm.confirmLabel": "破棄",
|
||||
"infoView.dispose.confirm.cancelLabel": "キャンセル",
|
||||
"infoView.dispose.toast.success": "インスタンスを破棄しました。再読み込み中...",
|
||||
"infoView.dispose.toast.error": "インスタンスの破棄に失敗しました。",
|
||||
} as const
|
||||
|
||||
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "Включите стриминг, чтобы наблюдать за активностью сервера OpenCode.",
|
||||
"infoView.logs.empty.waiting": "Ожидание вывода сервера…",
|
||||
"infoView.logs.scrollToBottom": "Прокрутить вниз",
|
||||
|
||||
"infoView.dispose.actions.dispose": "Сбросить инстанс",
|
||||
"infoView.dispose.actions.disposing": "Сброс...",
|
||||
"infoView.dispose.confirm.title": "Сбросить инстанс?",
|
||||
"infoView.dispose.confirm.message": "Это очистит кэш состояния проекта для этого каталога и перезагрузит инстанс.",
|
||||
"infoView.dispose.confirm.confirmLabel": "Сбросить",
|
||||
"infoView.dispose.confirm.cancelLabel": "Отмена",
|
||||
"infoView.dispose.toast.success": "Инстанс сброшен. Перезагрузка...",
|
||||
"infoView.dispose.toast.error": "Не удалось сбросить инстанс.",
|
||||
} as const
|
||||
|
||||
@@ -15,4 +15,13 @@ export const logMessages = {
|
||||
"infoView.logs.paused.description": "启用流式输出以查看 OpenCode 服务器活动。",
|
||||
"infoView.logs.empty.waiting": "正在等待服务器输出...",
|
||||
"infoView.logs.scrollToBottom": "滚动到底部",
|
||||
|
||||
"infoView.dispose.actions.dispose": "释放实例",
|
||||
"infoView.dispose.actions.disposing": "正在释放...",
|
||||
"infoView.dispose.confirm.title": "要释放实例吗?",
|
||||
"infoView.dispose.confirm.message": "这将清除此目录的项目缓存状态,并重新加载实例。",
|
||||
"infoView.dispose.confirm.confirmLabel": "释放",
|
||||
"infoView.dispose.confirm.cancelLabel": "取消",
|
||||
"infoView.dispose.toast.success": "实例已释放。正在重新加载...",
|
||||
"infoView.dispose.toast.error": "释放实例失败。",
|
||||
} as const
|
||||
|
||||
@@ -46,7 +46,7 @@ class SDKManager {
|
||||
|
||||
export type { OpencodeClient }
|
||||
|
||||
function buildInstanceBaseUrl(proxyPath: string): string {
|
||||
export function buildInstanceBaseUrl(proxyPath: string): string {
|
||||
const normalized = normalizeProxyPath(proxyPath)
|
||||
const base = stripTrailingSlashes(CODENOMAD_API_BASE)
|
||||
return `${base}${normalized}/`
|
||||
|
||||
@@ -54,6 +54,13 @@ interface BackgroundProcessRemovedEvent {
|
||||
}
|
||||
}
|
||||
|
||||
interface ServerInstanceDisposedEvent {
|
||||
type: "server.instance.disposed"
|
||||
properties: {
|
||||
directory: string
|
||||
}
|
||||
}
|
||||
|
||||
type SSEEvent =
|
||||
| MessageUpdateEvent
|
||||
| MessageRemovedEvent
|
||||
@@ -74,6 +81,7 @@ type SSEEvent =
|
||||
| TuiToastEvent
|
||||
| BackgroundProcessUpdatedEvent
|
||||
| BackgroundProcessRemovedEvent
|
||||
| ServerInstanceDisposedEvent
|
||||
| { type: string; properties?: Record<string, unknown> }
|
||||
|
||||
type ConnectionStatus = InstanceStreamStatus
|
||||
@@ -173,6 +181,9 @@ class SSEManager {
|
||||
case "background.process.removed":
|
||||
this.onBackgroundProcessRemoved?.(instanceId, event as BackgroundProcessRemovedEvent)
|
||||
break
|
||||
case "server.instance.disposed":
|
||||
this.onInstanceDisposed?.(instanceId, event as ServerInstanceDisposedEvent)
|
||||
break
|
||||
default:
|
||||
log.warn("Unknown SSE event type", { type: event.type })
|
||||
}
|
||||
@@ -205,6 +216,7 @@ class SSEManager {
|
||||
onLspUpdated?: (instanceId: string, event: EventLspUpdated) => void
|
||||
onBackgroundProcessUpdated?: (instanceId: string, event: BackgroundProcessUpdatedEvent) => void
|
||||
onBackgroundProcessRemoved?: (instanceId: string, event: BackgroundProcessRemovedEvent) => void
|
||||
onInstanceDisposed?: (instanceId: string, event: ServerInstanceDisposedEvent) => void
|
||||
onConnectionLost?: (instanceId: string, reason: string) => void | Promise<void>
|
||||
|
||||
getStatus(instanceId: string): ConnectionStatus | null {
|
||||
|
||||
Reference in New Issue
Block a user