Update files
This commit is contained in:
@@ -381,6 +381,7 @@ const styles = StyleSheet.create((theme) => ({
|
||||
},
|
||||
sectionHeader: {
|
||||
paddingVertical: theme.spacing[2],
|
||||
paddingHorizontal: theme.spacing[3],
|
||||
marginTop: theme.spacing[2],
|
||||
},
|
||||
sectionTitle: {
|
||||
|
||||
@@ -62,8 +62,7 @@ export function AgentStatusBar({ agentId, serverId }: AgentStatusBarProps) {
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
side="top"
|
||||
align="center"
|
||||
fullWidth
|
||||
align="start"
|
||||
testID="agent-mode-menu"
|
||||
>
|
||||
<DropdownMenuLabel>Mode</DropdownMenuLabel>
|
||||
|
||||
@@ -17,7 +17,7 @@ import { router, usePathname } from "expo-router";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import { type GestureType } from "react-native-gesture-handler";
|
||||
import { useQueries, useQueryClient, type UseQueryOptions } from "@tanstack/react-query";
|
||||
import { ChevronDown, ChevronRight, Plus } from "lucide-react-native";
|
||||
import { Archive, ChevronDown, ChevronRight, Plus } from "lucide-react-native";
|
||||
import {
|
||||
DraggableList,
|
||||
type DraggableRenderItemInfo,
|
||||
@@ -394,8 +394,21 @@ export function GroupedAgentList({
|
||||
[setProjectOrder]
|
||||
);
|
||||
|
||||
const handleArchiveAgent = useCallback(
|
||||
(e: { stopPropagation: () => void }, agent: AggregatedAgent) => {
|
||||
e.stopPropagation();
|
||||
const session = useSessionStore.getState().sessions[agent.serverId];
|
||||
const archiveMethod = session?.methods?.archiveAgent;
|
||||
if (archiveMethod) {
|
||||
archiveMethod(agent.id);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const AgentListRow = useCallback(
|
||||
({ agent }: { agent: AggregatedAgent }) => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const timeAgo = formatTimeAgo(agent.lastActivityAt);
|
||||
const agentKey = `${agent.serverId}:${agent.id}`;
|
||||
const isSelected = selectedAgentId === agentKey;
|
||||
@@ -415,49 +428,74 @@ export function GroupedAgentList({
|
||||
? (checkout.currentBranch ?? checkout.baseRef ?? "git")
|
||||
: null;
|
||||
|
||||
const canArchive = !isRunning && !agent.requiresAttention;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={({ pressed, hovered }) => [
|
||||
style={({ pressed }) => [
|
||||
styles.agentItem,
|
||||
isSelected && styles.agentItemSelected,
|
||||
hovered && styles.agentItemHovered,
|
||||
isHovered && styles.agentItemHovered,
|
||||
pressed && styles.agentItemPressed,
|
||||
]}
|
||||
onPress={() => handleAgentPress(agent.serverId, agent.id)}
|
||||
onLongPress={() => handleAgentLongPress(agent)}
|
||||
onHoverIn={() => setIsHovered(true)}
|
||||
onHoverOut={() => setIsHovered(false)}
|
||||
testID={`agent-row-${agent.serverId}-${agent.id}`}
|
||||
>
|
||||
{({ hovered }) => (
|
||||
<View style={styles.agentContent}>
|
||||
<View style={styles.row}>
|
||||
{statusColor && (
|
||||
<View
|
||||
style={[styles.statusDot, { backgroundColor: statusColor }]}
|
||||
/>
|
||||
)}
|
||||
<Text
|
||||
style={[
|
||||
styles.agentTitle,
|
||||
(isSelected || hovered) && styles.agentTitleHighlighted,
|
||||
]}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{agent.title || "New agent"}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Text style={styles.secondaryRow} numberOfLines={1}>
|
||||
{activeBranchLabel ? `${activeBranchLabel} · ${timeAgo}` : timeAgo}
|
||||
<View style={styles.agentContent}>
|
||||
<View style={styles.row}>
|
||||
{statusColor && (
|
||||
<View
|
||||
style={[styles.statusDot, { backgroundColor: statusColor }]}
|
||||
/>
|
||||
)}
|
||||
<Text
|
||||
style={[
|
||||
styles.agentTitle,
|
||||
(isSelected || isHovered) && styles.agentTitleHighlighted,
|
||||
]}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{agent.title || "New agent"}
|
||||
</Text>
|
||||
{isHovered && canArchive && (
|
||||
<Pressable
|
||||
style={styles.archiveButton}
|
||||
onPress={(e) => handleArchiveAgent(e, agent)}
|
||||
onHoverIn={() => setIsHovered(true)}
|
||||
onHoverOut={() => setIsHovered(true)}
|
||||
testID={`agent-archive-${agent.serverId}-${agent.id}`}
|
||||
>
|
||||
{({ hovered: archiveHovered }) => (
|
||||
<Archive
|
||||
size={14}
|
||||
color={
|
||||
archiveHovered
|
||||
? theme.colors.foreground
|
||||
: theme.colors.foregroundMuted
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Pressable>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
<Text style={styles.secondaryRow} numberOfLines={1}>
|
||||
{activeBranchLabel ? `${activeBranchLabel} · ${timeAgo}` : timeAgo}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
);
|
||||
},
|
||||
[
|
||||
handleAgentLongPress,
|
||||
handleAgentPress,
|
||||
handleArchiveAgent,
|
||||
selectedAgentId,
|
||||
theme.colors.foreground,
|
||||
theme.colors.foregroundMuted,
|
||||
theme.colors.palette.blue,
|
||||
theme.colors.success,
|
||||
]
|
||||
@@ -661,6 +699,11 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.foreground,
|
||||
opacity: 0.8,
|
||||
},
|
||||
archiveButton: {
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
marginLeft: theme.spacing[1],
|
||||
},
|
||||
agentTitleHighlighted: {
|
||||
color: theme.colors.foreground,
|
||||
opacity: 1,
|
||||
|
||||
@@ -220,6 +220,9 @@ function normalizeAgentSnapshot(
|
||||
const attentionTimestamp = snapshot.attentionTimestamp
|
||||
? new Date(snapshot.attentionTimestamp)
|
||||
: null;
|
||||
const archivedAt = snapshot.archivedAt
|
||||
? new Date(snapshot.archivedAt)
|
||||
: null;
|
||||
return {
|
||||
serverId,
|
||||
id: snapshot.id,
|
||||
@@ -244,6 +247,7 @@ function normalizeAgentSnapshot(
|
||||
attentionReason: snapshot.attentionReason ?? null,
|
||||
attentionTimestamp,
|
||||
parentAgentId: snapshot.parentAgentId,
|
||||
archivedAt,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -297,6 +301,7 @@ export interface SessionContextValue {
|
||||
images?: Array<{ uri: string; mimeType?: string }>
|
||||
) => Promise<void>;
|
||||
deleteAgent: (agentId: string) => void;
|
||||
archiveAgent: (agentId: string) => void;
|
||||
createAgent: (options: {
|
||||
config: any;
|
||||
initialPrompt: string;
|
||||
@@ -1436,6 +1441,27 @@ export function SessionProvider({
|
||||
});
|
||||
});
|
||||
|
||||
const unsubAgentArchived = client.on("agent_archived", (message) => {
|
||||
if (message.type !== "agent_archived") {
|
||||
return;
|
||||
}
|
||||
const { agentId, archivedAt } = message.payload;
|
||||
console.log("[Session] Agent archived:", agentId);
|
||||
|
||||
setAgents(serverId, (prev) => {
|
||||
const existing = prev.get(agentId);
|
||||
if (!existing) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Map(prev);
|
||||
next.set(agentId, {
|
||||
...existing,
|
||||
archivedAt: new Date(archivedAt),
|
||||
});
|
||||
return next;
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubSessionState();
|
||||
unsubAgentState();
|
||||
@@ -1450,6 +1476,7 @@ export function SessionProvider({
|
||||
unsubTranscription();
|
||||
unsubProviderModels();
|
||||
unsubAgentDeleted();
|
||||
unsubAgentArchived();
|
||||
};
|
||||
}, [
|
||||
client,
|
||||
@@ -1837,6 +1864,19 @@ export function SessionProvider({
|
||||
[client]
|
||||
);
|
||||
|
||||
const archiveAgent = useCallback(
|
||||
(agentId: string) => {
|
||||
if (!client) {
|
||||
console.warn("[Session] archiveAgent skipped: daemon unavailable");
|
||||
return;
|
||||
}
|
||||
void client.archiveAgent(agentId).catch((error) => {
|
||||
console.error("[Session] Failed to archive agent:", error);
|
||||
});
|
||||
},
|
||||
[client]
|
||||
);
|
||||
|
||||
const restartServer = useCallback(
|
||||
(reason?: string) => {
|
||||
if (!client) {
|
||||
@@ -2158,6 +2198,7 @@ export function SessionProvider({
|
||||
refreshSession,
|
||||
cancelAgentRun,
|
||||
deleteAgent,
|
||||
archiveAgent,
|
||||
sendAgentMessage,
|
||||
createAgent,
|
||||
setAgentMode,
|
||||
@@ -2181,6 +2222,7 @@ export function SessionProvider({
|
||||
refreshSession,
|
||||
cancelAgentRun,
|
||||
deleteAgent,
|
||||
archiveAgent,
|
||||
sendAgentMessage,
|
||||
createAgent,
|
||||
setAgentMode,
|
||||
@@ -2208,6 +2250,7 @@ export function SessionProvider({
|
||||
cancelAgentRun,
|
||||
sendAgentMessage,
|
||||
deleteAgent,
|
||||
archiveAgent,
|
||||
createAgent,
|
||||
setAgentMode,
|
||||
respondToPermission,
|
||||
@@ -2228,6 +2271,7 @@ export function SessionProvider({
|
||||
cancelAgentRun,
|
||||
sendAgentMessage,
|
||||
deleteAgent,
|
||||
archiveAgent,
|
||||
createAgent,
|
||||
setAgentMode,
|
||||
respondToPermission,
|
||||
|
||||
@@ -80,6 +80,7 @@ export function useAggregatedAgents(): AggregatedAgentsResult {
|
||||
attentionReason: agent.attentionReason,
|
||||
attentionTimestamp: agent.attentionTimestamp,
|
||||
parentAgentId: agent.parentAgentId,
|
||||
archivedAt: agent.archivedAt,
|
||||
};
|
||||
allAgents.push(nextAgent);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ export interface Agent {
|
||||
attentionReason?: "finished" | "error" | "permission" | null;
|
||||
attentionTimestamp?: Date | null;
|
||||
parentAgentId?: string | null;
|
||||
archivedAt?: Date | null;
|
||||
}
|
||||
|
||||
export type ExplorerEntryKind = "file" | "directory";
|
||||
@@ -183,6 +184,7 @@ export interface SessionState {
|
||||
images?: Array<{ uri: string; mimeType?: string }>
|
||||
) => Promise<void>;
|
||||
deleteAgent: (agentId: string) => void;
|
||||
archiveAgent: (agentId: string) => void;
|
||||
createAgent: (options: {
|
||||
config: any;
|
||||
initialPrompt: string;
|
||||
|
||||
@@ -13,4 +13,5 @@ export interface AgentDirectoryEntry {
|
||||
attentionReason?: "finished" | "error" | "permission" | null;
|
||||
attentionTimestamp?: Date | null;
|
||||
parentAgentId?: string | null;
|
||||
archivedAt?: Date | null;
|
||||
}
|
||||
|
||||
@@ -237,6 +237,12 @@ export function groupAgents(
|
||||
const now = Date.now();
|
||||
|
||||
for (const agent of agents) {
|
||||
// Archived agents are always inactive (hidden from sidebar)
|
||||
if (agent.archivedAt) {
|
||||
inactiveAgents.push(agent);
|
||||
continue;
|
||||
}
|
||||
|
||||
const isRunningOrAttention =
|
||||
agent.status === "running" || agent.requiresAttention;
|
||||
const isRecentlyActive =
|
||||
|
||||
Reference in New Issue
Block a user