Merge origin/main into dev (second round)

Resolve 21 conflicts from latest main (provider profiles, Windows fixes, 0.1.55-rc.1).
Fix all type errors and syntax issues from merge artifacts.
This commit is contained in:
Mohamed Boudra
2026-04-14 04:07:36 +07:00
249 changed files with 9118 additions and 4973 deletions
+12 -4
View File
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ActivityIndicator, Platform, Text, View } from "react-native";
import { ActivityIndicator, Text, View } from "react-native";
import ReanimatedAnimated from "react-native-reanimated";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { useShallow } from "zustand/shallow";
@@ -46,6 +46,7 @@ import {
deriveRouteBottomAnchorIntent,
deriveRouteBottomAnchorRequest,
} from "@/screens/agent/agent-ready-screen-bottom-anchor";
import { isNative } from "@/constants/platform";
function formatProviderLabel(provider: Agent["provider"]): string {
if (!provider) {
@@ -242,7 +243,7 @@ function AgentPanelBody({
);
const agentState = useSessionStore(
useShallow((state) => {
const agent = agentId ? state.sessions[serverId]?.agents?.get(agentId) ?? null : null;
const agent = agentId ? (state.sessions[serverId]?.agents?.get(agentId) ?? null) : null;
return {
serverId: agent?.serverId ?? null,
id: agent?.id ?? null,
@@ -690,7 +691,14 @@ function ChatAgentContent({
projectPlacement,
}
: null,
[agentState.serverId, agentState.id, agentState.status, agentState.cwd, agentState.lastError, projectPlacement],
[
agentState.serverId,
agentState.id,
agentState.status,
agentState.cwd,
agentState.lastError,
projectPlacement,
],
);
const placeholderAgent: AgentScreenAgent | null = useMemo(() => {
@@ -791,7 +799,7 @@ function ChatAgentContent({
if (!isConnected || !hasSession) {
return;
}
const shouldSyncOnEntry = needsAuthoritativeSync || Platform.OS !== "web";
const shouldSyncOnEntry = needsAuthoritativeSync || isNative;
if (!shouldSyncOnEntry) {
return;
}
+15 -20
View File
@@ -18,7 +18,7 @@ function useSetupPanelDescriptor(
serverId: context.serverId,
workspaceId: target.workspaceId,
});
const snapshot = useWorkspaceSetupStore((state) => (key ? state.snapshots[key] ?? null : null));
const snapshot = useWorkspaceSetupStore((state) => (key ? (state.snapshots[key] ?? null) : null));
if (snapshot?.status === "completed") {
return {
@@ -98,7 +98,7 @@ function SetupPanel() {
serverId,
workspaceId: target.workspaceId,
});
const snapshot = useWorkspaceSetupStore((state) => (key ? state.snapshots[key] ?? null : null));
const snapshot = useWorkspaceSetupStore((state) => (key ? (state.snapshots[key] ?? null) : null));
const upsertProgress = useWorkspaceSetupStore((state) => state.upsertProgress);
// On mount, if no snapshot in the store, request cached status from server
@@ -160,13 +160,14 @@ function SetupPanel() {
return null;
})();
const statusLabel = snapshot?.status === "running"
? "Running"
: snapshot?.status === "completed"
? "Completed"
: snapshot?.status === "failed"
? "Failed"
: "Waiting for setup output";
const statusLabel =
snapshot?.status === "running"
? "Running"
: snapshot?.status === "completed"
? "Completed"
: snapshot?.status === "failed"
? "Failed"
: "Waiting for setup output";
return (
<ScrollView
@@ -175,10 +176,9 @@ function SetupPanel() {
testID="workspace-setup-panel"
>
{/* Hidden element for status — preserves testID for E2E */}
<Text
style={styles.hiddenStatus}
testID="workspace-setup-status"
>{statusLabel}</Text>
<Text style={styles.hiddenStatus} testID="workspace-setup-status">
{statusLabel}
</Text>
{isWaiting ? (
<View style={styles.waitingContainer}>
@@ -241,17 +241,12 @@ function SetupPanel() {
{command.command}
</Text>
{command.durationMs != null ? (
<Text style={styles.commandDuration}>
{formatDuration(command.durationMs)}
</Text>
<Text style={styles.commandDuration}>{formatDuration(command.durationMs)}</Text>
) : null}
<ChevronRight
size={14}
color={theme.colors.foregroundMuted}
style={[
styles.chevron,
showDetail && styles.chevronExpanded,
]}
style={[styles.chevron, showDetail && styles.chevronExpanded]}
/>
</Pressable>
{showDetail ? (
+6 -2
View File
@@ -39,7 +39,9 @@ function useTerminalPanelDescriptor(
queryFn: async (): Promise<ListTerminalsPayload> => {
if (!client || !workspaceDirectory) {
throw new Error(
workspaceAuthority.ok ? "Workspace execution directory not found" : workspaceAuthority.message,
workspaceAuthority.ok
? "Workspace execution directory not found"
: workspaceAuthority.message,
);
}
return client.listTerminals(workspaceDirectory);
@@ -76,7 +78,9 @@ function TerminalPanel() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", padding: 16 }}>
<Text>
{workspaceAuthority.ok ? "Workspace execution directory not found." : workspaceAuthority.message}
{workspaceAuthority.ok
? "Workspace execution directory not found."
: workspaceAuthority.message}
</Text>
</View>
);