feat: add onboarding command and migrate git diff to checkout API
This commit is contained in:
@@ -506,6 +506,7 @@ export function GitDiffPane({ serverId, agentId, cwd }: GitDiffPaneProps) {
|
||||
});
|
||||
const {
|
||||
status: prStatus,
|
||||
githubFeaturesEnabled,
|
||||
payloadError: prPayloadError,
|
||||
refresh: refreshPrStatus,
|
||||
} = useCheckoutPrStatusQuery({
|
||||
@@ -840,7 +841,7 @@ export function GitDiffPane({ serverId, agentId, cwd }: GitDiffPaneProps) {
|
||||
const diffErrorMessage =
|
||||
diffPayloadError?.message ??
|
||||
(isDiffError && diffError instanceof Error ? diffError.message : null);
|
||||
const prErrorMessage = prPayloadError?.message ?? null;
|
||||
const prErrorMessage = githubFeaturesEnabled ? prPayloadError?.message ?? null : null;
|
||||
const branchLabel =
|
||||
gitStatus?.currentBranch && gitStatus.currentBranch !== "HEAD"
|
||||
? gitStatus.currentBranch
|
||||
@@ -993,7 +994,7 @@ export function GitDiffPane({ serverId, agentId, cwd }: GitDiffPaneProps) {
|
||||
}
|
||||
|
||||
// View PR - when PR exists
|
||||
if (hasPullRequest && prStatus?.url) {
|
||||
if (githubFeaturesEnabled && hasPullRequest && prStatus?.url) {
|
||||
const prUrl = prStatus.url;
|
||||
allActions.set("view-pr", {
|
||||
id: "view-pr",
|
||||
@@ -1008,7 +1009,7 @@ export function GitDiffPane({ serverId, agentId, cwd }: GitDiffPaneProps) {
|
||||
}
|
||||
|
||||
// Create PR - when ahead of base and no PR
|
||||
if (aheadCount > 0 && !hasPullRequest) {
|
||||
if (githubFeaturesEnabled && aheadCount > 0 && !hasPullRequest) {
|
||||
allActions.set("create-pr", {
|
||||
id: "create-pr",
|
||||
label: "Create PR",
|
||||
@@ -1112,7 +1113,7 @@ export function GitDiffPane({ serverId, agentId, cwd }: GitDiffPaneProps) {
|
||||
|
||||
return { primary, secondary, menu };
|
||||
}, [
|
||||
isGit, hasRemote, hasPullRequest, prStatus?.url, aheadCount, isPaseoOwnedWorktree, isOnBaseBranch,
|
||||
isGit, hasRemote, hasPullRequest, prStatus?.url, aheadCount, isPaseoOwnedWorktree, isOnBaseBranch, githubFeaturesEnabled,
|
||||
hasUncommittedChanges, aheadOfOrigin, shipDefault, baseRefLabel,
|
||||
commitDisabled, pushDisabled, prDisabled, mergeDisabled, mergeFromBaseDisabled, archiveDisabled,
|
||||
commitStatus, pushStatus, prCreateStatus, mergeStatus, mergeFromBaseStatus, archiveStatus,
|
||||
|
||||
@@ -322,7 +322,6 @@ export function SessionProvider({
|
||||
const setPendingPermissions = useSessionStore(
|
||||
(state) => state.setPendingPermissions
|
||||
);
|
||||
const setGitDiffs = useSessionStore((state) => state.setGitDiffs);
|
||||
const setFileExplorer = useSessionStore((state) => state.setFileExplorer);
|
||||
const clearDraftInput = useDraftStore((state) => state.clearDraftInput);
|
||||
const setQueuedMessages = useSessionStore((state) => state.setQueuedMessages);
|
||||
@@ -666,22 +665,6 @@ export function SessionProvider({
|
||||
[serverId, setFileExplorer]
|
||||
);
|
||||
|
||||
const gitDiffMutation = useMutation({
|
||||
mutationFn: async ({ agentId }: { agentId: string }) => {
|
||||
if (!agentId) {
|
||||
throw new Error("Agent id is required");
|
||||
}
|
||||
if (!client) {
|
||||
throw new Error("Daemon client unavailable");
|
||||
}
|
||||
const payload = await client.getGitDiff(agentId);
|
||||
if (payload.error) {
|
||||
throw new Error(payload.error);
|
||||
}
|
||||
return { agentId: payload.agentId, diff: payload.diff ?? "" };
|
||||
},
|
||||
});
|
||||
|
||||
const refreshAgentMutation = useMutation({
|
||||
mutationFn: async ({ agentId }: { agentId: string }) => {
|
||||
if (!agentId) {
|
||||
@@ -1275,15 +1258,6 @@ export function SessionProvider({
|
||||
return next;
|
||||
});
|
||||
|
||||
setGitDiffs(serverId, (prev) => {
|
||||
if (!prev.has(agentId)) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Map(prev);
|
||||
next.delete(agentId);
|
||||
return next;
|
||||
});
|
||||
|
||||
setFileExplorer(serverId, (prev) => {
|
||||
if (!prev.has(agentId)) {
|
||||
return prev;
|
||||
@@ -1343,7 +1317,6 @@ export function SessionProvider({
|
||||
setAgents,
|
||||
setAgentLastActivity,
|
||||
setPendingPermissions,
|
||||
setGitDiffs,
|
||||
setFileExplorer,
|
||||
setHasHydratedAgents,
|
||||
updateConnectionStatus,
|
||||
@@ -1635,24 +1608,6 @@ export function SessionProvider({
|
||||
[]
|
||||
);
|
||||
|
||||
const requestGitDiff = useCallback(
|
||||
(agentId: string) => {
|
||||
gitDiffMutation
|
||||
.mutateAsync({ agentId })
|
||||
.then((result) => {
|
||||
setGitDiffs(serverId, (prev) =>
|
||||
new Map(prev).set(result.agentId, result.diff)
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
setGitDiffs(serverId, (prev) =>
|
||||
new Map(prev).set(agentId, `Error: ${error.message}`)
|
||||
);
|
||||
});
|
||||
},
|
||||
[serverId, gitDiffMutation, setGitDiffs]
|
||||
);
|
||||
|
||||
const requestDirectoryListing = useCallback(
|
||||
(agentId: string, path: string, options?: { recordHistory?: boolean }) => {
|
||||
const normalizedPath = path && path.length > 0 ? path : ".";
|
||||
|
||||
@@ -43,6 +43,7 @@ export function useCheckoutPrStatusQuery({
|
||||
|
||||
return {
|
||||
status: query.data?.status ?? null,
|
||||
githubFeaturesEnabled: query.data?.githubFeaturesEnabled ?? true,
|
||||
payloadError: query.data?.error ?? null,
|
||||
isLoading: query.isLoading,
|
||||
isFetching: query.isFetching,
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { UnistylesRuntime } from "react-native-unistyles";
|
||||
import { useSessionStore } from "@/stores/session-store";
|
||||
import { usePanelStore } from "@/stores/panel-store";
|
||||
|
||||
const GIT_DIFF_STALE_TIME = 30_000;
|
||||
|
||||
function gitDiffQueryKey(serverId: string, agentId: string) {
|
||||
return ["gitDiff", serverId, agentId] as const;
|
||||
}
|
||||
|
||||
interface UseGitDiffQueryOptions {
|
||||
serverId: string;
|
||||
agentId: string;
|
||||
}
|
||||
|
||||
export function useGitDiffQuery({ serverId, agentId }: UseGitDiffQueryOptions) {
|
||||
const queryClient = useQueryClient();
|
||||
const client = useSessionStore(
|
||||
(state) => state.sessions[serverId]?.client ?? null
|
||||
);
|
||||
const isConnected = useSessionStore(
|
||||
(state) => state.sessions[serverId]?.connection.isConnected ?? false
|
||||
);
|
||||
const isMobile =
|
||||
UnistylesRuntime.breakpoint === "xs" || UnistylesRuntime.breakpoint === "sm";
|
||||
const mobileView = usePanelStore((state) => state.mobileView);
|
||||
const desktopFileExplorerOpen = usePanelStore((state) => state.desktop.fileExplorerOpen);
|
||||
const explorerTab = usePanelStore((state) => state.explorerTab);
|
||||
const isOpen = isMobile ? mobileView === "file-explorer" : desktopFileExplorerOpen;
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: gitDiffQueryKey(serverId, agentId),
|
||||
queryFn: async () => {
|
||||
if (!client) {
|
||||
throw new Error("Daemon client not available");
|
||||
}
|
||||
const response = await client.getGitDiff(agentId);
|
||||
return response.diff;
|
||||
},
|
||||
enabled: !!client && isConnected && !!agentId,
|
||||
staleTime: GIT_DIFF_STALE_TIME,
|
||||
refetchInterval: 10_000,
|
||||
});
|
||||
|
||||
// Revalidate when sidebar opens with "changes" tab active
|
||||
useEffect(() => {
|
||||
if (!isOpen || explorerTab !== "changes" || !agentId) {
|
||||
return;
|
||||
}
|
||||
// Invalidate to trigger background refetch (shows stale data while fetching)
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: gitDiffQueryKey(serverId, agentId),
|
||||
});
|
||||
}, [isOpen, explorerTab, serverId, agentId, queryClient]);
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
return query.refetch();
|
||||
}, [query]);
|
||||
|
||||
return {
|
||||
diff: query.data ?? null,
|
||||
isLoading: query.isLoading,
|
||||
isFetching: query.isFetching,
|
||||
isError: query.isError,
|
||||
error: query.error,
|
||||
refresh,
|
||||
};
|
||||
}
|
||||
@@ -201,9 +201,6 @@ export interface SessionState {
|
||||
// Permissions
|
||||
pendingPermissions: Map<string, PendingPermission>;
|
||||
|
||||
// Git diffs
|
||||
gitDiffs: Map<string, string>;
|
||||
|
||||
// File explorer
|
||||
fileExplorer: Map<string, AgentFileExplorerState>;
|
||||
|
||||
@@ -258,9 +255,6 @@ interface SessionStoreActions {
|
||||
// Permissions
|
||||
setPendingPermissions: (serverId: string, perms: Map<string, PendingPermission> | ((prev: Map<string, PendingPermission>) => Map<string, PendingPermission>)) => void;
|
||||
|
||||
// Git diffs
|
||||
setGitDiffs: (serverId: string, diffs: Map<string, string> | ((prev: Map<string, string>) => Map<string, string>)) => void;
|
||||
|
||||
// File explorer
|
||||
setFileExplorer: (serverId: string, state: Map<string, AgentFileExplorerState> | ((prev: Map<string, AgentFileExplorerState>) => Map<string, AgentFileExplorerState>)) => void;
|
||||
|
||||
@@ -332,7 +326,6 @@ function createInitialSessionState(serverId: string, client: DaemonClient, audio
|
||||
initializingAgents: new Map(),
|
||||
agents: new Map(),
|
||||
pendingPermissions: new Map(),
|
||||
gitDiffs: new Map(),
|
||||
fileExplorer: new Map(),
|
||||
queuedMessages: new Map(),
|
||||
};
|
||||
@@ -745,28 +738,6 @@ export const useSessionStore = create<SessionStore>()(
|
||||
});
|
||||
},
|
||||
|
||||
// Git diffs
|
||||
setGitDiffs: (serverId, diffs) => {
|
||||
set((prev) => {
|
||||
const session = prev.sessions[serverId];
|
||||
if (!session) {
|
||||
return prev;
|
||||
}
|
||||
const nextDiffs = typeof diffs === "function" ? diffs(session.gitDiffs) : diffs;
|
||||
if (session.gitDiffs === nextDiffs) {
|
||||
return prev;
|
||||
}
|
||||
logSessionStoreUpdate("setGitDiffs", serverId, { count: nextDiffs.size });
|
||||
return {
|
||||
...prev,
|
||||
sessions: {
|
||||
...prev.sessions,
|
||||
[serverId]: { ...session, gitDiffs: nextDiffs },
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
// File explorer
|
||||
setFileExplorer: (serverId, state) => {
|
||||
set((prev) => {
|
||||
|
||||
Reference in New Issue
Block a user