Merge branch 'main' into dev

Resolve 38 conflicts preserving both sides' work:
- Server: DB-based registries (dev) + WorkspaceGitService/DaemonConfigStore (main)
- App: script proxy/voice MCP (dev) + pin/hide tabs/bootstrap boundary (main)
- Shared: WorkspaceScriptPayload (dev) + git/GitHub runtime schemas (main)
- Deleted workspace-registry-bootstrap.ts (dev's DB approach supersedes)
This commit is contained in:
Mohamed Boudra
2026-04-14 03:05:45 +07:00
333 changed files with 13490 additions and 6317 deletions
@@ -3,15 +3,7 @@ import { ActivityIndicator, Alert, Text, View } from "react-native";
import * as Clipboard from "expo-clipboard";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { settingsStyles } from "@/styles/settings";
import {
ArrowUpRight,
Play,
Pause,
RotateCw,
Copy,
FileText,
Activity,
} from "lucide-react-native";
import { ArrowUpRight, Play, Pause, RotateCw, Copy, FileText, Activity } from "lucide-react-native";
import { AdaptiveModalSheet } from "@/components/adaptive-modal-sheet";
import { Button } from "@/components/ui/button";
import { useAppSettings } from "@/hooks/use-settings";
@@ -106,7 +98,14 @@ export function LocalDaemonSection({ appVersion, showLifecycleControls }: LocalD
console.error("[Settings] Failed to open desktop daemon action confirmation", error);
Alert.alert("Error", "Unable to open the daemon confirmation dialog.");
});
}, [daemonActionLabel, daemonStatus?.status, isRestartingDaemon, refetch, setStatus, showSection]);
}, [
daemonActionLabel,
daemonStatus?.status,
isRestartingDaemon,
refetch,
setStatus,
showSection,
]);
const handleToggleDaemonManagement = useCallback(() => {
if (isUpdatingDaemonManagement) {
@@ -394,7 +393,9 @@ export function LocalDaemonSection({ appVersion, showLifecycleControls }: LocalD
snapPoints={["70%", "92%"]}
>
<View style={styles.modalBody}>
<Text style={settingsStyles.rowHint}>{daemonLogs?.logPath ?? "Log path unavailable."}</Text>
<Text style={settingsStyles.rowHint}>
{daemonLogs?.logPath ?? "Log path unavailable."}
</Text>
<Text style={styles.logOutput} selectable>
{daemonLogs?.contents.length ? daemonLogs.contents : "(log file is empty)"}
</Text>
@@ -87,7 +87,9 @@ export function IntegrationsSection() {
<Button
variant="ghost"
size="sm"
leftIcon={<ArrowUpRight size={theme.iconSize.sm} color={theme.colors.foregroundMuted} />}
leftIcon={
<ArrowUpRight size={theme.iconSize.sm} color={theme.colors.foregroundMuted} />
}
textStyle={settingsStyles.sectionHeaderLinkText}
style={settingsStyles.sectionHeaderLink}
onPress={() => void openExternalUrl(CLI_DOCS_URL)}
@@ -98,7 +100,9 @@ export function IntegrationsSection() {
<Button
variant="ghost"
size="sm"
leftIcon={<ArrowUpRight size={theme.iconSize.sm} color={theme.colors.foregroundMuted} />}
leftIcon={
<ArrowUpRight size={theme.iconSize.sm} color={theme.colors.foregroundMuted} />
}
textStyle={settingsStyles.sectionHeaderLinkText}
style={settingsStyles.sectionHeaderLink}
onPress={() => void openExternalUrl(SKILLS_DOCS_URL)}
+1 -4
View File
@@ -38,10 +38,7 @@ export interface DesktopOpenerBridge {
}
export interface DesktopMenuBridge {
showContextMenu?: (input?: {
kind?: "terminal";
hasSelection?: boolean;
}) => Promise<void>;
showContextMenu?: (input?: { kind?: "terminal"; hasSelection?: boolean }) => Promise<void>;
}
export interface DesktopWindowControlsOverlayUpdate {
@@ -14,7 +14,9 @@ const originalGlobals: GlobalSnapshot = {
navigatorDescriptor: Object.getOwnPropertyDescriptor(globalThis, "navigator"),
windowDescriptor: Object.getOwnPropertyDescriptor(globalThis, "window"),
paseoDesktop:
typeof window === "undefined" ? undefined : (window as { paseoDesktop?: unknown }).paseoDesktop,
typeof globalThis.window === "undefined"
? undefined
: (globalThis.window as { paseoDesktop?: unknown }).paseoDesktop,
};
function ensureWindow(): { paseoDesktop?: unknown } {
@@ -55,8 +57,8 @@ function restoreGlobals(): void {
delete (globalThis as { window?: unknown }).window;
}
if (typeof window !== "undefined") {
(window as { paseoDesktop?: unknown }).paseoDesktop = originalGlobals.paseoDesktop;
if (typeof globalThis.window !== "undefined") {
(globalThis.window as { paseoDesktop?: unknown }).paseoDesktop = originalGlobals.paseoDesktop;
}
}
@@ -128,7 +128,9 @@ export function useDesktopPermissions(): UseDesktopPermissionsReturn {
body: "If you can see this, desktop notifications work.",
});
if (!sent) {
setTestNotificationError("Notification was not delivered. Check System Settings > Notifications.");
setTestNotificationError(
"Notification was not delivered. Check System Settings > Notifications.",
);
}
} catch (error) {
setTestNotificationError("Failed to send notification.");
@@ -40,7 +40,12 @@ export function UpdateBanner() {
if (!isDesktopApp) return null;
if (dismissed) return null;
if (status !== "available" && status !== "installed" && status !== "installing" && status !== "error")
if (
status !== "available" &&
status !== "installed" &&
status !== "installing" &&
status !== "error"
)
return null;
const isInstalled = status === "installed";