refactor: simplify modal mounting with lazy wrapper and add read-only git env
This commit is contained in:
@@ -24,8 +24,6 @@ export default function HomeScreen() {
|
||||
} = useAggregatedAgents();
|
||||
const [showCreateModal, setShowCreateModal] = useState(false);
|
||||
const [showImportModal, setShowImportModal] = useState(false);
|
||||
const [createModalMounted, setCreateModalMounted] = useState(false);
|
||||
const [importModalMounted, setImportModalMounted] = useState(false);
|
||||
const [pendingImportServerId, setPendingImportServerId] = useState<string | null>(null);
|
||||
const { modal, flow, action, serverId: serverIdParam } = useLocalSearchParams<{
|
||||
modal?: string;
|
||||
@@ -49,13 +47,11 @@ export default function HomeScreen() {
|
||||
const hasAgents = aggregatedAgents.length > 0;
|
||||
|
||||
const handleCreateAgent = useCallback(() => {
|
||||
setCreateModalMounted(true);
|
||||
setShowCreateModal(true);
|
||||
}, []);
|
||||
|
||||
const openImportModal = useCallback((serverIdOverride?: string | null) => {
|
||||
setPendingImportServerId(serverIdOverride ?? null);
|
||||
setImportModalMounted(true);
|
||||
setShowImportModal(true);
|
||||
}, []);
|
||||
|
||||
@@ -138,19 +134,12 @@ export default function HomeScreen() {
|
||||
</ReanimatedAnimated.View>
|
||||
|
||||
{/* Create Agent Modal */}
|
||||
{createModalMounted ? (
|
||||
<CreateAgentModal
|
||||
isVisible={showCreateModal}
|
||||
onClose={handleCloseCreateModal}
|
||||
/>
|
||||
) : null}
|
||||
{importModalMounted ? (
|
||||
<ImportAgentModal
|
||||
isVisible={showImportModal}
|
||||
onClose={handleCloseImportModal}
|
||||
serverId={pendingImportServerId}
|
||||
/>
|
||||
) : null}
|
||||
<CreateAgentModal isVisible={showCreateModal} onClose={handleCloseCreateModal} />
|
||||
<ImportAgentModal
|
||||
isVisible={showImportModal}
|
||||
onClose={handleCloseImportModal}
|
||||
serverId={pendingImportServerId}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ interface AgentFlowModalProps {
|
||||
flow: "create" | "import";
|
||||
initialValues?: CreateAgentInitialValues;
|
||||
serverId?: string | null;
|
||||
onAfterClose?: () => void;
|
||||
}
|
||||
|
||||
type DictationToastConfig = {
|
||||
@@ -237,6 +238,7 @@ function AgentFlowModal({
|
||||
flow,
|
||||
initialValues,
|
||||
serverId,
|
||||
onAfterClose,
|
||||
}: AgentFlowModalProps) {
|
||||
const insets = useSafeAreaInsets();
|
||||
const { height: screenHeight, width: screenWidth } = useWindowDimensions();
|
||||
@@ -1326,7 +1328,8 @@ function AgentFlowModal({
|
||||
resetFormState();
|
||||
setIsMounted(false);
|
||||
navigateToAgentIfNeeded();
|
||||
}, [navigateToAgentIfNeeded, resetFormState]);
|
||||
onAfterClose?.();
|
||||
}, [navigateToAgentIfNeeded, onAfterClose, resetFormState]);
|
||||
|
||||
const requestImportCandidates = useCallback(
|
||||
(provider?: AgentProvider) => {
|
||||
@@ -2433,12 +2436,33 @@ function AgentFlowModal({
|
||||
);
|
||||
}
|
||||
|
||||
function LazyAgentFlowModal(props: Omit<AgentFlowModalProps, "onAfterClose">) {
|
||||
const { isVisible } = props;
|
||||
const [shouldRender, setShouldRender] = useState(isVisible);
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
setShouldRender(true);
|
||||
}
|
||||
}, [isVisible]);
|
||||
|
||||
const handleAfterClose = useCallback(() => {
|
||||
setShouldRender(false);
|
||||
}, []);
|
||||
|
||||
if (!shouldRender) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <AgentFlowModal {...props} onAfterClose={handleAfterClose} />;
|
||||
}
|
||||
|
||||
export function CreateAgentModal(props: ModalWrapperProps) {
|
||||
return <AgentFlowModal {...props} flow="create" />;
|
||||
return <LazyAgentFlowModal {...props} flow="create" />;
|
||||
}
|
||||
|
||||
export function ImportAgentModal(props: ModalWrapperProps) {
|
||||
return <AgentFlowModal {...props} flow="import" />;
|
||||
return <LazyAgentFlowModal {...props} flow="import" />;
|
||||
}
|
||||
|
||||
interface ModalHeaderProps {
|
||||
|
||||
@@ -171,7 +171,9 @@ export function GlobalFooter() {
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
onPress={() => setShowImportModal(true)}
|
||||
onPress={() => {
|
||||
setShowImportModal(true);
|
||||
}}
|
||||
style={({ pressed }) => [
|
||||
styles.footerButton,
|
||||
pressed && styles.buttonPressed,
|
||||
|
||||
@@ -72,6 +72,10 @@ type AgentMcpClientConfig = {
|
||||
};
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const READ_ONLY_GIT_ENV: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
GIT_OPTIONAL_LOCKS: "0",
|
||||
};
|
||||
const ACTIVE_TITLE_GENERATIONS = new Set<string>();
|
||||
const pendingAgentInitializations = new Map<string, Promise<ManagedAgent>>();
|
||||
let restartRequested = false;
|
||||
@@ -1526,11 +1530,11 @@ export class Session {
|
||||
const repoInfo = await detectRepoInfo(resolvedCwd);
|
||||
const { stdout: branchesRaw } = await execAsync(
|
||||
"git branch --format='%(refname:short)'",
|
||||
{ cwd: repoInfo.path }
|
||||
{ cwd: repoInfo.path, env: READ_ONLY_GIT_ENV }
|
||||
);
|
||||
const { stdout: currentRaw } = await execAsync(
|
||||
"git rev-parse --abbrev-ref HEAD",
|
||||
{ cwd: resolvedCwd }
|
||||
{ cwd: resolvedCwd, env: READ_ONLY_GIT_ENV }
|
||||
);
|
||||
const currentBranch = currentRaw.trim();
|
||||
const branches = branchesRaw
|
||||
@@ -1687,7 +1691,10 @@ export class Session {
|
||||
|
||||
private async isWorkingTreeDirty(cwd: string): Promise<boolean> {
|
||||
try {
|
||||
const { stdout } = await execAsync("git status --porcelain", { cwd });
|
||||
const { stdout } = await execAsync("git status --porcelain", {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
});
|
||||
return stdout.trim().length > 0;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
|
||||
@@ -4,6 +4,10 @@ import { existsSync, readFileSync } from "fs";
|
||||
import { join, basename, dirname } from "path";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const READ_ONLY_GIT_ENV: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
GIT_OPTIONAL_LOCKS: "0",
|
||||
};
|
||||
|
||||
interface RepoInfo {
|
||||
type: "bare" | "normal";
|
||||
@@ -88,6 +92,7 @@ export async function detectRepoInfo(cwd: string): Promise<RepoInfo> {
|
||||
try {
|
||||
const { stdout } = await execAsync("git rev-parse --show-toplevel", {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
});
|
||||
const repoRoot = stdout.trim();
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user