merge: integrate main into dev

Resolve 9 merge conflicts preserving both sides' intent:
- nix hash, bootstrap hostnames rename, websocket-server wiring
- session.ts handler dedup, snapshot fallback, worktree registration
- worktree-session git service + script/setup features
- sidebar-workspace-list setup navigation, session-context cleanup
- workspace-registry-bootstrap test kept (code still exists)
- checkout-git test additions from both sides

Post-merge fixes: isPaneFocused prop rename, server type rebuild.
This commit is contained in:
Mohamed Boudra
2026-04-15 16:07:39 +07:00
73 changed files with 2288 additions and 1126 deletions
@@ -59,7 +59,7 @@ export function useAgentAttentionClear({
return;
}
deferredFocusEntryClearRef.current = false;
client.clearAgentAttention(resolvedAgentId);
client.clearAgentAttention(resolvedAgentId).catch(() => {});
},
[agentId, attentionReason, client, isConnected, requiresAttention],
);
@@ -9,10 +9,6 @@ import {
import { getHostRuntimeStore } from "@/runtime/host-runtime";
import { useSidebarOrderStore } from "@/stores/sidebar-order-store";
import { projectDisplayNameFromProjectId } from "@/utils/project-display-name";
import {
summarizeSidebarProjects,
summarizeWorkspaceCollection,
} from "@/utils/workspace-fetch-debug";
const EMPTY_ORDER: string[] = [];
const EMPTY_PROJECTS: SidebarProjectEntry[] = [];
@@ -302,14 +298,6 @@ export function useSidebarWorkspacesList(options?: {
if (!serverId) {
return;
}
console.log("[WorkspaceFetch][sidebar] model", {
serverId,
connectionStatus,
hasHydratedWorkspaces,
sessionWorkspaces: summarizeWorkspaceCollection(sessionWorkspaces?.values()),
projects: summarizeSidebarProjects(projects),
});
}, [connectionStatus, hasHydratedWorkspaces, projects, serverId, sessionWorkspaces]);
useEffect(() => {
@@ -355,21 +343,10 @@ export function useSidebarWorkspacesList(options?: {
let cursor: string | null = null;
try {
while (true) {
console.log("[WorkspaceFetch][sidebar-refresh] request", {
serverId,
cursor,
existingWorkspaces: summarizeWorkspaceCollection(existingWorkspaces?.values()),
});
const payload = await client.fetchWorkspaces({
sort: [{ key: "activity_at", direction: "desc" }],
page: cursor ? { limit: 200, cursor } : { limit: 200 },
});
console.log("[WorkspaceFetch][sidebar-refresh] response", {
serverId,
cursor,
pageInfo: payload.pageInfo,
payload: summarizeWorkspaceCollection(payload.entries),
});
for (const entry of payload.entries) {
const workspace = toWorkspaceDescriptor(entry);
next.set(
@@ -388,10 +365,6 @@ export function useSidebarWorkspacesList(options?: {
const store = useSessionStore.getState();
store.setWorkspaces(serverId, next);
store.setHasHydratedWorkspaces(serverId, true);
console.log("[WorkspaceFetch][sidebar-refresh] applied", {
serverId,
nextWorkspaces: summarizeWorkspaceCollection(next.values()),
});
} catch (error) {
console.error("[WorkspaceFetch][sidebar-refresh] failed", {
serverId,