feat: implement manual SDK session sync and fix UI crash
Some checks failed
Release Binaries / release (push) Has been cancelled

This commit is contained in:
Gemini AI
2025-12-27 12:11:08 +04:00
Unverified
parent 251fad85b1
commit 0e5059fc88
5 changed files with 127 additions and 33 deletions

View File

@@ -7,6 +7,8 @@ import {
Settings,
Plug,
Sparkles,
RefreshCw,
Download,
ChevronRight,
ChevronDown,
Folder,
@@ -21,6 +23,7 @@ import InstanceServiceStatus from "../instance-service-status"
import McpManager from "../mcp-manager"
import { catalog, catalogLoading, catalogError, loadCatalog } from "../../stores/skills"
import { getSessionSkills, setSessionSkills } from "../../stores/session-state"
import { syncSessionsFromSdk } from "../../stores/session-api"
export interface FileNode {
name: string
@@ -132,6 +135,7 @@ export const Sidebar: Component<SidebarProps> = (props) => {
const [rootFiles, setRootFiles] = createSignal<FileNode[]>([])
const [lastRequestedTab, setLastRequestedTab] = createSignal<string | null>(null)
const [searchQuery, setSearchQuery] = createSignal("")
const [syncing, setSyncing] = createSignal(false)
const [searchResults, setSearchResults] = createSignal<FileNode[]>([])
const [searchLoading, setSearchLoading] = createSignal(false)
const [gitStatus, setGitStatus] = createSignal<{
@@ -322,6 +326,25 @@ export const Sidebar: Component<SidebarProps> = (props) => {
</Show>
<Show when={activeTab() === "sessions"}>
<div class="flex flex-col gap-1">
<div class="px-2 mb-2">
<button
onClick={async () => {
setSyncing(true)
try {
await syncSessionsFromSdk(props.instanceId)
} finally {
setSyncing(false)
}
}}
disabled={syncing()}
class="w-full flex items-center justify-center gap-2 px-3 py-2 text-xs font-semibold uppercase tracking-wide rounded-md bg-blue-500/10 text-blue-400 border border-blue-500/20 hover:bg-blue-500/20 disabled:opacity-50 transition-all"
>
<Show when={syncing()} fallback={<Download size={14} />}>
<RefreshCw size={14} class="animate-spin" />
</Show>
{syncing() ? "Syncing..." : "Sync SDK Sessions"}
</button>
</div>
<For each={props.sessions}>
{(session) => (
<div
@@ -479,8 +502,8 @@ export const Sidebar: Component<SidebarProps> = (props) => {
type="button"
onClick={() => toggleSkillSelection(skill.id)}
class={`w-full text-left px-3 py-2 rounded-md border transition-colors ${isSelected()
? "border-blue-500/60 bg-blue-500/10 text-blue-200"
: "border-white/10 bg-white/5 text-zinc-300 hover:text-white"
? "border-blue-500/60 bg-blue-500/10 text-blue-200"
: "border-white/10 bg-white/5 text-zinc-300 hover:text-white"
}`}
>
<div class="text-xs font-semibold">{skill.name}</div>

View File

@@ -1153,6 +1153,27 @@ async function loadMessages(instanceId: string, sessionId: string, force = false
updateSessionInfo(instanceId, sessionId)
}
async function syncSessionsFromSdk(instanceId: string): Promise<void> {
const instance = instances().get(instanceId)
if (!instance) throw new Error("Instance not ready")
const folderPath = instance.folder
if (!folderPath) throw new Error("No folder path for instance")
log.info({ instanceId, folderPath }, "Manual SDK sync requested")
try {
const result = await nativeSessionApi.syncFromSdk(instanceId, folderPath)
log.info({ instanceId, result }, "Manual SDK sync result")
// Refresh sessions after sync
await fetchSessions(instanceId)
} catch (error) {
log.error({ instanceId, error }, "Manual SDK sync failed")
throw error
}
}
export {
createSession,
deleteSession,
@@ -1160,6 +1181,7 @@ export {
fetchProviders,
fetchSessions,
syncSessionsFromSdk,
forkSession,
loadMessages,
}

View File

@@ -26,7 +26,7 @@ import {
setActiveParentSession,
setActiveSession,
setSessionDraftPrompt,
} from "./session-state"
} from "./session-state"
import { getDefaultModel } from "./session-models"
import {
@@ -35,6 +35,7 @@ import {
fetchAgents,
fetchProviders,
fetchSessions,
syncSessionsFromSdk,
forkSession,
loadMessages,
} from "./session-api"
@@ -88,6 +89,7 @@ export {
fetchAgents,
fetchProviders,
fetchSessions,
syncSessionsFromSdk,
forkSession,
getActiveParentSession,
getActiveSession,