Skip to content

Commit 4908f30

Browse files
committed
fix: use first app in order instead of latest_app_status for focus in tasks
This change modifies both the tasks page (list view) and individual task page to focus on the first app in order rather than the most recently active app. Previously, Claude terminal apps would auto-focus because they report status updates frequently, making them the 'latest_app_status'. Now the focus respects the app ordering as defined in templates. Changes: - TasksPage: Use first app from all agents instead of latest_app_status.app_id - TaskApps: Use first app in apps array instead of latest_app_status.app_id - Both components now exclude AI_APP_CHAT_SLUG consistently Fixes the issue where Claude terminal apps always auto-focus instead of respecting the defined app order in templates.
1 parent 60927c7 commit 4908f30

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

site/src/pages/TaskPage/TaskApps.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ export const TaskApps: FC<TaskAppsProps> = ({ task }) => {
3333
.filter((a) => !!a && a.slug !== AI_APP_CHAT_SLUG);
3434

3535
const [activeAppId, setActiveAppId] = useState<string>(() => {
36-
const appId = task.workspace.latest_app_status?.app_id;
37-
if (!appId) {
38-
throw new Error("No active app found in task");
36+
// Use the first app in order instead of the most recently active app
37+
const firstApp = apps[0];
38+
if (!firstApp) {
39+
throw new Error("No apps found in task");
3940
}
40-
return appId;
41+
return firstApp.id;
4142
});
4243

4344
const activeApp = apps.find((app) => app.id === activeAppId);

site/src/pages/TasksPage/TasksPage.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import { useAuthenticated } from "hooks";
3232
import { ExternalLinkIcon, RotateCcwIcon, SendIcon } from "lucide-react";
3333
import { AI_PROMPT_PARAMETER_NAME, type Task } from "modules/tasks/tasks";
34+
import { AI_APP_CHAT_SLUG } from "../TaskPage/constants";
3435
import { WorkspaceAppStatus } from "modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus";
3536
import { type FC, type ReactNode, useState } from "react";
3637
import { Helmet } from "react-helmet-async";
@@ -328,11 +329,31 @@ const TasksTable: FC<TasksTableProps> = ({ templates, filter }) => {
328329
tasks.map(({ workspace, prompt }) => {
329330
const templateDisplayName =
330331
workspace.template_display_name ?? workspace.template_name;
331-
const status = workspace.latest_app_status;
332+
333+
// Get all apps from all agents, excluding the chat UI app
334+
const allApps = workspace.latest_build.resources
335+
.flatMap((r) => r.agents)
336+
.filter((a) => !!a)
337+
.flatMap((a) => a.apps)
338+
.filter((app) => app.slug !== AI_APP_CHAT_SLUG);
339+
340+
// Use the first app in order instead of the most recently active app
341+
const focusedApp = allApps[0];
342+
343+
// Find the agent that contains the focused app
332344
const agent = workspace.latest_build.resources
333345
.flatMap((r) => r.agents)
334-
.find((a) => a?.id === status?.agent_id);
335-
const app = agent?.apps.find((a) => a.id === status?.app_id);
346+
.filter((a) => !!a)
347+
.find((a) => a.apps.some((app) => app.id === focusedApp?.id));
348+
349+
// Create a status object for the focused app, or fall back to latest_app_status
350+
const status = focusedApp ? {
351+
...workspace.latest_app_status,
352+
app_id: focusedApp.id,
353+
agent_id: agent?.id || workspace.latest_app_status?.agent_id,
354+
} : workspace.latest_app_status;
355+
356+
const app = focusedApp;
336357

337358
return (
338359
<TableRow key={workspace.id} className="relative" hover>

0 commit comments

Comments
 (0)