mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
docs: add Codex integration guide and improve agent creation UX
This commit is contained in:
@@ -26,3 +26,13 @@ Don't run them anywhere else. Check logs there.
|
|||||||
## Andriod
|
## Andriod
|
||||||
|
|
||||||
Take screensots like this: `adb exec-out screencap -p > screenshot.png`
|
Take screensots like this: `adb exec-out screencap -p > screenshot.png`
|
||||||
|
|
||||||
|
## Asking Codex for a second opinion
|
||||||
|
|
||||||
|
You can ask Codex for a second opinion on a problem you're working on.
|
||||||
|
|
||||||
|
Set a high timeout, like 2 minutes.
|
||||||
|
|
||||||
|
Try not to bias it, state the problem clearly and let it work it out.
|
||||||
|
|
||||||
|
`codex exec "prompt"`
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|||||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||||
import { theme as defaultTheme, theme } from "../styles/theme";
|
import { theme as defaultTheme, theme } from "../styles/theme";
|
||||||
|
|
||||||
// Simple unique ID generator
|
|
||||||
let messageIdCounter = 0;
|
|
||||||
function generateMessageId(): string {
|
|
||||||
return `msg_${Date.now()}_${messageIdCounter++}`;
|
|
||||||
}
|
|
||||||
import { useWebSocket } from "@/hooks/use-websocket";
|
import { useWebSocket } from "@/hooks/use-websocket";
|
||||||
import { useAudioRecorder } from "@/hooks/use-audio-recorder";
|
import { useAudioRecorder } from "@/hooks/use-audio-recorder";
|
||||||
import { useAudioPlayer } from "@/hooks/use-audio-player";
|
import { useAudioPlayer } from "@/hooks/use-audio-player";
|
||||||
@@ -1247,9 +1242,8 @@ export default function VoiceAssistantScreen() {
|
|||||||
function handleSelectConversation(newConversationId: string | null) {
|
function handleSelectConversation(newConversationId: string | null) {
|
||||||
// Clear all state
|
// Clear all state
|
||||||
setMessages([]);
|
setMessages([]);
|
||||||
setAgentMessages(new Map());
|
setAgentStreamState(new Map());
|
||||||
setCurrentAssistantMessage("");
|
setCurrentAssistantMessage("");
|
||||||
setCurrentAgentMessages(new Map());
|
|
||||||
setUserInput("");
|
setUserInput("");
|
||||||
setArtifacts(new Map());
|
setArtifacts(new Map());
|
||||||
setCurrentArtifact(null);
|
setCurrentArtifact(null);
|
||||||
@@ -1402,7 +1396,7 @@ export default function VoiceAssistantScreen() {
|
|||||||
>
|
>
|
||||||
{messages.length === 0 && !currentAssistantMessage && (
|
{messages.length === 0 && !currentAssistantMessage && (
|
||||||
<View style={styles.emptyState}>
|
<View style={styles.emptyState}>
|
||||||
<Text style={styles.emptyStateTitle}>OnTheGo</Text>
|
<Text style={styles.emptyStateTitle}>Hammock</Text>
|
||||||
<Text style={styles.emptyStateSubtitle}>
|
<Text style={styles.emptyStateSubtitle}>
|
||||||
What would you like to work on?
|
What would you like to work on?
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import {
|
|||||||
Pressable,
|
Pressable,
|
||||||
TextInput,
|
TextInput,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
KeyboardAvoidingView,
|
|
||||||
Platform,
|
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller";
|
||||||
|
import ReanimatedAnimated, { useAnimatedStyle } from "react-native-reanimated";
|
||||||
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import { X } from "lucide-react-native";
|
import { X } from "lucide-react-native";
|
||||||
import { StyleSheet } from "react-native-unistyles";
|
import { StyleSheet } from "react-native-unistyles";
|
||||||
import { theme as defaultTheme } from "@/styles/theme";
|
import { theme as defaultTheme } from "@/styles/theme";
|
||||||
@@ -37,10 +38,24 @@ export function CreateAgentModal({
|
|||||||
onClose,
|
onClose,
|
||||||
onCreateAgent,
|
onCreateAgent,
|
||||||
}: CreateAgentModalProps) {
|
}: CreateAgentModalProps) {
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
const { height: keyboardHeight } = useReanimatedKeyboardAnimation();
|
||||||
|
|
||||||
const [workingDir, setWorkingDir] = useState("");
|
const [workingDir, setWorkingDir] = useState("");
|
||||||
const [selectedMode, setSelectedMode] = useState("plan");
|
const [selectedMode, setSelectedMode] = useState("plan");
|
||||||
const [errorMessage, setErrorMessage] = useState("");
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
|
|
||||||
|
// Keyboard animation
|
||||||
|
const bottomInset = insets.bottom;
|
||||||
|
const animatedKeyboardStyle = useAnimatedStyle(() => {
|
||||||
|
"worklet";
|
||||||
|
const absoluteHeight = Math.abs(keyboardHeight.value);
|
||||||
|
const padding = Math.max(0, absoluteHeight - bottomInset);
|
||||||
|
return {
|
||||||
|
paddingBottom: padding,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
if (!workingDir.trim()) {
|
if (!workingDir.trim()) {
|
||||||
setErrorMessage("Working directory is required");
|
setErrorMessage("Working directory is required");
|
||||||
@@ -65,12 +80,11 @@ export function CreateAgentModal({
|
|||||||
transparent={true}
|
transparent={true}
|
||||||
onRequestClose={handleClose}
|
onRequestClose={handleClose}
|
||||||
>
|
>
|
||||||
<KeyboardAvoidingView
|
<View style={styles.modalOverlay}>
|
||||||
style={styles.modalOverlay}
|
|
||||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
||||||
>
|
|
||||||
<Pressable style={styles.modalBackdrop} onPress={handleClose} />
|
<Pressable style={styles.modalBackdrop} onPress={handleClose} />
|
||||||
<View style={styles.modalContent}>
|
<ReanimatedAnimated.View
|
||||||
|
style={[styles.modalContent, animatedKeyboardStyle]}
|
||||||
|
>
|
||||||
<View style={styles.modalInner}>
|
<View style={styles.modalInner}>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
@@ -149,25 +163,29 @@ export function CreateAgentModal({
|
|||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Action Buttons */}
|
|
||||||
<View style={styles.buttonContainer}>
|
|
||||||
<Pressable
|
|
||||||
style={[styles.createButton, !workingDir.trim() && styles.createButtonDisabled]}
|
|
||||||
onPress={handleCreate}
|
|
||||||
disabled={!workingDir.trim()}
|
|
||||||
>
|
|
||||||
<Text style={styles.createButtonText}>Create Agent</Text>
|
|
||||||
</Pressable>
|
|
||||||
|
|
||||||
<Pressable style={styles.cancelButton} onPress={handleClose}>
|
|
||||||
<Text style={styles.cancelButtonText}>Cancel</Text>
|
|
||||||
</Pressable>
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
{/* Fixed Footer with Create Button */}
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.footer,
|
||||||
|
{ paddingBottom: Math.max(insets.bottom, 16) },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
style={[
|
||||||
|
styles.createButton,
|
||||||
|
!workingDir.trim() && styles.createButtonDisabled,
|
||||||
|
]}
|
||||||
|
onPress={handleCreate}
|
||||||
|
disabled={!workingDir.trim()}
|
||||||
|
>
|
||||||
|
<Text style={styles.createButtonText}>Create Agent</Text>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ReanimatedAnimated.View>
|
||||||
</KeyboardAvoidingView>
|
</View>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -175,19 +193,28 @@ export function CreateAgentModal({
|
|||||||
const styles = StyleSheet.create((theme) => ({
|
const styles = StyleSheet.create((theme) => ({
|
||||||
modalOverlay: {
|
modalOverlay: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: "rgba(0,0,0,0.5)",
|
justifyContent: "flex-end",
|
||||||
},
|
},
|
||||||
modalBackdrop: {
|
modalBackdrop: {
|
||||||
flex: 1,
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: "rgba(0,0,0,0.5)",
|
||||||
|
zIndex: 1,
|
||||||
},
|
},
|
||||||
modalContent: {
|
modalContent: {
|
||||||
backgroundColor: theme.colors.card,
|
backgroundColor: theme.colors.card,
|
||||||
borderTopLeftRadius: theme.spacing[6],
|
borderTopLeftRadius: theme.spacing[6],
|
||||||
borderTopRightRadius: theme.spacing[6],
|
borderTopRightRadius: theme.spacing[6],
|
||||||
height: "75%",
|
minHeight: "80%",
|
||||||
|
zIndex: 2,
|
||||||
|
elevation: 5,
|
||||||
},
|
},
|
||||||
modalInner: {
|
modalInner: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
minHeight: 0,
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
@@ -207,7 +234,7 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
},
|
},
|
||||||
scrollContent: {
|
scrollContent: {
|
||||||
padding: theme.spacing[6],
|
padding: theme.spacing[6],
|
||||||
paddingBottom: theme.spacing[4] * 5,
|
paddingBottom: theme.spacing[4],
|
||||||
},
|
},
|
||||||
formSection: {
|
formSection: {
|
||||||
marginBottom: theme.spacing[6],
|
marginBottom: theme.spacing[6],
|
||||||
@@ -289,14 +316,18 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
color: theme.colors.mutedForeground,
|
color: theme.colors.mutedForeground,
|
||||||
fontSize: theme.fontSize.sm,
|
fontSize: theme.fontSize.sm,
|
||||||
},
|
},
|
||||||
buttonContainer: {
|
footer: {
|
||||||
gap: theme.spacing[3],
|
borderTopWidth: theme.borderWidth[1],
|
||||||
marginTop: theme.spacing[4],
|
borderTopColor: theme.colors.border,
|
||||||
|
paddingHorizontal: theme.spacing[6],
|
||||||
|
paddingTop: theme.spacing[4],
|
||||||
|
backgroundColor: theme.colors.card,
|
||||||
},
|
},
|
||||||
createButton: {
|
createButton: {
|
||||||
backgroundColor: theme.colors.palette.blue[500],
|
backgroundColor: theme.colors.palette.blue[500],
|
||||||
paddingVertical: theme.spacing[4],
|
paddingVertical: theme.spacing[4],
|
||||||
borderRadius: theme.borderRadius.lg,
|
borderRadius: theme.borderRadius.lg,
|
||||||
|
marginBottom: theme.spacing[4],
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
createButtonDisabled: {
|
createButtonDisabled: {
|
||||||
@@ -308,17 +339,4 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
fontSize: theme.fontSize.base,
|
fontSize: theme.fontSize.base,
|
||||||
fontWeight: theme.fontWeight.semibold,
|
fontWeight: theme.fontWeight.semibold,
|
||||||
},
|
},
|
||||||
cancelButton: {
|
|
||||||
backgroundColor: "transparent",
|
|
||||||
paddingVertical: theme.spacing[4],
|
|
||||||
borderRadius: theme.borderRadius.lg,
|
|
||||||
alignItems: "center",
|
|
||||||
borderWidth: theme.borderWidth[1],
|
|
||||||
borderColor: theme.colors.border,
|
|
||||||
},
|
|
||||||
cancelButtonText: {
|
|
||||||
color: theme.colors.foreground,
|
|
||||||
fontSize: theme.fontSize.base,
|
|
||||||
fontWeight: theme.fontWeight.semibold,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user